{
  "openapi": "3.1.0",
  "info": {
    "title": "One Server Management API",
    "version": "v1",
    "description": "The One Server management API. Every request needs an Authorization: Bearer <token> header; make a token in the console under Account, API and MCP tokens. Add ?lang=en or ?lang=ja for error messages in that language."
  },
  "servers": [
    {
      "url": "https://end.blackall.ai/api/v1"
    }
  ],
  "tags": [
    {
      "name": "account",
      "description": "Account and regions"
    },
    {
      "name": "projects",
      "description": "Projects"
    },
    {
      "name": "keys",
      "description": "Keys and signing"
    },
    {
      "name": "database",
      "description": "Database"
    },
    {
      "name": "auth",
      "description": "Auth and users"
    },
    {
      "name": "storage",
      "description": "Storage"
    },
    {
      "name": "deployments",
      "description": "Deployments and repositories"
    },
    {
      "name": "functions",
      "description": "Functions"
    },
    {
      "name": "domains",
      "description": "Domains and edge"
    },
    {
      "name": "network",
      "description": "Network"
    },
    {
      "name": "jobs",
      "description": "Scheduled jobs"
    },
    {
      "name": "webhooks",
      "description": "Database webhooks"
    },
    {
      "name": "backups",
      "description": "Backups and restore"
    },
    {
      "name": "logs",
      "description": "Logs and observability"
    },
    {
      "name": "team",
      "description": "Team and notifications"
    },
    {
      "name": "billing",
      "description": "Billing and usage"
    },
    {
      "name": "other",
      "description": "Other"
    }
  ],
  "paths": {
    "/": {
      "get": {
        "operationId": "get_root",
        "summary": "API version",
        "description": "Returns the name and version of this API. Useful to check that a token is accepted.",
        "tags": [
          "account"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "name": {},
                    "version": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          }
        },
        "x-oneend-scope": null
      }
    },
    "/me": {
      "get": {
        "operationId": "whoami",
        "summary": "My account",
        "description": "Tells you whose token this is and what it may do. operator says whether the operator tools are open to it (active) and, when not, this account's reasons (refused: not_listed, token_bound, no_second_factor). Call it first when you are not sure where to start.",
        "tags": [
          "account"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "email": {},
                    "organisation": {},
                    "projects": {},
                    "scopes": {},
                    "zone": {},
                    "read_only": {},
                    "next": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "whoami"
      }
    },
    "/regions": {
      "get": {
        "operationId": "list_regions",
        "summary": "Regions",
        "description": "Returns the regions. You can create a project now only where can_create is true; where it is false the region is being prepared and is listed, but cannot be chosen yet. A region is chosen once when a project is created and cannot be changed later, so check this before create_project.",
        "tags": [
          "account"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "code": {},
                      "name": {},
                      "country": {},
                      "status": {},
                      "is_default": {},
                      "can_create": {}
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_regions"
      }
    },
    "/regions/requests": {
      "post": {
        "operationId": "request_region",
        "summary": "Request a region",
        "description": "Records that you need a region that is not open yet (one where can_create is false). A person from our team will contact you. No date is promised. A region that is already open is not something to request: create the project there with create_project.",
        "tags": [
          "account"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "region": {},
                    "name": {},
                    "recorded": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-mcp-tool": "request_region",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "region": {
                    "type": "string",
                    "description": "A code that list_regions reported with can_create=false."
                  },
                  "note": {
                    "type": "string",
                    "description": "What you plan to run there, and why it has to be that region. Optional, but it is the first thing the person who contacts you reads."
                  }
                },
                "required": [
                  "region"
                ]
              }
            }
          }
        }
      }
    },
    "/server-sizes": {
      "get": {
        "operationId": "list_server_sizes",
        "summary": "Server sizes and prices",
        "description": "Each server size (memory) with its Google machine, CPUs and monthly price per region (monthly_minor). With no currency, the organisation's billing currency. KRW is in won with VAT included; USD is in cents with tax added at checkout. A size whose included_in is pro is included in the Pro plan. A region whose region_status is planned is coming soon and cannot be chosen. listed false means the sizes are not on sale yet and sizes is empty.",
        "tags": [
          "account"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "region",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "One region's code (code in list_regions) to see only that region. Empty means every region."
            }
          },
          {
            "name": "currency",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "KRW",
                "USD"
              ],
              "description": "KRW or USD. Empty means the organisation's billing currency."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_server_sizes"
      }
    },
    "/imports/sources": {
      "get": {
        "operationId": "import_sources",
        "summary": "Import sources",
        "description": "The same as Import from another server in the console. For each source account connected to this organisation (Supabase, Vercel, PostgreSQL), its projects, and the imports so far. Accounts are connected in the console (connect_url), so a token is never pasted into a chat.",
        "tags": [
          "account"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "org",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "The organisation id or name. Empty means the first one this token reaches."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "organisation": {},
                    "connect_url": {},
                    "sources": {},
                    "imports": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "import_sources"
      }
    },
    "/imports": {
      "post": {
        "operationId": "start_import",
        "summary": "Start an import",
        "description": "The same as [Start import] in the console. Starts an import split in the console (import), or a new one from import_sources' connection and project, split one new project per group. New projects are made; the source is never changed. A Supabase source needs its session pooler connection string in address, used for this run only and then deleted. Starting a stopped import again passes over finished destinations and moves only what changed. Owners, admins and developers only.",
        "tags": [
          "account"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "org",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "The organisation id or name. Empty means the first one this token reaches."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-mcp-tool": "start_import",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {}
              }
            }
          }
        }
      }
    },
    "/imports/{id}": {
      "get": {
        "operationId": "get_import",
        "summary": "Import progress",
        "description": "The same as the import progress page in the console. For each destination the state and counts of each step (schema, sign-in users, data, files, scheduled jobs...), what is not moved and why, and what is worth checking.",
        "tags": [
          "account"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The import id."
            }
          },
          {
            "name": "org",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "The organisation id or name. Empty means the first one this token reaches."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_import"
      }
    },
    "/projects": {
      "get": {
        "operationId": "get_projects",
        "summary": "Projects",
        "description": "Returns the projects on this account and the API address of each. status is ready (usable), provisioning (the database is being made, a few seconds), failed (retry_provisioning) or paused.",
        "tags": [
          "projects"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "ref": {},
                      "name": {},
                      "organisation": {},
                      "organisation_id": {},
                      "region": {},
                      "api_url": {},
                      "paused": {},
                      "archive_at": {},
                      "archive_purge_at": {},
                      "created_at": {}
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_projects"
      },
      "post": {
        "operationId": "create_project",
        "summary": "Create a project",
        "description": "Creates a new project with a database, sign-in and file storage. Leave the region empty for the default region. The region cannot be changed after the project is created. The price is the same in every region. With several organizations, org chooses which one to create it in (only its owners, admins and developers can, within the number of projects its plan allows). The database is ready a few seconds later: when status is provisioning, pass wait (seconds) or use tables and keys once status in list_projects is ready.",
        "tags": [
          "projects"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "wait",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 120,
              "description": "Seconds to wait for the database to be ready (status: ready). The default 0 answers at once. It usually takes a few seconds."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "name": {},
                    "organisation": {},
                    "region": {},
                    "api_url": {},
                    "status": {},
                    "created_at": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          },
          "502": {
            "$ref": "#/components/responses/E502"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-mcp-tool": "create_project",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "A name for people to read."
                  },
                  "region": {
                    "type": "string",
                    "description": "Where to put it. list_regions tells you the values you can use. Empty means the default region."
                  },
                  "org": {
                    "type": "string",
                    "description": "The id or name of the organization to create it in (organisation_id or organisation from list_projects). Empty means the first organization you can create projects in."
                  },
                  "wait": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 120,
                    "description": "Seconds to wait for the database to be ready (status: ready). The default 0 answers at once. It usually takes a few seconds."
                  },
                  "tier": {
                    "type": "string",
                    "description": "The size of a server for this project alone: a value list_server_sizes gave (for example 4gb), or default for the plan's own size. The server is asked for as soon as the project exists. Empty starts it on the shared server."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{ref}": {
      "get": {
        "operationId": "get_projects_ref",
        "summary": "One project",
        "description": "Returns the one entry of the project list with this ref.",
        "tags": [
          "projects"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "ref": {},
                      "name": {},
                      "organisation": {},
                      "organisation_id": {},
                      "region": {},
                      "api_url": {},
                      "paused": {},
                      "archive_at": {},
                      "archive_purge_at": {},
                      "created_at": {}
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_projects"
      },
      "patch": {
        "operationId": "rename_project",
        "summary": "Rename",
        "description": "Changes the project name, the organisation name, or both. The identifier (ref) and the addresses do not change. Only owners and admins can do this.",
        "tags": [
          "projects"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "name": {},
                    "organisation": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "rename_project",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "The new project name."
                  },
                  "organisation": {
                    "type": "string",
                    "description": "The new organisation name."
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete_project",
        "summary": "Delete a project",
        "description": "Permanently deletes the project's tables, users, files, functions, scheduled jobs, environment variables and domains. This cannot be undone. Use it only when the user clearly asks, and put the project name exactly in confirm. The last remaining project cannot be deleted. Only owners and admins can do this.",
        "tags": [
          "projects"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "deleted": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "delete_project",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "confirm": {
                    "type": "string",
                    "description": "The project name. It must be exactly the name from list_projects."
                  }
                },
                "required": [
                  "confirm"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/transfer": {
      "get": {
        "operationId": "list_transfer_targets",
        "summary": "Organizations to transfer to",
        "description": "The other organizations this project can move to (ones where you are an owner or admin), with id, name and plan. can_transfer says whether you can move it, which needs you to be an owner of its current organization. Put an id in organisation of transfer_project.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "name": {},
                    "organisation": {},
                    "organisation_id": {},
                    "targets": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_transfer_targets"
      },
      "post": {
        "operationId": "transfer_project",
        "summary": "Transfer project",
        "description": "Moves the project to another organization. You must be an owner of its current organization and an owner or admin of the receiving one, and the receiving plan must have room for another project. From the move on, usage is billed to the receiving organization, so this month's bill splits at that moment. Access given to members of the old organization is removed, and only an owner of the receiving organization can move it back. Addresses, keys, data and deployments stay as they are. Use it only when the user clearly asks, and put the project name exactly in confirm.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "name": {},
                    "organisation": {},
                    "organisation_id": {},
                    "transferred": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "transfer_project",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "organisation": {
                    "type": "string",
                    "description": "The receiving organization id, from list_transfer_targets. Its name also works when only one has it."
                  },
                  "confirm": {
                    "type": "string",
                    "description": "The project name. It must be exactly the name from list_projects."
                  }
                },
                "required": [
                  "organisation",
                  "confirm"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/pause": {
      "post": {
        "operationId": "pause_project",
        "summary": "Pause a project",
        "description": "Stops everything the project does: the site, API and functions return 503, realtime connections are refused, and scheduled jobs and new deployments stop. Data and files stay, and resume_project brings it straight back. Paused for over 90 days, the database moves to archive storage (get_project_archive). Only owners and admins can do this.",
        "tags": [
          "projects"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "paused": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "pause_project"
      }
    },
    "/projects/{ref}/resume": {
      "post": {
        "operationId": "resume_project",
        "summary": "Resume a project",
        "description": "Starts a paused project again, including one the Free plan paused after 3 unused days (a new deployment also starts it). Scheduled jobs do not catch up on missed runs; they run from the next scheduled time.",
        "tags": [
          "projects"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "paused": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "resume_project"
      }
    },
    "/projects/{ref}/server": {
      "get": {
        "operationId": "get_server",
        "summary": "Dedicated server",
        "description": "Shows the project's dedicated server: size (tier), location, status, address, monthly price, standby, automatic failover, restore days, when it may next move, and jobs in progress. server is null when the project uses the shared server; offered is false while dedicated servers are not open.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "offered": {},
                    "server": {},
                    "standby": {},
                    "options": {},
                    "next_move_at": {},
                    "jobs": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_server"
      },
      "post": {
        "operationId": "request_server",
        "summary": "Rent a dedicated server",
        "description": "Rents a server for this project alone. Show sizes and monthly prices per location with list_server_sizes first, and pass only what the user chose. Usually ready within 10 minutes; the database and app move onto it, then the address switches. From the Pro plan. Only owners and admins can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "job": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "request_server",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "tier": {
                    "type": "string",
                    "pattern": "^[0-9]+gb$",
                    "description": "Server size: a tier from list_server_sizes (for example 4gb)."
                  },
                  "region": {
                    "type": "string",
                    "pattern": "^[a-z]{2}-[a-z]+-[0-9]$",
                    "description": "Location; the project's own when absent. A region from list_server_sizes."
                  }
                },
                "required": [
                  "tier"
                ]
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "resize_server",
        "summary": "Change the server size",
        "description": "Changes the dedicated server's size. when=now does it now, tonight between 03:00 and 05:00 in the server location's time. Without a standby the server does not answer for 3 to 5 minutes; with one, only the few seconds of the switch. Changing size is free; the monthly price is the new size's (list_server_sizes). Only owners and admins can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "job": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "resize_server",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "tier": {
                    "type": "string",
                    "pattern": "^[0-9]+gb$",
                    "description": "Server size: a tier from list_server_sizes (for example 4gb)."
                  },
                  "when": {
                    "type": "string",
                    "enum": [
                      "now",
                      "tonight"
                    ],
                    "description": "now (default) or tonight (03:00 to 05:00)."
                  }
                },
                "required": [
                  "tier"
                ]
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "release_server",
        "summary": "Give back the dedicated server",
        "description": "Gives the dedicated server back: a last backup, the database and app moved to the shared server, then the server (and its standby) deleted. Writes pause during the move. Use it only when the user asks, and put the ref exactly in confirm. Only owners and admins can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "job": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "release_server",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "confirm": {
                    "type": "string",
                    "description": "The project ID (ref). Must equal ref."
                  }
                },
                "required": [
                  "confirm"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/server/standby": {
      "put": {
        "operationId": "set_standby",
        "summary": "Standby server",
        "description": "Turns a standby server of the same size in the same location on or off. It replicates the database continuously and costs the same as its size a month (list_server_sizes). With auto_failover=true the project switches to it on its own once the primary has not answered for 60 seconds (needs a standby). Only owners and admins can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "job": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "set_standby",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "standby": {
                    "type": "boolean",
                    "description": "Whether to keep a standby server."
                  },
                  "auto_failover": {
                    "type": "boolean",
                    "description": "Automatic failover. false by default."
                  }
                },
                "required": [
                  "standby"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/server/move": {
      "post": {
        "operationId": "move_server",
        "summary": "Move the server",
        "description": "Moves the dedicated server to another location. Free, once a month (next_move_at). A server is made there and replicated; writes pause for a few seconds when the address switches. The old server is kept for 7 days. The monthly price is the new location's (list_server_sizes). Only owners and admins can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "job": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "move_server",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "region": {
                    "type": "string",
                    "pattern": "^[a-z]{2}-[a-z]+-[0-9]$",
                    "description": "Location: a region from list_server_sizes (for example kr-seoul-1)."
                  }
                },
                "required": [
                  "region"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/server/restore-days": {
      "put": {
        "operationId": "set_restore_days",
        "summary": "Restore days",
        "description": "Sets how far back the project can be restored to a moment: 7 or 28 days. 28 is only on a dedicated server and adds a monthly charge (get_server options, get_billing). Only owners and admins can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "job": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "set_restore_days",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "days": {
                    "type": "integer",
                    "enum": [
                      7,
                      28
                    ],
                    "description": "7 or 28."
                  }
                },
                "required": [
                  "days"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/archive": {
      "get": {
        "operationId": "get_project_archive",
        "summary": "Database archive status",
        "description": "A database that has been unusable for 90 days (a failed payment, the Free plan, a pause) is moved to archive storage. Returns where this project stands: state (none, scheduled, archiving, archived, restoring, purged), reason, archive_at (when it moves), purge_at (when the archive and the files are deleted, a year after the move), restore_blocked_by.",
        "tags": [
          "projects"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_project_archive"
      }
    },
    "/projects/{ref}/archive/restore": {
      "post": {
        "operationId": "restore_project_archive",
        "summary": "Restore an archived database",
        "description": "Makes the database in archive storage again, exactly as it was archived. Usually a few minutes; a paused project starts again with the restore. Refused while a payment is outstanding or on the Free plan (restore_blocked_by). If the archive was already deleted, creates a new, empty database. Owners and admins only.",
        "tags": [
          "projects"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "restore": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "restore_project_archive"
      }
    },
    "/projects/{ref}/archive/download": {
      "post": {
        "operationId": "create_archive_download_url",
        "summary": "Archive download address",
        "description": "Creates a signed address the archived database (pg_dump format; restore it with pg_restore) can be downloaded from for an hour. Needs a reason, which is kept in the access records. Owners and admins only.",
        "tags": [
          "projects"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "url": {},
                    "expires_at": {},
                    "bytes": {},
                    "format": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "create_archive_download_url",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string",
                    "minLength": 4,
                    "maxLength": 300,
                    "description": "Why it is downloaded. Kept in the access records."
                  }
                },
                "required": [
                  "reason"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/keys": {
      "get": {
        "operationId": "get_project_keys",
        "summary": "Get API keys",
        "description": "Returns the project address and its two keys. The publishable key is for browsers. The secret key bypasses every access rule, so use it only on a server. Only a token with write access can call this. When you need values for frontend code, call it with only: \"publishable\": you get the address and the publishable key only, so the secret key never enters the conversation or the code (a read-only token can do this).",
        "tags": [
          "keys"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "only",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "publishable"
              ],
              "description": "publishable returns only the address and the publishable key. Empty returns both keys."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "api_url": {},
                    "publishable_key": {},
                    "secret_key": {},
                    "key_version": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "secrets.read (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "get_project_keys"
      }
    },
    "/projects/{ref}/advisors": {
      "get": {
        "operationId": "get_advisors",
        "summary": "Security and performance check",
        "description": "Looks for security and performance problems in the project's database structure: tables with RLS off, rules that let anyone write, views that bypass access rules, security definer functions with no fixed search_path, views that expose the users table, foreign keys with no index, tables with no primary key, duplicate indexes, and rules that call uid() for every row. Where there is SQL that fixes an item (remedy), it is included. No data is read. Call this after creating tables or changing rules.",
        "tags": [
          "database"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_advisors"
      }
    },
    "/projects/{ref}/api-keys": {
      "get": {
        "operationId": "list_api_keys",
        "summary": "Named API keys",
        "description": "The name, kind, prefix, last use and revoked state of each bw_publishable_ and bw_secret_ key made for a purpose. The value of a secret key is never returned. The value of a publishable key is.",
        "tags": [
          "keys"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {},
                      "name": {},
                      "kind": {},
                      "prefix": {},
                      "publishable_key": {},
                      "created_at": {},
                      "created_by": {},
                      "last_used_at": {},
                      "revoked_at": {}
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_api_keys"
      },
      "post": {
        "operationId": "create_api_key",
        "summary": "Create an API key",
        "description": "Creates one named key. publishable is for browsers (follows access rules); secret is for servers (bypasses access rules). The value of a secret key is in this response only and cannot be seen again. Only owners and admins can create keys, up to 20 per project.",
        "tags": [
          "keys"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "create_api_key",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "kind": {
                    "type": "string",
                    "enum": [
                      "publishable",
                      "secret"
                    ],
                    "description": "publishable for browsers, secret for servers."
                  },
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 60,
                    "description": "What the key is for. For example: payment server"
                  }
                },
                "required": [
                  "kind",
                  "name"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/api-keys/{id}": {
      "delete": {
        "operationId": "revoke_api_key",
        "summary": "Revoke an API key",
        "description": "Revokes one named key. Requests with that key are refused within 30 seconds. Other keys are not affected. This cannot be undone.",
        "tags": [
          "keys"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The id from list_api_keys."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "revoked": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "revoke_api_key"
      }
    },
    "/projects/{ref}/s3-keys": {
      "get": {
        "operationId": "list_s3_keys",
        "summary": "S3 access keys",
        "description": "The S3 endpoint (endpoint, region, force_path_style), the TUS address for resumable uploads, and each S3 access key's name, access key ID, last use and revoked state. The secret access key is never returned.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "keys": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_s3_keys"
      },
      "post": {
        "operationId": "create_s3_key",
        "summary": "Create an S3 access key",
        "description": "Creates an access key ID and secret access key that the AWS SDKs, the aws CLI or rclone sign requests to /storage/v1/s3 with. It acts as the service role and bypasses access rules, so keep it on a server. The secret access key is in this response only and cannot be seen again. Only owners and admins can create keys, up to 20 per project.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "create_s3_key",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 60,
                    "description": "What the key is for. For example: backup server"
                  }
                },
                "required": [
                  "name"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/s3-keys/{id}": {
      "delete": {
        "operationId": "revoke_s3_key",
        "summary": "Revoke an S3 access key",
        "description": "Revokes one S3 access key. Requests signed with it are refused within 30 seconds. Other keys are not affected. This cannot be undone.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The keys[].id from list_s3_keys."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "revoked": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "revoke_s3_key"
      }
    },
    "/projects/{ref}/tables/{table}/csv": {
      "get": {
        "operationId": "export_table_csv",
        "summary": "Export a table as CSV",
        "description": "Returns a table's rows as CSV (the first line holds the column names), as the console table editor's export does. Up to 1MB comes back; past that it is cut at a whole row and truncated is true. Then split the range with filters and fetch it in several calls. An empty field is NULL and \"\" is an empty string.",
        "tags": [
          "database"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "table",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The table name (list_tables)."
            }
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Order by this column. Empty for the table's own order."
            }
          },
          {
            "name": "desc",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "With true, largest first."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "table": {},
                    "rows": {},
                    "bytes": {},
                    "truncated": {},
                    "csv": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "export_table_csv"
      },
      "post": {
        "operationId": "import_table_csv",
        "summary": "Import CSV into a table",
        "description": "Puts CSV rows into a table, as the console table editor's import does. The first line names the columns, and each goes into the column of the same name (columns changes that). If any row cannot go in, nothing goes in, and the line numbers and reasons come back. Up to 2MB and 10,000 rows. An unquoted empty field is NULL or the column's default. Split anything larger into several calls.",
        "tags": [
          "database"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "table",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The table name (list_tables)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "table": {},
                    "inserted": {},
                    "columns": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "import_table_csv",
        "x-oneend-max-body-bytes": 4194304,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "csv": {
                    "type": "string",
                    "description": "The CSV text. The first line holds the column names."
                  },
                  "columns": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "For each CSV column, the table column it goes into, or \"\" to skip it. As many as the first line has. Leave it out to match by name."
                  }
                },
                "required": [
                  "csv"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/tables": {
      "get": {
        "operationId": "list_tables",
        "summary": "Tables",
        "description": "Returns the project's tables with their columns, an approximate row count and the state of their access rules. If rules are on and there are none, the publishable key sees nothing.",
        "tags": [
          "database"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "name": {},
                      "approximate_rows": {},
                      "row_level_security": {},
                      "policies": {},
                      "columns": {}
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_tables"
      }
    },
    "/projects/{ref}/policies": {
      "get": {
        "operationId": "list_policies",
        "summary": "Access rules",
        "description": "Returns which action on which table is open to whom.",
        "tags": [
          "database"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_policies"
      }
    },
    "/projects/{ref}/storage/policies": {
      "post": {
        "operationId": "post_projects_ref_storage_policies",
        "summary": "Create a file access rule",
        "description": "Adds one access rule to the file table (`objects`). Takes `name`, `command` (select, insert, update, delete or all), `roles`, `using` and `check`. The project login does not own the file table, so rules cannot be made with SQL; use this route.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {}
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/storage/copy-from-import": {
      "post": {
        "operationId": "copy_storage_from_import",
        "summary": "Copy files from an import",
        "description": "Copies a Supabase project's buckets and files into a project here (ref), read with a Supabase account connected in import_sources. A bucket missing here is made with the source's public flag, size limit and types; files go into the same store upload_object writes to, held to the same limits. A file already here with the same size is passed over, so calling again is safe. One call copies up to 200 files (max_files) within 45 seconds; when files remain, call again with the answer's next until done is true. The answer gives each bucket's created, copied, skipped, failed and bytes, and the first few failed files. The Supabase key never appears in the conversation. Bucket access rules are not copied. dry_run shows the counts and changes nothing. Owners, admins and developers only.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "source_project": {},
                    "dry_run": {},
                    "done": {},
                    "next": {},
                    "buckets": {},
                    "failures": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "copy_storage_from_import",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "buckets": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Supabase bucket names to copy. Empty means all of them."
                  },
                  "rename": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string"
                    },
                    "description": "Bucket names to change, {\"Supabase bucket\": \"bucket here\"}. Without it a name is lowercased with spaces as - (My Files becomes my-files)."
                  },
                  "dry_run": {
                    "type": "boolean",
                    "description": "true shows the buckets that would be made and the files that would be copied, without changing anything."
                  },
                  "max_files": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 1000,
                    "description": "The most files to copy in this call (default 200, at most 1000)."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/usage": {
      "get": {
        "operationId": "usage",
        "summary": "Usage",
        "description": "Returns the number of tables, rows, users and files, the storage used, this month's metered amounts, and the limits a minute (limits.outbound_requests_per_minute: outside requests that functions, pg_net and HTTP jobs share; calls to the project's own API are not counted).",
        "tags": [
          "billing"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "tables": {},
                    "approximate_rows": {},
                    "users": {},
                    "files": {},
                    "storage_bytes": {},
                    "database_bytes": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "usage"
      }
    },
    "/projects/{ref}/users": {
      "get": {
        "operationId": "list_users",
        "summary": "The service's users",
        "description": "The users who signed up to the service that uses this project. They are separate from platform accounts. Up to 200 come at a time, and total gives the full count. When has_more is true there are more, so call again with a higher offset. Using the length of users as the head count is wrong.",
        "tags": [
          "auth"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "description": "How many users to get at a time. Default 50, at most 200."
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "description": "How many users to skip. Default 0."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "users": {},
                    "total": {},
                    "limit": {},
                    "offset": {},
                    "has_more": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_users"
      },
      "post": {
        "operationId": "add_user",
        "summary": "Add a user",
        "description": "Creates one user in this project's service. The password must be at least 10 characters.",
        "tags": [
          "auth"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "added": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "add_user",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "description": "The user's email address."
                  },
                  "password": {
                    "type": "string",
                    "description": "At least 10 characters."
                  }
                },
                "required": [
                  "email",
                  "password"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/buckets/{bucket}/empty": {
      "post": {
        "operationId": "empty_bucket",
        "summary": "Empty a bucket",
        "description": "Deletes every file in a bucket and keeps the bucket. It cannot be undone, so use it only when the user clearly asks, and put the bucket name exactly in confirm. removed is the number of files deleted.",
        "tags": [
          "storage"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "bucket",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The bucket name, from list_buckets."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "bucket": {},
                    "removed": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "empty_bucket",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "confirm": {
                    "type": "string",
                    "description": "The bucket name. It must be exactly the same as bucket."
                  }
                },
                "required": [
                  "confirm"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/buckets/{bucket}/objects": {
      "get": {
        "operationId": "list_objects",
        "summary": "Files",
        "description": "Lists one folder of a bucket: its subfolders and files with name, size and type. Choose the folder with prefix (for example avatars/2024/) and find names with search.",
        "tags": [
          "storage"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "bucket",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The bucket name, from list_buckets."
            }
          },
          {
            "name": "prefix",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "The folder to list. Empty for the top."
            }
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Only names containing this."
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 1000,
              "description": "100 by default."
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "description": "How many to skip."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "bucket": {},
                    "prefix": {},
                    "total": {},
                    "objects": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_objects"
      },
      "post": {
        "operationId": "upload_object",
        "summary": "Upload a file",
        "description": "Uploads one file to a bucket (up to 2MB). Text goes as it is; for binary set encoding to base64 and put base64 in content. A file with the same name is refused, unless upsert is true, which replaces it. The bucket's size and type limits apply. Upload bigger files through the storage API (/storage/v1).",
        "tags": [
          "storage"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "bucket",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The bucket name, from list_buckets."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "bucket": {},
                    "name": {},
                    "size": {},
                    "mime": {},
                    "replaced": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "upload_object",
        "x-oneend-max-body-bytes": 4194304,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "content": {
                    "type": "string",
                    "description": "The file content (base64 when encoding is base64)."
                  },
                  "name": {
                    "type": "string",
                    "description": "The path inside the bucket. For example: docs/readme.txt"
                  },
                  "encoding": {
                    "type": "string",
                    "enum": [
                      "utf-8",
                      "base64"
                    ],
                    "description": "utf-8 by default."
                  },
                  "content_type": {
                    "type": "string",
                    "description": "For example image/png. Empty means text or application/octet-stream."
                  },
                  "upsert": {
                    "type": "boolean",
                    "description": "With true, a file with the same name is replaced."
                  }
                },
                "required": [
                  "content",
                  "name"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/buckets/{bucket}/object": {
      "get": {
        "operationId": "download_object",
        "summary": "Download a file",
        "description": "Returns the content of one file (up to 2MB): text as utf-8, binary as base64. For bigger files make an address with create_signed_url.",
        "tags": [
          "storage"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "bucket",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The bucket name, from list_buckets."
            }
          },
          {
            "name": "name",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "The path inside the bucket."
            }
          },
          {
            "name": "encoding",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "utf-8",
                "base64"
              ],
              "description": "Empty chooses by the content."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "bucket": {},
                    "name": {},
                    "size": {},
                    "mime": {},
                    "encoding": {},
                    "content": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "download_object"
      },
      "delete": {
        "operationId": "delete_object",
        "summary": "Delete a file",
        "description": "Removes one file from a bucket. This cannot be undone.",
        "tags": [
          "storage"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "bucket",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The bucket name, from list_buckets."
            }
          },
          {
            "name": "name",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "The path inside the bucket."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "bucket": {},
                    "name": {},
                    "removed": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "delete_object"
      }
    },
    "/projects/{ref}/buckets/{bucket}/upload-urls": {
      "post": {
        "operationId": "create_upload_url",
        "summary": "Make an upload URL",
        "description": "Makes a URL to upload one file larger than 2MB, such as an image or a video. The file itself is not sent through this tool. PUT the file bytes as the body to the returned url, with its type (image/png, video/mp4 and so on) as content-type, as in the curl of example. The URL works for that one name for 2 hours. A file larger than max_bytes, or of a type not in allowed_mime_types, is refused; for a file larger than max_bytes use the resumable (TUS) upload in blackwall://storage. For a public bucket, public_url is its public address once uploaded.",
        "tags": [
          "storage"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "bucket",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "A bucket name from list_buckets."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "bucket": {},
                    "name": {},
                    "method": {},
                    "url": {},
                    "expires_at": {},
                    "max_bytes": {},
                    "allowed_mime_types": {},
                    "public_url": {},
                    "example": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "create_upload_url",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "The path inside the bucket, such as videos/intro.mp4."
                  },
                  "upsert": {
                    "type": "boolean",
                    "description": "When true, replaces a file with the same name. By default that is refused."
                  }
                },
                "required": [
                  "name"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/buckets/{bucket}/signed-urls": {
      "post": {
        "operationId": "create_signed_url",
        "summary": "Create a signed URL",
        "description": "Makes an address anyone can download one file of a private bucket from for a set time (1 hour by default, 7 days at most). Whoever has the address downloads without signing in, so make only what you need.",
        "tags": [
          "storage"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "bucket",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The bucket name, from list_buckets."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "bucket": {},
                    "name": {},
                    "url": {},
                    "expires_at": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "create_signed_url",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "The path inside the bucket."
                  },
                  "expires_in": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 604800,
                    "description": "Seconds it stays open. 3600 by default."
                  }
                },
                "required": [
                  "name"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/buckets/{bucket}": {
      "patch": {
        "operationId": "update_bucket",
        "summary": "Change bucket settings",
        "description": "Changes whether a bucket is public, the largest one file may be, and the types it takes. Only what you give changes. Making it public lets anyone download its files, so do it only when the user clearly asks. Files already there stay as they are.",
        "tags": [
          "storage"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "bucket",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The bucket name, from list_buckets."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "bucket": {},
                    "public": {},
                    "file_size_limit": {},
                    "allowed_mime_types": {},
                    "files": {},
                    "bytes": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "update_bucket",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "public": {
                    "type": "boolean",
                    "description": "true for public, false for private."
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete_bucket",
        "summary": "Delete a bucket",
        "description": "Deletes an empty bucket. One that still holds files is refused, so empty it first with empty_bucket. It cannot be undone. Use it only when the user clearly asks, and put the bucket name exactly in confirm.",
        "tags": [
          "storage"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "bucket",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The bucket name, from list_buckets."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "bucket": {},
                    "deleted": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "delete_bucket",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "confirm": {
                    "type": "string",
                    "description": "The bucket name. It must be exactly the same as bucket."
                  }
                },
                "required": [
                  "confirm"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/buckets": {
      "get": {
        "operationId": "list_buckets",
        "summary": "Buckets",
        "description": "Returns the storage buckets with the number of files and the size of each.",
        "tags": [
          "storage"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_buckets"
      },
      "post": {
        "operationId": "create_bucket",
        "summary": "Create a bucket",
        "description": "Anyone can read a public bucket. Only the uploader can read a private bucket. file_size_limit and allowed_mime_types set the largest file and the types it takes from the start (later, with update_bucket).",
        "tags": [
          "storage"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "bucket": {},
                    "public": {},
                    "file_size_limit": {},
                    "allowed_mime_types": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "create_bucket",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "pattern": "^[a-z0-9][a-z0-9._-]{1,62}$",
                    "description": "The bucket name: 2 to 63 characters of lowercase letters, digits, \". _ -\"."
                  },
                  "public": {
                    "type": "boolean",
                    "description": "Private by default."
                  }
                },
                "required": [
                  "id"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/deployments/sources/upload-urls": {
      "post": {
        "operationId": "create_source_upload_url",
        "summary": "Make an upload URL for a deployment archive",
        "description": "For deploying a site too large for deploy_files (over 3MB) without a repository: makes a URL to upload one archive (.zip, .tar, .tar.gz) to. The archive itself is not sent through this tool. PUT the archive as the body to the returned url (as in the curl of example, with no token); the answer carries source, and deploy_source with that source deploys it. The URL works for this project for 1 hour and takes up to max_bytes.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "method": {},
                    "url": {},
                    "expires_at": {},
                    "max_bytes": {},
                    "formats": {},
                    "example": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "create_source_upload_url"
      }
    },
    "/projects/{ref}/deployments/sources": {
      "post": {
        "operationId": "post_projects_ref_deployments_sources",
        "summary": "Upload files to deploy",
        "description": "Send the files to deploy, without a repository, as one archive (`.zip`, `.tar`, `.tar.gz`) as the body. It is kept under the digest of its contents; the deployment is a second call, `POST /deployments` with `{\"source\": \"<digest>\"}`, so the same bytes can be deployed to a preview and then to production.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-max-body-bytes": 52428800,
        "requestBody": {
          "required": true,
          "content": {
            "application/octet-stream": {
              "schema": {
                "type": "string",
                "contentMediaType": "application/octet-stream"
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/deployments": {
      "post": {
        "operationId": "post_projects_ref_deployments",
        "summary": "Create a deployment",
        "description": "Three kinds, by what the body holds. `source` is the digest of an archive sent to `POST /deployments/sources`; `files` (or `files_base64`) maps paths to contents; with neither, `app`, `branch` and `commit` build a commit from the repository. `target` set to `production` deploys to production, otherwise to a preview.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "deploy_source",
        "x-oneend-max-body-bytes": 4194304,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "source": {
                    "type": "string",
                    "pattern": "^[0-9a-f]{64}$",
                    "description": "The source returned by the upload (a 64 character SHA-256)."
                  },
                  "files": {
                    "type": "string"
                  },
                  "files_base64": {
                    "type": "string"
                  },
                  "app": {
                    "type": "string",
                    "description": "The app to deploy (a name from list_apps). Leave it out when there is one app."
                  },
                  "branch": {
                    "type": "string",
                    "description": "The name of the preview, which becomes its address. preview by default."
                  },
                  "commit": {
                    "type": "string"
                  },
                  "wait": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 120,
                    "description": "Seconds to wait for the build to finish (ready or error). The default 0 answers at once. If it is not done in time the answer has still_running: true and retry_after_seconds. MCP clients usually give up on a call after about 60 seconds, so around 45 is safe."
                  },
                  "block_on_advisors": {
                    "type": "boolean",
                    "description": "With true, a production deploy is refused while get_advisors has any critical security problem (advisors.critical). The default false deploys and reports the count and the top 3 in advisors. Previews are never held back."
                  },
                  "prebuilt": {
                    "type": "boolean",
                    "description": "With true, nothing is built and the files are served as they are."
                  },
                  "target": {
                    "type": "string",
                    "enum": [
                      "preview",
                      "production"
                    ],
                    "description": "preview by default."
                  },
                  "message": {
                    "type": "string",
                    "description": "A note to show in the deployment list (optional)."
                  }
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "list_deployments",
        "summary": "Deployments",
        "description": "Shows this project's recent deployments, newest first: status (queued, building, ready, error), environment, addresses, branch, commit and the reason it failed. Deleted deployments are left out (list_deleted_deployments shows them). When next_before is set, pass it as before for the next page. url is the deployment's own dpl- address, production_url the production address, preview_url its branch's preview address. preview_protection says who can open a preview address (members: organization members only, the default / password / off: anyone); null for production, whose address is always public, though with protection on a dpl- address is protected even for a production build.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "description": "Default 20."
            }
          },
          {
            "name": "before",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^dpl-[0-9a-f]{16}$",
              "description": "Start after this deployment (older ones). next_before from the previous page."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "preview_protection": {},
                    "deployments": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_deployments"
      }
    },
    "/projects/{ref}/deployments/{id}/redeploy": {
      "post": {
        "operationId": "redeploy",
        "summary": "Redeploy",
        "description": "Builds the same commit as one deployment again, to the same environment. Use it to rerun a build that failed for a reason unrelated to the commit (an environment variable added later, a package registry that was briefly down). Only owners and admins can deploy to production. The answer has the new deployment's addresses (url, preview_url or production_url) and the security check (advisors).",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The deployment name, starting with dpl-."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "id": {},
                    "status": {},
                    "environment": {},
                    "preview_protection": {},
                    "advisors": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "redeploy"
      }
    },
    "/projects/{ref}/deployments/{id}/promote": {
      "post": {
        "operationId": "promote_deployment",
        "summary": "Promote a preview to production",
        "description": "Moves a finished preview deployment to production. The same commit is built again with the production environment variables, and when it finishes the production address points to the result. The preview build is not reused so that preview keys never reach production. Given a finished production deployment, the production address points to it now without a rebuild, and a hold a rollback put on production (production_held) is lifted; give the one serving now to lift the hold alone. Only owners and admins can do this.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The dpl- name of the deployment to promote: usually a preview, or a production deployment to lift a hold."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "id": {},
                    "status": {},
                    "environment": {},
                    "preview_protection": {},
                    "advisors": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)",
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "promote_deployment"
      }
    },
    "/projects/{ref}/deployments/{id}/rollback": {
      "post": {
        "operationId": "rollback_deployment",
        "summary": "Roll back production",
        "description": "Points the production address straight back to a production deployment that served before. Nothing is rebuilt, and the switch takes a few seconds. Custom domains follow. The answer has that deployment's url and production_url. Production is then held (production_held): new production builds are built but not served until you promote one with promote_deployment. Only owners and admins can do this.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The dpl- name of the production deployment to go back to."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "id": {},
                    "status": {},
                    "production_held": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "rollback_deployment"
      }
    },
    "/projects/{ref}/deploy-hooks": {
      "get": {
        "operationId": "list_deploy_hooks",
        "summary": "Deploy hooks",
        "description": "Shows the deploy hooks and their addresses. A POST to an address builds the latest commit of its branch, so the address itself is a secret. A read-only token sees only the last four characters of each address (secret_hidden); a token with write access sees all of it.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "hooks": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-permissions": [
          "secrets.read (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "list_deploy_hooks"
      },
      "post": {
        "operationId": "create_deploy_hook",
        "summary": "Create a deploy hook",
        "description": "Creates an address that triggers a build without a push. Have a CMS call it when a post is published, or a scheduled job. Only owners and admins can create a hook for the production branch.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "create_deploy_hook",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "app": {
                    "type": "string",
                    "description": "The name from list_apps."
                  },
                  "branch": {
                    "type": "string",
                    "description": "The branch whose latest commit is built."
                  },
                  "name": {
                    "type": "string",
                    "description": "A name to recognise the hook by."
                  }
                },
                "required": [
                  "app",
                  "branch"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/deploy-hooks/{id}": {
      "delete": {
        "operationId": "remove_deploy_hook",
        "summary": "Remove a deploy hook",
        "description": "Removes a deploy hook. Whatever called its address no longer causes a deployment.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The id from list_deploy_hooks."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "id": {},
                    "removed": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "remove_deploy_hook"
      }
    },
    "/projects/{ref}/deployment-retention": {
      "get": {
        "operationId": "get_deployment_retention",
        "summary": "Deployment retention",
        "description": "Returns how many days canceled, failed, preview and production deployments are kept: the days in force (days), the project's own number (project_days, null when it follows the plan) and the plan default (plan_days). Also what is kept whatever the period (always_kept) and how many days a deleted deployment can be restored (restore_days).",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "canceled": {},
                    "error": {},
                    "preview": {},
                    "production": {},
                    "always_kept": {},
                    "restore_days": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_deployment_retention"
      },
      "put": {
        "operationId": "set_deployment_retention",
        "summary": "Change deployment retention",
        "description": "Changes how long each kind of deployment is kept. A deployment past its period is deleted and can be restored with restore_deployment for 3 days. Recent and served deployments are kept whatever the period. Only project admins can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "set_deployment_retention",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "canceled_days": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "minimum": 1,
                    "maximum": 3650,
                    "description": "Days to keep canceled or skipped deployments (1 to 3650). null for the plan default. Left out: kept as it is."
                  },
                  "error_days": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "minimum": 1,
                    "maximum": 3650,
                    "description": "Days to keep failed deployments (1 to 3650). null for the plan default. Left out: kept as it is."
                  },
                  "preview_days": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "minimum": 1,
                    "maximum": 3650,
                    "description": "Days to keep preview deployments (1 to 3650). null for the plan default. Left out: kept as it is."
                  },
                  "production_days": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "minimum": 1,
                    "maximum": 3650,
                    "description": "Days to keep production deployments (1 to 3650). null for the plan default. Left out: kept as it is."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/deployments/deleted": {
      "get": {
        "operationId": "list_deleted_deployments",
        "summary": "Recently deleted deployments",
        "description": "Returns the deployments deleted in the last 3 days (by hand or because their retention period ended) and until when each can be restored (restorable_until). Meanwhile their own address answers 410.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "deployments": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_deleted_deployments"
      }
    },
    "/projects/{ref}/deployments/{id}": {
      "delete": {
        "operationId": "delete_deployment",
        "summary": "Delete a deployment",
        "description": "Deletes one deployment. A deployment being served or still building cannot be deleted. It can be restored with restore_deployment for 3 days, then its files and build log are removed. Production deployments take a project admin, the rest a developer or above.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^dpl-[0-9a-f]{16}$",
              "description": "The deployment id (dpl-…). list_deployments or list_deleted_deployments shows it."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "id": {},
                    "deleted": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "delete_deployment"
      },
      "get": {
        "operationId": "get_deployment",
        "summary": "One deployment and its build log",
        "description": "Shows the status of one deployment, its addresses and the end of its build log. When a build failed, the reason is usually in the last few lines of the log. Environment variable values the customer set are masked as ••••••. url is the deployment's own dpl- address; production_url or preview_url is the production or branch address. preview_protection says who can open a preview address (members: organization members only, the default / password / off: anyone); null for production, whose address is always public. With wait (seconds) it waits for the build to finish.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The deployment name, starting with dpl-."
            }
          },
          {
            "name": "tail",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 5000,
              "description": "How many lines from the end of the build log. Default 200."
            }
          },
          {
            "name": "wait",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 120,
              "description": "Seconds to wait for the build to finish (ready or error). The default 0 answers at once. If it is not done in time the answer has still_running: true and retry_after_seconds. MCP clients usually give up on a call after about 60 seconds, so around 45 is safe."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "preview_protection": {},
                    "build_log": {},
                    "build_log_lines": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_deployment"
      }
    },
    "/projects/{ref}/deployments/{id}/restore": {
      "post": {
        "operationId": "restore_deployment",
        "summary": "Restore a deployment",
        "description": "Restores a deployment deleted in the last 30 days. Its own address answers again, and it can be rolled back or promoted to. Production deployments take a project admin, the rest a developer or above.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^dpl-[0-9a-f]{16}$",
              "description": "The deployment id (dpl-…). list_deployments or list_deleted_deployments shows it."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "id": {},
                    "restored": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "restore_deployment"
      }
    },
    "/projects/{ref}/domains": {
      "get": {
        "operationId": "list_domains",
        "summary": "Domains",
        "description": "Shows the domains connected to this project with what each is for (site/api), the branch it follows, where it redirects, its verification state (with the TXT record to add if not verified yet) and its certificate state.",
        "tags": [
          "domains"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "domains": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_domains"
      },
      "post": {
        "operationId": "add_domain",
        "summary": "Connect a domain",
        "description": "Connects a domain. Add the returned verification_record (TXT) to DNS and it is verified within a few minutes. With target=api the address answers as the project API (data, sign-in, storage). With branch, it follows that branch's preview. Wildcards such as *.example.com work. With pair_www=true the www address is connected too and one redirects to the other.",
        "tags": [
          "domains"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "domains": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "add_domain",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "hostname": {
                    "type": "string",
                    "description": "For example: example.com, api.example.com, *.example.com"
                  },
                  "target": {
                    "type": "string",
                    "enum": [
                      "site",
                      "api"
                    ],
                    "description": "site for the deployed site, api for the project API."
                  },
                  "branch": {
                    "type": "string",
                    "description": "Site only. Empty means production."
                  },
                  "pair_www": {
                    "type": "boolean",
                    "description": "Also connect the www address and redirect one to the other."
                  },
                  "app": {
                    "type": "string",
                    "description": "The app name (name from list_apps). Empty means the project's site (the app with project_site true)."
                  }
                },
                "required": [
                  "hostname"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/domains/{hostname}": {
      "delete": {
        "operationId": "remove_domain",
        "summary": "Disconnect a domain",
        "description": "Disconnects a domain. The address stops answering within a few seconds. Use it only when the user clearly asks, and put the domain exactly in confirm.",
        "tags": [
          "domains"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "hostname",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The connected domain."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "domains": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "remove_domain",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "confirm": {
                    "type": "string",
                    "description": "The domain. It must be the same as hostname (case does not matter)."
                  }
                },
                "required": [
                  "confirm"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/domains/{hostname}/redirect": {
      "put": {
        "operationId": "set_domain_redirect",
        "summary": "Redirect a domain",
        "description": "Makes this domain redirect to another domain of the same project, or, with to empty, serve the site again. With a path in to (example.com/vision), the visited path is appended to it and the query string goes along: vision.example.com/x?y=1 → example.com/vision/x?y=1, and the home page goes to example.com/vision. The domain in to must be connected to this project and not itself a redirect.",
        "tags": [
          "domains"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "hostname",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The domain to redirect."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "domains": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "set_domain_redirect",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "to": {
                    "type": "string",
                    "description": "A domain, or a domain and a path (for example example.com/vision). Empty turns the redirect off."
                  },
                  "status": {
                    "type": "integer",
                    "enum": [
                      308,
                      307,
                      301,
                      302
                    ],
                    "description": "The status code. 308 (permanent, keeps the method) by default. Left out, the current one stays."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/edge": {
      "get": {
        "operationId": "get_edge",
        "summary": "Firewall and cache",
        "description": "Shows this project's IP deny and allow lists, the request limit per minute for one address, what they apply to, and when the cache was last purged.",
        "tags": [
          "domains"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "deny": {},
                    "allow": {},
                    "rate_per_minute": {},
                    "scope": {},
                    "cache_purged_at": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_edge"
      },
      "put": {
        "operationId": "set_edge",
        "summary": "Change the firewall",
        "description": "Changes the IP deny list, the allow list (empty allows everyone), the request limit per minute (10 to 100000, null for the platform default) and what they apply to (all/site/api). Only the fields you give change. Only owners and admins can do this.",
        "tags": [
          "domains"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "deny": {},
                    "allow": {},
                    "rate_per_minute": {},
                    "scope": {},
                    "cache_purged_at": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "set_edge",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "deny": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "IP addresses or CIDR ranges to refuse."
                  },
                  "allow": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "IP addresses or CIDR ranges to allow. Empty allows everyone."
                  },
                  "rate_per_minute": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "description": "Requests per minute from one address, 10 to 100000. null for the platform default."
                  },
                  "scope": {
                    "type": "string",
                    "enum": [
                      "all",
                      "site",
                      "api"
                    ],
                    "description": "What the rules apply to: all, site or api."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/edge/purge": {
      "post": {
        "operationId": "purge_edge_cache",
        "summary": "Purge the cache",
        "description": "Discards every response stored at the edge because a server deployment allowed sharing with s-maxage. From the next request, the deployment answers again.",
        "tags": [
          "domains"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "deny": {},
                    "allow": {},
                    "rate_per_minute": {},
                    "scope": {},
                    "cache_purged_at": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "purge_edge_cache"
      }
    },
    "/projects/{ref}/branch-previews": {
      "get": {
        "operationId": "get_branch_previews",
        "summary": "Branch previews",
        "description": "Shows whether a push to a branch other than production builds a preview in this project's organization (branch_previews). false means only what reaches the production branch (usually main) is built.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "organization": {},
                    "branch_previews": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_branch_previews"
      },
      "put": {
        "operationId": "set_branch_previews",
        "summary": "Change branch previews",
        "description": "Turns preview builds for branch pushes on or off for the whole organization. false builds only what reaches the production branch (usually main); a skipped push stays in the deployment history as skipped. Redeploys, uploads and deploy hooks still build. Applies to every project in the organization. Only owners and admins can do this.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "organization": {},
                    "branch_previews": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "team.manage (owner or admin)"
        ],
        "x-oneend-mcp-tool": "set_branch_previews",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean",
                    "description": "true builds a preview for every branch push."
                  }
                },
                "required": [
                  "enabled"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/preview-protection": {
      "get": {
        "operationId": "get_preview_protection",
        "summary": "Preview protection",
        "description": "Shows who can open deployments that are not production (branch previews, per-deployment addresses): off, members (organisation members only), password. Also returns which addresses are protected (scope), addresses let in without signing in (trusted_ips), paths that pass unchecked (options_paths), bypass keys (bypass_secrets, only their last four characters) and share links (share_links).",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "mode": {},
                    "has_password": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_preview_protection"
      },
      "put": {
        "operationId": "set_preview_protection",
        "summary": "Change preview protection",
        "description": "Changes who can open previews. members means organisation members signed in to the console, password means one shared password (a password of at least 8 characters is needed the first time), off means anyone. The production address and connected domains are always public. Only owners and admins can do this.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "set_preview_protection",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "mode": {
                    "type": "string",
                    "enum": [
                      "off",
                      "members",
                      "password"
                    ],
                    "description": "off, members or password."
                  },
                  "password": {
                    "type": "string",
                    "description": "When mode is password. Empty keeps the password already set."
                  }
                },
                "required": [
                  "mode"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/apps": {
      "get": {
        "operationId": "list_apps",
        "summary": "Connected repositories and build settings",
        "description": "For each repository that deploys to this project, shows the production branch, the folder to build (root_directory), the framework preset (framework; null means detect automatically) and the build command, output directory and install command overrides (build_command, output_directory, install_command; null means the preset default). detected_framework is what the latest build used, and frameworks lists the presets you can choose. A repository appears on its first push.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "apps": {},
                    "frameworks": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_apps"
      }
    },
    "/projects/{ref}/apps/{name}": {
      "delete": {
        "operationId": "delete_app",
        "summary": "Delete an app",
        "description": "Deletes one app of the project (an app whose folder a monorepo removed). Its addresses stop answering at once, its builds in progress are cancelled, and its deployments are deleted with no restore, their files gone within minutes. A push no longer builds it even if the folder is still in the repository. It cannot be undone. The project's own site, an app with domains and an app with disks are refused, with what to do first. Use it only when the user clearly asks, and put the app name exactly in confirm. Only owners and admins can do this.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The name from list_apps."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "delete_app",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "confirm": {
                    "type": "string",
                    "description": "The app name. It must be exactly the same as name."
                  }
                },
                "required": [
                  "confirm"
                ]
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "update_app",
        "summary": "Change build settings",
        "description": "Changes one repository's production branch, folder to build, framework preset, build command, output directory or install command. For a monorepo, put the app folder (for example apps/web) in root_directory. Values you leave out stay as they are; null puts one back to detect automatically (the preset default). An empty command skips that step. If the repository's blackwall.json sets the same item, its value comes first. Takes effect from the next deployment, except port (the port the server listens on), which restarts the server within a minute. Only owners and admins can do this.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The name from list_apps."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "update_app",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "production_branch": {
                    "type": "string",
                    "description": "The branch that deploys to production."
                  },
                  "root_directory": {
                    "type": "string",
                    "description": "A path relative to the repository. \".\" for the whole repository."
                  },
                  "run_as": {
                    "type": "string",
                    "enum": [
                      "platform",
                      "image"
                    ],
                    "description": "Who the server runs as. platform (the default) is an ordinary user (10001); image is the user the image names, root included, inside a gVisor sandbox. Use image only for Dockerfile apps that must start as root, like the official WordPress image. The server restarts within a minute, without a rebuild."
                  },
                  "port": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "minimum": 1,
                    "maximum": 65535,
                    "description": "The port the server listens on inside its container. null for the image's EXPOSE, or 3000. A change restarts the server within a minute, with no new deployment."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/logs": {
      "get": {
        "operationId": "get_logs",
        "summary": "Logs",
        "description": "Shows what happened in the project, newest first: requests to the site, API, sign-in and functions (method, path, status, time taken) and the lines the deployed servers and functions printed. If the app returns 500, look here first with level set to error. For the next page, pass the response's next_before as before. Query strings are not stored.",
        "tags": [
          "logs"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "source",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "site",
                "server",
                "api",
                "auth",
                "functions",
                "build"
              ],
              "description": "Where the lines come from: site, server, api, auth, functions, build."
            }
          },
          {
            "name": "level",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "warn",
                "error"
              ],
              "description": "warn for warnings and errors, error for errors only."
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "before",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Only lines older than this time. The previous response's next_before."
            }
          },
          {
            "name": "deployment",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "description": "Default 100."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "lines": {},
                    "next_before": {},
                    "retention_days": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_logs"
      }
    },
    "/projects/{ref}/rows/{table}": {
      "get": {
        "operationId": "read_rows",
        "summary": "Read a table",
        "description": "Reads the first rows of a table as they are. For checking; when you need conditions, use run_sql.",
        "tags": [
          "database"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "table",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The table name."
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "description": "Default 50 rows."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "columns": {},
                    "rows": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "read_rows"
      }
    },
    "/projects/{ref}/migrations": {
      "get": {
        "operationId": "list_migrations",
        "summary": "Migration history",
        "description": "Returns the version, name and time applied of each migration applied with apply_migrations, oldest first. The record is kept in the project's oneend_migrations table.",
        "tags": [
          "database"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "ledger": {},
                    "migrations": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_migrations"
      },
      "post": {
        "operationId": "apply_migrations",
        "summary": "Apply migrations",
        "description": "Runs the migrations not yet applied, in version order, each in a transaction of its own, and records them. Versions already applied are skipped. If one fails, only that one is rolled back and applying stops; the ones before it stay applied. Use this instead of run_sql when changing the schema, and you can apply the same changes to other projects exactly as they are. Files from supabase/migrations can be sent as they are: Supabase names such as public., auth.uid(), storage. and to authenticated are run in this project's names and reported in translated (Supabase name translation). The ledger keeps each file as written.",
        "tags": [
          "database"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "applied": {},
                    "recorded_only": {},
                    "already_applied": {},
                    "drifted": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "apply_migrations",
        "x-oneend-max-body-bytes": 8388608,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "migrations": {
                    "type": "array",
                    "maxItems": 500,
                    "items": {
                      "type": "object",
                      "properties": {
                        "version": {
                          "type": "string",
                          "pattern": "^[0-9]{1,32}$"
                        },
                        "name": {
                          "type": "string"
                        },
                        "sql": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "version",
                        "sql"
                      ],
                      "additionalProperties": false
                    },
                    "description": "The migrations, each with version, name and sql."
                  },
                  "include_all": {
                    "type": "boolean",
                    "description": "Also applies versions earlier than the last applied one. False by default."
                  },
                  "record_only": {
                    "type": "boolean",
                    "description": "Records them as applied without running them. False by default."
                  },
                  "dry_run": {
                    "type": "boolean",
                    "description": "Only tells you what would be applied."
                  }
                },
                "required": [
                  "migrations"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/migrations/{version}": {
      "delete": {
        "operationId": "remove_migration_record",
        "summary": "Remove a migration record",
        "description": "Marks one migration as not applied. Only the record is removed; what the migration made is left as it is.",
        "tags": [
          "database"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[0-9]{1,32}$",
              "description": "The version from list_migrations."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "version": {},
                    "removed": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "remove_migration_record"
      }
    },
    "/projects/{ref}/schema": {
      "get": {
        "operationId": "dump_schema",
        "summary": "The schema as SQL",
        "description": "Returns the project's schema (types, sequences, tables and constraints, foreign keys, indexes, functions, views, triggers, RLS and rules) as SQL that builds it again. Row data and privileges are not included.",
        "tags": [
          "database"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "sql": {},
                    "objects": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "dump_schema"
      }
    },
    "/projects/{ref}/types/typescript": {
      "get": {
        "operationId": "generate_typescript_types",
        "summary": "Generate TypeScript types",
        "description": "Makes the Database type for supabase-js's createClient<Database>() from the project's tables, views, functions and enums. Call it again after changing the schema.",
        "tags": [
          "database"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "schema",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "public by default. A schema the project made (name from list_schemas) works too."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "schema": {},
                    "types": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "generate_typescript_types"
      }
    },
    "/projects/{ref}/sql/query": {
      "post": {
        "operationId": "query_sql",
        "summary": "Query SQL (read-only)",
        "description": "Runs one query (SELECT and the like) on the project's PostgreSQL database in a read-only transaction and returns the rows. A statement that changes data or structure is refused; use run_sql for that. A read-only token can call it. It does not open Vault secrets (decrypted_secret in vault.decrypted_secrets is empty). SQL follows the PostgreSQL 16 documentation (https://www.postgresql.org/docs/16/sql-commands.html).",
        "tags": [
          "database"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "query_sql",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "sql": {
                    "type": "string",
                    "description": "One query to run."
                  }
                },
                "required": [
                  "sql"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/sql": {
      "post": {
        "operationId": "run_sql",
        "summary": "Run SQL (changes)",
        "description": "Runs SQL that changes data or structure (CREATE, INSERT, UPDATE, DELETE and so on) on the project's PostgreSQL database and returns the resulting rows. For reading only, use query_sql. SQL follows the PostgreSQL 16 documentation (https://www.postgresql.org/docs/16/sql-commands.html). A new table gets access rules turned on automatically, so unless you then create rules, the publishable key sees nothing. The role names to use in rules are <ref>_anon, <ref>_authenticated and <ref>_service_role. SQL written for Supabase (public., auth.uid(), storage., to authenticated) is run in this project's names, and translated says what was replaced (Supabase name translation).",
        "tags": [
          "database"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "run_sql",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "sql": {
                    "type": "string",
                    "description": "One SQL statement to run."
                  }
                },
                "required": [
                  "sql"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/users/{id}/links": {
      "post": {
        "operationId": "generate_link",
        "summary": "Make a sign-in link",
        "description": "Makes the link a sign-in mail would carry and returns it instead of mailing it: invite (creates the user when there is none), magiclink (sign-in without a password), recovery (a password reset) or signup (confirms a new sign-up; needs password). Whoever opens action_link is signed in as that user, so it is as good as a password. Make one only when the user clearly asks, and give it only to that person. redirect_to must be an address added with add_redirect_url. Only roles that can see the secret key (owner, admin, developer) can do this.",
        "tags": [
          "auth"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The user's email address."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "type": {},
                    "user_id": {},
                    "email": {},
                    "action_link": {},
                    "email_otp": {},
                    "redirect_to": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "secrets.read (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "generate_link",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": [
                      "invite",
                      "magiclink",
                      "recovery",
                      "signup"
                    ],
                    "description": "invite, magiclink, recovery or signup."
                  },
                  "password": {
                    "type": "string",
                    "description": "For signup, the new user's password (at least 10 characters)."
                  },
                  "data": {
                    "type": "object",
                    "description": "User metadata for a user that invite, signup or magiclink creates."
                  },
                  "redirect_to": {
                    "type": "string",
                    "description": "Where to return after confirming. Only an address in list_redirect_urls."
                  }
                },
                "required": [
                  "type"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/users/{id}": {
      "patch": {
        "operationId": "update_user",
        "summary": "Change a user",
        "description": "Changes one of this project's users: the email, the password, whether the email is confirmed, a ban and its end, and the metadata. Only what you give changes. A new password or a ban signs the person out everywhere. A password needs at least 10 characters, and one known from a breach is refused. Metadata is merged into what is there. Use it only when the user clearly asks.",
        "tags": [
          "auth"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The id (UUID) from list_users."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "user": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "update_user",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "description": "The new email address."
                  },
                  "password": {
                    "type": "string",
                    "description": "The new password (at least 10 characters)."
                  },
                  "email_confirm": {
                    "type": "boolean",
                    "description": "With true, marks the email address as confirmed."
                  },
                  "ban_duration": {
                    "type": "string",
                    "description": "How long to ban, such as 24h, 30m or 876000h (in effect forever). none lifts a ban."
                  },
                  "user_metadata": {
                    "type": "object",
                    "description": "Values to merge into the metadata the user may change."
                  },
                  "app_metadata": {
                    "type": "object",
                    "description": "Values to merge into the metadata only a server changes (a role, a plan and so on)."
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "remove_user",
        "summary": "Remove a user",
        "description": "Removes one of the project's users. This cannot be undone. id is the value list_users returned. Use it only when the user clearly asks, and put that user's email (or id) exactly in confirm.",
        "tags": [
          "auth"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The id (UUID) from list_users."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "id": {},
                    "removed": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "remove_user",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "confirm": {
                    "type": "string",
                    "description": "The email or id of the user to remove. It must match email or id in list_users."
                  }
                },
                "required": [
                  "confirm"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/users/import": {
      "post": {
        "operationId": "import_users",
        "summary": "Import users",
        "description": "Imports up to 500 users at once from another service (for example a Supabase auth.users export). Ids and bcrypt password hashes are kept, so nobody has to choose a new password. The whole list is checked first: a wrong row is named by number and nothing is imported. An account that already exists is skipped, so repeating a call is safe. dry_run=true only checks.",
        "tags": [
          "auth"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "dry_run": {},
                    "found": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "import_users",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "users": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "email": {
                          "type": "string"
                        },
                        "id": {
                          "type": "string"
                        },
                        "encrypted_password": {
                          "type": "string"
                        },
                        "email_confirmed": {
                          "type": "boolean"
                        },
                        "user_metadata": {
                          "type": "object"
                        },
                        "app_metadata": {
                          "type": "object"
                        }
                      },
                      "required": [
                        "email"
                      ],
                      "additionalProperties": false
                    },
                    "description": "The accounts: { email, id?, encrypted_password?, email_confirmed?, user_metadata?, app_metadata? }."
                  },
                  "dry_run": {
                    "type": "boolean",
                    "description": "Check the list and import nothing."
                  }
                },
                "required": [
                  "users"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/retry-provisioning": {
      "post": {
        "operationId": "retry_provisioning",
        "summary": "Retry a project that failed to set up",
        "description": "Sets up again a project whose database could not be created. Use it when another tool refuses with \"could not create\". Do not create a new project: this continues setting up the same one, and a new one only doubles the bill.",
        "tags": [
          "projects"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "retried": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "retry_provisioning"
      }
    },
    "/projects/{ref}/functions": {
      "get": {
        "operationId": "list_functions",
        "summary": "Functions",
        "description": "Shows the deployed functions with the address to call each one and whether it is public. egress says whether outbound requests are on, and outbound_requests_per_minute is the limit a minute on outside requests that functions, pg_net and HTTP jobs share (calls to the project's own API are not counted).",
        "tags": [
          "functions"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "functions": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_functions"
      }
    },
    "/projects/{ref}/functions/{name}": {
      "get": {
        "operationId": "get_function",
        "summary": "Read a function's code",
        "description": "Shows the code and version of a deployed function. Read the current code before changing it. When deploy_function answered status \"building\", build.status (building, deployed or failed) and build.error tell how it ended.",
        "tags": [
          "functions"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The function name."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "name": {},
                    "status": {},
                    "public": {},
                    "version": {},
                    "url": {},
                    "updated_at": {},
                    "bundled": {},
                    "bytes": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_function"
      },
      "put": {
        "operationId": "deploy_function",
        "summary": "Deploy a function",
        "description": "Deploys one function. A function with the same name is replaced as a whole, and the next call runs the new code. The code is one TypeScript file that exports, with export default, (request, { sql }) => response. request has method, headers, claims (the claims of the key it was called with: role anon, authenticated or service_role; null for a public function called with no key), text() and json(); sql(text, values) runs one SQL statement with this project's service_role privileges and returns an array of rows. The response is an object (sent as JSON), a string, or { status, headers, body }. To use npm packages, send dependencies ({\"zod\":\"^3.23.8\"}) or package_json (a string) with it. They are installed at deploy time and bundled with the code into one ESM file (up to 5MB; install scripts are not run; no native modules). A package set installed once is reused, so from the second deploy on it takes seconds. If it has not finished in 40 seconds, it answers status \"building\" at once and the deploy carries on on the server. Then call get_function again until build.status is deployed or failed. For several files, send them together as files ({\"lib/util.ts\": \"...\"}) and import them by relative path. To send a whole folder, leave source empty and put everything, index.ts included, in files. As on Supabase, the imports of a deno.json (or import_map.json) and npm:, jsr: and URL imports (such as npm:zod@3, jsr:@supabase/supabase-js@2, https://esm.sh/…, https://deno.land/std@0.177.0/http/server.ts) work. npm:, jsr: and esm.sh are installed as npm packages at deploy time; any other URL is fetched once at deploy time and bundled with the code (the addresses and SHA-256 fetched are in get_function's remote_imports, and must match a deno.lock when there is one). Nothing is fetched while the function runs. As with Supabase's supabase/functions/<name>/ folder, when the code imports ../_shared/cors.ts, put it in files as \"../_shared/cors.ts\". Only folders beside the function folder can be sent this way. One call may run for 150 seconds (as on Supabase). To change that, use set_function_limits. The caller's Authorization header (when it is a key of this project) reaches the function as it was sent, so createClient(url, anonKey, { global: { headers: { Authorization: req.headers.get('Authorization') } } }) acts as that person. When you change a bundled function, send back the package_json and files that get_function returned, as they are. Leave them out and it becomes a single-file function. Network access is off by default and can be turned on with set_function_egress. The production environment variables arrive in process.env. Only owners and admins can deploy functions. Who can call it: a private function (the default) needs a key of this project: the publishable key (claims.role anon), a signed-in user's token (authenticated) or the secret key (service_role). This is what Supabase's verify_jwt checks, so supabase.functions.invoke and a fetch with the publishable key work as they are. To accept signed-in users only, check request.claims.role in the function. With public set to true, anyone can call it, with no key at all. Use that only for requests that arrive without a key, such as a payment provider's webhook. Calling: POST https://<ref>.<zone>/functions/v1/<name>, with the header Authorization: Bearer <publishable key, user token or secret key>.",
        "tags": [
          "functions"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Starts with a lowercase letter; lowercase letters, digits and hyphens. It becomes the end of the address you call."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "name": {},
                    "status": {},
                    "version": {},
                    "public": {},
                    "url": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "deploy_function",
        "x-oneend-max-body-bytes": 4194304,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "source": {
                    "type": "string",
                    "description": "The whole function code (up to 8MB). With files, it is saved as the entry file. Leave it out when files holds the entry."
                  },
                  "public": {
                    "type": "boolean",
                    "description": "Left out, the current value is kept; a new function is private."
                  },
                  "package_json": {
                    "type": "string",
                    "description": "The whole package.json (optional). With it, packages are installed and everything is bundled into one file."
                  },
                  "package_lock": {
                    "type": "string",
                    "description": "package-lock.json (optional). With it, npm ci installs exactly those versions."
                  },
                  "dependencies": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string"
                    },
                    "description": "The npm packages to use and their versions. For example: {\"zod\": \"^3.23.8\"}. Merged into the dependencies of package_json."
                  },
                  "files": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string"
                    },
                    "description": "Other files to put beside source, relative path to content (up to 200, 8MB in total). A folder beside the function folder is written \"../_shared/cors.ts\"."
                  },
                  "entry": {
                    "type": "string",
                    "description": "The file name source is saved as. index.ts by default."
                  }
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "set_function_limits",
        "summary": "Function time limits",
        "description": "Sets, without deploying again, how long one call of a function may take (timeout_seconds) and how long one SQL statement of it may take (sql_timeout_seconds), in seconds. The defaults are 150 seconds (as on Supabase's edge functions) and 8 seconds; this server's maximum is get_function's timeout_cap_seconds. null puts one back to its default; leaving it out keeps the current value. Takes effect from the next call. A call past its limit is cut off with 504.",
        "tags": [
          "functions"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The function name."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "name": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "set_function_limits",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "public": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "remove_function",
        "summary": "Remove a function",
        "description": "Removes a function. Its address returns 404, and scheduled jobs that call it fail. It cannot be undone, so use it only when the user clearly asks, and put the function name exactly in confirm.",
        "tags": [
          "functions"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The function name."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "name": {},
                    "removed": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "remove_function",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "confirm": {
                    "type": "string",
                    "description": "The function name. It must be exactly the same as name."
                  }
                },
                "required": [
                  "confirm"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/database": {
      "get": {
        "operationId": "get_database_connection",
        "summary": "Database connection details",
        "description": "Shows the addresses for connecting directly to this project's PostgreSQL: direct (5432, session: migration tools and database clients) and pooler (6543, transaction: serverless). The password is not stored, so it appears as [YOUR-PASSWORD].",
        "tags": [
          "database"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "available": {},
                    "host": {},
                    "database": {},
                    "user": {},
                    "password_set": {},
                    "direct": {},
                    "pooler": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-permissions": [
          "secrets.read (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "get_database_connection"
      }
    },
    "/projects/{ref}/database/password": {
      "post": {
        "operationId": "reset_database_password",
        "summary": "New database password",
        "description": "Creates a new password for direct connections and returns it once. Anything connecting with the old password is refused from its next connection: servers, jobs and tools connected with it now break when they reconnect, so put the project name (name from list_projects) exactly in confirm.This user bypasses row level security, so keep it on servers only. With keep_for_deploys: true the password is also kept sealed, and production servers, middleware and functions get DATABASE_URL, POSTGRES_URL and DIRECT_URL at runtime (never builds). Deployed code can then read every row, like the secret key, so turn it on only when the user wants it. A reset without it stops the handover. Use this only when the user asks. Only owners and admins can do this.",
        "tags": [
          "database"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "reset_database_password",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "keep_for_deploys": {
                    "type": "boolean",
                    "description": "true: hand it to production deploys as DATABASE_URL (kept sealed). Absent or false: not kept, and any handover stops."
                  },
                  "confirm": {
                    "type": "string",
                    "description": "The project name. It must be exactly the same as name in list_projects."
                  }
                },
                "required": [
                  "confirm"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/backups": {
      "get": {
        "operationId": "list_backups",
        "summary": "Backups",
        "description": "Shows the project backups (automatic every night between 03:00 and 05:00 in the local time of the project region, made by hand, and made just before a restore) and the restore history. retention_days is how long they are kept.",
        "tags": [
          "backups"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "retention_days": {},
                    "point_in_time": {},
                    "backups": {},
                    "restores": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_backups"
      },
      "post": {
        "operationId": "create_backup",
        "summary": "Back up now",
        "description": "Backs up the tables, users and files now. Make one before a big change (a migration, a large delete). Kept for 7 days.",
        "tags": [
          "backups"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "id": {},
                    "status": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "create_backup"
      }
    },
    "/projects/{ref}/backups/{backup_id}/restore": {
      "post": {
        "operationId": "post_projects_ref_backups_backup_id_restore",
        "summary": "Restore a backup",
        "description": "Returns the project's tables, users and files to when the backup was made. Give at (an ISO time) instead of backup_id to return to that moment, to the second (Pro and above, within list_backups' point_in_time range); files are then returned to what the rows at that moment point to (including ones deleted in the last 14 days) only on servers that use a file bucket, and otherwise left as they are now. Every change after that point is lost, so use this only when the user clearly asks. The state just before the restore is backed up first, so you can restore again with undo_backup_id. Only owners and admins can do this.",
        "tags": [
          "backups"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "backup_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The id from list_backups."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "restore_backup"
      }
    },
    "/projects/{ref}/backups/restore-to-time": {
      "post": {
        "operationId": "post_projects_ref_backups_restore_to_time",
        "summary": "Restore a backup",
        "description": "Returns the project's tables, users and files to when the backup was made. Give at (an ISO time) instead of backup_id to return to that moment, to the second (Pro and above, within list_backups' point_in_time range); files are then returned to what the rows at that moment point to (including ones deleted in the last 14 days) only on servers that use a file bucket, and otherwise left as they are now. Every change after that point is lost, so use this only when the user clearly asks. The state just before the restore is backed up first, so you can restore again with undo_backup_id. Only owners and admins can do this.",
        "tags": [
          "backups"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "restore_backup",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "at": {
                    "type": "string",
                    "description": "For example: 2026-10-01T14:59:00+09:00"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/webhooks": {
      "get": {
        "operationId": "list_db_webhooks",
        "summary": "Database webhooks",
        "description": "Shows the webhooks that report table changes and their recent deliveries. attached false means the table was dropped and the webhook stopped. The signing key (signing_secret) is shown once, when the webhook is created (create_db_webhook); the list carries only signing_secret_set and its last four characters (signing_secret_last4).",
        "tags": [
          "webhooks"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "webhooks": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_db_webhooks"
      },
      "post": {
        "operationId": "create_db_webhook",
        "summary": "Create a database webhook",
        "description": "Sends a POST when rows are added to, changed in or deleted from a table. Only for committed changes, within a few seconds. With kind url, target is a public https address (no private or internal addresses, redirects are not followed); with function, it is the name of a function in this project. Body: { type: \"INSERT\"|\"UPDATE\"|\"DELETE\", table, schema: \"public\", record, old_record, hook, delivery, occurred_at }. Verify it with the header x-blackwall-signature: t=<seconds>,v1=<HMAC-SHA256(signing_secret, \"<t>.<body>\") in hex>. signing_secret is in this answer only and cannot be read again, so save it on the receiving side right away. On failure (a response other than 2xx, or more than 10 seconds), it sends again after 10 seconds, 1 minute, 5 minutes and 30 minutes, and gives up on the fifth try.",
        "tags": [
          "webhooks"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "webhook": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          },
          "500": {
            "$ref": "#/components/responses/E500"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "create_db_webhook",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "A name to recognise the webhook by."
                  },
                  "table": {
                    "type": "string",
                    "description": "A table name from list_tables."
                  },
                  "events": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "insert",
                        "update",
                        "delete"
                      ]
                    },
                    "description": "Which changes to send: insert, update, delete."
                  },
                  "kind": {
                    "type": "string",
                    "enum": [
                      "url",
                      "function"
                    ],
                    "description": "url to POST to an address, function to call a function in this project."
                  },
                  "target": {
                    "type": "string",
                    "description": "The https address, or the function name."
                  }
                },
                "required": [
                  "name",
                  "table",
                  "events",
                  "kind",
                  "target"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/webhooks/{webhook}": {
      "patch": {
        "operationId": "set_db_webhook_enabled",
        "summary": "Turn a database webhook on or off",
        "description": "Turns a webhook off or on. Changes made while it is off are never sent. webhook is the id or the name.",
        "tags": [
          "webhooks"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "webhook",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The webhook id or name."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "id": {},
                    "enabled": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "set_db_webhook_enabled",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean",
                    "description": "true to turn it on, false to turn it off."
                  }
                },
                "required": [
                  "enabled"
                ]
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "remove_db_webhook",
        "summary": "Remove a database webhook",
        "description": "Removes a webhook, its delivery history and any changes not sent yet.",
        "tags": [
          "webhooks"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "webhook",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The webhook id or name."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "id": {},
                    "removed": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "remove_db_webhook"
      }
    },
    "/projects/{ref}/webhooks/{webhook}/deliveries": {
      "get": {
        "operationId": "list_db_webhook_deliveries",
        "summary": "Database webhook deliveries",
        "description": "Shows a webhook's recent deliveries with the response status and the reason for any failure, newest first. Kept for 7 days.",
        "tags": [
          "webhooks"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "webhook",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The webhook id or name."
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number",
              "description": "How many deliveries to show."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "id": {},
                    "deliveries": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_db_webhook_deliveries"
      }
    },
    "/projects/{ref}/jobs": {
      "get": {
        "operationId": "list_jobs",
        "summary": "Scheduled jobs",
        "description": "Shows the scheduled jobs (cron) with their schedule, next run and last result. Jobs made with cron.schedule in the project's SQL have source sql. limit is the plan's number of jobs. All times are UTC.",
        "tags": [
          "jobs"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "timezone": {},
                    "limit": {},
                    "used": {},
                    "jobs": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_jobs"
      }
    },
    "/projects/{ref}/jobs/{job}": {
      "put": {
        "operationId": "save_job",
        "summary": "Create or change a scheduled job",
        "description": "Calls a function or runs one SQL statement on a schedule. A job with the same name is changed. schedule is five-field cron (minute hour day month weekday) in UTC. Korea is UTC+9, so midnight in Korea is \"0 15 * * *\". With kind function, target is the name of a deployed function (called with a POST whose body is {}); with sql, target is SQL run as the service role. External URLs cannot be called. Create a function, or use net.http_post from SQL. SQL has to finish within timeout_seconds (120 by default); when the SQL raises its own statement_timeout it is given that long. Either way, at most the plan's maximum (Free 300 seconds, Pro and Enterprise 3600). Jobs made with cron.schedule in SQL are listed too, with source sql; change them in SQL (cron.alter_job, cron.unschedule) or with set_job_enabled and remove_job. Each plan has a number of jobs per project (limit in list_jobs).",
        "tags": [
          "jobs"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "job",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The job name. Saving a name that exists changes that job."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "timezone": {},
                    "job": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "save_job",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "schedule": {
                    "type": "string",
                    "description": "For example: \"*/5 * * * *\" (every 5 minutes), \"0 15 * * *\" (midnight in Korea)."
                  },
                  "kind": {
                    "type": "string",
                    "enum": [
                      "function",
                      "sql"
                    ],
                    "description": "function to call a deployed function, sql to run SQL."
                  },
                  "target": {
                    "type": "string",
                    "description": "The function name, or the SQL to run."
                  },
                  "enabled": {
                    "type": "boolean",
                    "description": "Whether the job runs. On by default."
                  },
                  "timeout_seconds": {
                    "type": "number",
                    "description": "How long a SQL job may run, in seconds. 120 by default; at most the plan's maximum (Free 300, Pro and Enterprise 3600)."
                  }
                },
                "required": [
                  "schedule",
                  "kind",
                  "target"
                ]
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "set_job_enabled",
        "summary": "Turn a scheduled job on or off",
        "description": "Turns a scheduled job off or back on. When turned back on it does not catch up on missed runs; it runs from the next scheduled time. job is the id or the name.",
        "tags": [
          "jobs"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "job",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The job id or name."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "id": {},
                    "enabled": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "set_job_enabled",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean",
                    "description": "true to turn it on, false to turn it off."
                  }
                },
                "required": [
                  "enabled"
                ]
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "remove_job",
        "summary": "Remove a scheduled job",
        "description": "Removes a scheduled job and its run history.",
        "tags": [
          "jobs"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "job",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The job id or name."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "id": {},
                    "removed": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "remove_job"
      }
    },
    "/projects/{ref}/schemas": {
      "get": {
        "operationId": "list_schemas",
        "summary": "Project schemas",
        "description": "The schemas the project made with SQL besides public (create schema blackquant), and whether the data API exposes each (exposed). In the database the name is app_<ref>_<name>, but SQL and clients use the name as written.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "always_exposed": {},
                    "schemas": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_schemas"
      }
    },
    "/projects/{ref}/schemas/exposed": {
      "put": {
        "operationId": "set_exposed_schemas",
        "summary": "Set exposed schemas",
        "description": "Sets, as a whole list, the schemas the data API (/rest/v1) answers for besides public (Supabase's Exposed schemas). Use an exposed schema with the Accept-Profile / Content-Profile headers, supabase-js db: { schema } or .schema(). Row level security and the anon, authenticated and service_role privileges apply exactly as in public. An empty list exposes only public. Takes effect within 30 seconds. Only owners and admins can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "exposed": {},
                    "schemas": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "set_exposed_schemas",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "exposed": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "The schema names to expose (name from list_schemas). public is always exposed."
                  }
                },
                "required": [
                  "exposed"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/data-api": {
      "get": {
        "operationId": "get_data_api_settings",
        "summary": "Data API settings",
        "description": "Whether the data API (/rest/v1) is on, the most rows one read returns (max_rows, null for no cap), the exposed schemas and the search path. search_path_choices are the schemas the search path can take: public, the schemas the project made with create schema, and extensions.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "enabled": {},
                    "max_rows": {},
                    "exposed_schemas": {},
                    "search_path": {},
                    "search_path_choices": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_data_api_settings"
      },
      "patch": {
        "operationId": "set_data_api_settings",
        "summary": "Change the Data API settings",
        "description": "Turns the data API (/rest/v1) on or off and sets the row cap and the search path. Only what is given changes. A schema on the search path comes after the one asked for, so functions and views find its tables and functions without the schema name. Takes effect within 30 seconds. Only owners and admins can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "set_data_api_settings",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean",
                    "description": "false makes every /rest/v1 request answer 404."
                  },
                  "max_rows": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "minimum": 1,
                    "maximum": 1000000,
                    "description": "The most rows one read returns. null for no cap."
                  },
                  "search_path": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "maxItems": 20,
                    "description": "The schemas to put on the search path (name from search_path_choices in get_data_api_settings). An empty list puts none."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/jobs/{job}/run": {
      "post": {
        "operationId": "run_job",
        "summary": "Run a scheduled job now",
        "description": "Runs the job once within a minute, without waiting for its schedule. See the result with list_job_runs.",
        "tags": [
          "jobs"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "job",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The job id or name."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "id": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "run_job"
      }
    },
    "/projects/{ref}/jobs/{job}/runs": {
      "get": {
        "operationId": "list_job_runs",
        "summary": "Scheduled job runs",
        "description": "Shows a job's recent runs and their results, newest first, with the error when one failed.",
        "tags": [
          "jobs"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "job",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The job id or name."
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number",
              "description": "How many runs to show."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "id": {},
                    "runs": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_job_runs"
      }
    },
    "/projects/{ref}/env": {
      "get": {
        "operationId": "list_env_vars",
        "summary": "Environment variables",
        "description": "The environment variables a deployed app gets when it is built and run. The same name can exist separately for production and preview. A sensitive value is not returned; only its last four characters come as value_hint. readable false means the value cannot be opened and is left out of builds, so save it again. automatic lists the automatic variables that are set without being saved: SUPABASE_URL, NEXT_PUBLIC_SUPABASE_URL, SUPABASE_ANON_KEY, NEXT_PUBLIC_SUPABASE_ANON_KEY, NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY and SUPABASE_SERVICE_ROLE_KEY, the names an app moved from Supabase already reads. available_in says where each is available: the public ones in build and runtime (build, runtime), SUPABASE_SERVICE_ROLE_KEY in runtime only (runtime: servers, middleware, functions), never in builds. A variable saved under the same name comes first, and a saved value goes to builds too (overridden_in).",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "automatic": {},
                    "variables": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-permissions": [
          "secrets.read (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "list_env_vars"
      },
      "post": {
        "operationId": "set_env_vars",
        "summary": "Save environment variables",
        "description": "Saves one or more environment variables. Give them one by one in variables, or the whole content of a .env file in dotenv. A name that exists is overwritten. If any one is invalid, nothing is saved, except that a dotenv line with a name the platform sets is skipped and listed in skipped. PORT, HOST, HOSTNAME, HOME and names starting with BLACKWALL_ are used by the platform and cannot be set. Builds get CI=1 unless you set CI yourself (CI=false, for example). Changed values are used from the next deployment. Without sensitive, a name that looks like a secret (API_KEY, STRIPE_SECRET, DATABASE_URL and the like) is saved as sensitive and cannot be read back (sensitive_keys). Only owners and admins can change production values.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "set_env_vars",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "variables": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "key": {
                          "type": "string"
                        },
                        "value": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "key",
                        "value"
                      ],
                      "additionalProperties": false
                    },
                    "description": "A list of { key, value }."
                  },
                  "dotenv": {
                    "type": "string",
                    "description": "The content of a .env file. Comments and blank lines are skipped."
                  },
                  "targets": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "production",
                        "preview",
                        "development"
                      ]
                    },
                    "minItems": 1,
                    "description": "preview means the deployments of every branch that is not the production branch."
                  },
                  "sensitive": {
                    "type": "boolean",
                    "description": "true: the value cannot be read again after it is saved. Not given: only a variable whose name contains SECRET, TOKEN, PASSWORD, PRIVATE, DSN, DATABASE_URL or KEY_, or ends in _KEY, is saved as sensitive. false: every value stays readable."
                  },
                  "app": {
                    "type": "string",
                    "description": "The app name (name from list_apps) to save them for that app only, over a project variable of the same name. Empty means every app of the project."
                  },
                  "branch": {
                    "type": "string",
                    "maxLength": 200,
                    "description": "A git branch name, to save them for that branch's previews only. targets must be preview alone. With app, they go to that app on that branch only. Empty means every preview."
                  }
                },
                "required": [
                  "targets"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/env/{target}/{key}": {
      "delete": {
        "operationId": "remove_env_var",
        "summary": "Remove an environment variable",
        "description": "Removes one environment variable from either production or preview. If the value was sensitive, it cannot be recovered.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "target",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "production",
                "preview",
                "development"
              ],
              "description": "production or preview."
            }
          },
          {
            "name": "key",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The variable name."
            }
          },
          {
            "name": "app",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "The app name, for a variable saved for one app only. Empty means the project's variable."
            }
          },
          {
            "name": "branch",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200,
              "description": "The git branch, for a variable saved for one branch's previews only (branch in list_env_vars)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "key": {},
                    "target": {},
                    "app": {},
                    "branch": {},
                    "removed": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "remove_env_var"
      }
    },
    "/projects/{ref}/auth/providers": {
      "get": {
        "operationId": "list_auth_providers",
        "summary": "Social sign-in settings",
        "description": "Shows which accounts people can use to sign in to this project's service. Every provider the platform supports is returned, so ones not set up yet show configured: false. Providers you registered yourself (custom:<name>) follow, with a custom entry (addresses, scopes, answer field mapping). callback_url is the address to paste as it is into the provider's console.",
        "tags": [
          "auth"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "anonymous_sign_in": {},
                    "providers": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_auth_providers"
      }
    },
    "/projects/{ref}/auth/providers/{provider}": {
      "put": {
        "operationId": "set_auth_provider",
        "summary": "Turn on social sign-in",
        "description": "Saves and turns on one provider's client ID and secret. The secret is sealed and cannot be read back; only its last four characters can be checked. First create an app in the provider's console and register the callback_url from list_auth_providers as its redirect address. To change only the ID of a provider already saved, leave client_secret as an empty string. As on Supabase, a provider of custom:<name> registers an OAuth 2.0 or OpenID Connect provider the platform does not list (for example custom:kakao-xts). It then needs issuer (for OpenID Connect this alone fills in the addresses) or authorize_url and token_url (and userinfo_url), and may take scopes and claims (which field of the answer is id, email, email_verified, name, avatar and phone, as dotted paths). Your app signs in with signInWithOAuth({ provider: \"custom:<name>\" }), and right after sign-in the session carries provider_token, once.",
        "tags": [
          "auth"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "provider",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^(google|kakao|naver|apple|github|gitlab|microsoft|facebook|line|discord|x|bitbucket|figma|linkedin_oidc|notion|twitch|slack_oidc|spotify|zoom|azure|keycloak|workos|twitter|slack|custom:[a-z0-9][a-z0-9_-]{0,39})$",
              "description": "The sign-in provider: google, kakao, naver, apple, github, gitlab, microsoft, facebook, line, discord, x, bitbucket, figma, linkedin_oidc, notion, twitch, slack_oidc, spotify, zoom, azure, keycloak, workos, twitter, slack, or custom:<name> for one you register yourself (lowercase letters, digits, - and _, up to 40)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "provider": {},
                    "enabled": {},
                    "callback_url": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "set_auth_provider",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "client_id": {
                    "type": "string",
                    "description": "The client ID from the provider's console."
                  },
                  "client_secret": {
                    "type": "string",
                    "description": "An empty string keeps the secret already saved. Required for a new provider."
                  },
                  "enabled": {
                    "type": "boolean",
                    "description": "On by default."
                  }
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "set_auth_provider_enabled",
        "summary": "Turn social sign-in off and on",
        "description": "Turns a provider off or on and keeps its saved credentials. Use it while finding out why a provider misbehaves; turning it back on needs no new secret.",
        "tags": [
          "auth"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "provider",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^(google|kakao|naver|apple|github|gitlab|microsoft|facebook|line|discord|x|bitbucket|figma|linkedin_oidc|notion|twitch|slack_oidc|spotify|zoom|azure|keycloak|workos|twitter|slack|custom:[a-z0-9][a-z0-9_-]{0,39})$",
              "description": "The sign-in provider: google, kakao, naver, apple, github, gitlab, microsoft, facebook, line, discord, x, bitbucket, figma, linkedin_oidc, notion, twitch, slack_oidc, spotify, zoom, azure, keycloak, workos, twitter, slack, or custom:<name> for one you register yourself (lowercase letters, digits, - and _, up to 40)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "provider": {},
                    "enabled": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "set_auth_provider_enabled",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean",
                    "description": "true to turn it on, false to turn it off."
                  }
                },
                "required": [
                  "enabled"
                ]
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "remove_auth_provider",
        "summary": "Remove social sign-in",
        "description": "Removes a provider's settings along with its credentials. To turn it off for a while, use set_auth_provider_enabled. After removing it this way, you have to get the secret again.",
        "tags": [
          "auth"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "provider",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^(google|kakao|naver|apple|github|gitlab|microsoft|facebook|line|discord|x|bitbucket|figma|linkedin_oidc|notion|twitch|slack_oidc|spotify|zoom|azure|keycloak|workos|twitter|slack|custom:[a-z0-9][a-z0-9_-]{0,39})$",
              "description": "The sign-in provider: google, kakao, naver, apple, github, gitlab, microsoft, facebook, line, discord, x, bitbucket, figma, linkedin_oidc, notion, twitch, slack_oidc, spotify, zoom, azure, keycloak, workos, twitter, slack, or custom:<name> for one you register yourself (lowercase letters, digits, - and _, up to 40)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "provider": {},
                    "removed": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "remove_auth_provider"
      }
    },
    "/projects/{ref}/auth/redirect-urls": {
      "get": {
        "operationId": "list_redirect_urls",
        "summary": "Addresses to return to after sign-in",
        "description": "The addresses a person can be sent back to after signing in. Nobody is sent to an address not listed here. If sign-in works but goes nowhere, look here first.",
        "tags": [
          "auth"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "urls": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_redirect_urls"
      },
      "post": {
        "operationId": "add_redirect_url",
        "summary": "Add an address to return to",
        "description": "Adds one address to the allow list. Scheme, host and port must all match and the path is not checked, so adding https://app.example.com/callback stores https://app.example.com. A mobile app’s own scheme is accepted too (co.example.app://callback, stored as co.example.app://callback): reverse-DNS, so it has a dot. The response holds the list as actually stored.",
        "tags": [
          "auth"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "urls": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "add_redirect_url",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "description": "The address, for example https://app.example.com."
                  }
                },
                "required": [
                  "url"
                ]
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "remove_redirect_url",
        "summary": "Remove an address to return to",
        "description": "Takes one address off the allow list. Give it exactly as list_redirect_urls returned it.",
        "tags": [
          "auth"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "urls": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "remove_redirect_url",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "description": "The address, as list_redirect_urls returned it."
                  }
                },
                "required": [
                  "url"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/auth/sms": {
      "get": {
        "operationId": "get_sms_settings",
        "summary": "SMS sign-in settings",
        "description": "Shows the SMS account used for phone sign-in (signInWithOtp({ phone })): the provider (platform, solapi, nhn, aligo, twilio), the sender number, the country codes it may send to, the code length and lifetime, and the hourly limit. Credentials show only their last four characters. platform_available has to be true to choose the platform account (₩100 a message, Korea only).",
        "tags": [
          "auth"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "configured": {},
                    "provider": {},
                    "enabled": {},
                    "sender": {},
                    "allowed_countries": {},
                    "otp_length": {},
                    "otp_ttl_seconds": {},
                    "hourly_limit": {},
                    "template": {},
                    "key_hint": {},
                    "secret_hint": {},
                    "account_hint": {},
                    "credentials_readable": {},
                    "platform_available": {},
                    "providers": {},
                    "updated_at": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_sms_settings"
      },
      "put": {
        "operationId": "set_sms_settings",
        "summary": "Set up SMS sign-in",
        "description": "Saves the SMS account and turns it on. Your own provider needs key, secret and account (they differ by provider: Solapi takes API Key and API Secret, NHN Cloud App Key and Secret Key, Aligo API Key and User ID as account, Twilio and Twilio Verify Account SID as account and Auth Token as secret, MessageBird Access Key as key, Textlocal API Key as key, Vonage API Key as key and API Secret as secret) and a sender registered with it (MessageBird, Textlocal and Vonage also take an alphanumeric sender ID of up to 11 characters; Twilio Verify takes its Verify Service SID, starting VA). Phone confirmations, test numbers and the rest are SMS_* keys of update_auth_config. Credentials left empty keep the stored ones. allowed_countries is only 82 (Korea) by default; adding countries you do not serve exposes you to fraud that makes you text premium-rate numbers abroad.",
        "tags": [
          "auth"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "set_sms_settings",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "provider": {
                    "type": "string",
                    "enum": [
                      "platform",
                      "solapi",
                      "nhn",
                      "aligo",
                      "twilio",
                      "messagebird",
                      "textlocal",
                      "vonage",
                      "twilio_verify"
                    ],
                    "description": "platform (the platform account, paid plans only), solapi, nhn, aligo, twilio, messagebird, textlocal, vonage or twilio_verify."
                  },
                  "key": {
                    "type": "string",
                    "description": "Solapi API Key, NHN Cloud App Key or Aligo API Key. Empty keeps the stored one."
                  },
                  "secret": {
                    "type": "string",
                    "description": "Solapi API Secret, NHN Cloud Secret Key or Twilio Auth Token. Empty keeps the stored one."
                  },
                  "account": {
                    "type": "string",
                    "description": "Aligo User ID or Twilio Account SID. Empty keeps the stored one."
                  },
                  "sender": {
                    "type": "string",
                    "description": "The sender number, e.g. 01012345678. For Twilio, a +1 number or a Messaging Service SID starting with MG."
                  },
                  "allowed_countries": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Country calling codes it may send to, e.g. [\"82\"]."
                  },
                  "otp_length": {
                    "type": "integer",
                    "minimum": 6,
                    "maximum": 10,
                    "description": "Digits in a code, 6 to 10. Default 6."
                  },
                  "otp_ttl_seconds": {
                    "type": "integer",
                    "minimum": 60,
                    "maximum": 3600,
                    "description": "How long a code is valid, 60 to 3600 seconds. Default 300."
                  },
                  "hourly_limit": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 100000,
                    "description": "Most messages the whole project may send in an hour. Default 200."
                  },
                  "template": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "The message, containing {{code}}. null for the default wording."
                  },
                  "enabled": {
                    "type": "boolean",
                    "description": "On by default."
                  }
                },
                "required": [
                  "provider"
                ]
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "remove_sms_settings",
        "summary": "Remove SMS sign-in",
        "description": "Removes the SMS account settings along with the credentials. Phone sign-in is then refused with phone_provider_disabled. To turn it off for a while, call set_sms_settings with enabled: false.",
        "tags": [
          "auth"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "removed": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "remove_sms_settings"
      }
    },
    "/projects/{ref}/auth/smtp": {
      "get": {
        "operationId": "get_smtp_settings",
        "summary": "SMTP settings",
        "description": "Shows the SMTP server and sender this project's auth emails (sign-up confirmation, password reset, sign-in link, email change, invitation) go out through: the same fields as Supabase's SMTP Settings. The password is never shown; password_hint has its last four characters (when it has at least 8). A last_error means that server refused and the email went out from the platform's address instead. configured false means the platform's address is used.",
        "tags": [
          "auth"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "configured": {},
                    "enabled": {},
                    "sender_email": {},
                    "sender_name": {},
                    "host": {},
                    "port": {},
                    "username": {},
                    "password_hint": {},
                    "password_readable": {},
                    "minimum_interval_seconds": {},
                    "rate_limit_per_hour": {},
                    "last_sent_at": {},
                    "last_error": {},
                    "last_error_at": {},
                    "updated_at": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_smtp_settings"
      },
      "put": {
        "operationId": "set_smtp_settings",
        "summary": "Set SMTP settings",
        "description": "Sends auth emails through this project's SMTP server, with the sender name and address you choose. The first time it needs sender_email, host, username and password; after that, only what changes (an empty password keeps the stored one). The server has to be on a public address and use TLS (from the start on 465, STARTTLS otherwise). If it refuses, the email goes out from the platform's address and the reason is kept in last_error. Check it with test_smtp_settings after saving.",
        "tags": [
          "auth"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "set_smtp_settings",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "sender_email": {
                    "type": "string",
                    "description": "Sender email, e.g. no-reply@shop.example."
                  },
                  "sender_name": {
                    "type": "string",
                    "description": "Sender name, e.g. My Shop."
                  },
                  "host": {
                    "type": "string",
                    "description": "The SMTP host, e.g. smtp.sendgrid.net."
                  },
                  "port": {
                    "type": "integer",
                    "enum": [
                      25,
                      465,
                      587,
                      2465,
                      2525
                    ],
                    "description": "Port: 25, 465, 587, 2465 or 2525. Default 587."
                  },
                  "username": {
                    "type": "string",
                    "description": "The SMTP username."
                  },
                  "password": {
                    "type": "string",
                    "description": "The SMTP password. Empty keeps the stored one."
                  },
                  "minimum_interval_seconds": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 3600,
                    "description": "Minimum seconds between two emails to the same address. Default 60."
                  },
                  "rate_limit_per_hour": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 10000,
                    "description": "Emails the whole project may send in an hour. Default 100. Past it, requests are refused with over_email_send_rate_limit (429)."
                  },
                  "enabled": {
                    "type": "boolean",
                    "description": "false keeps the settings and sends from the platform's address."
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "remove_smtp_settings",
        "summary": "Remove SMTP settings",
        "description": "Removes the SMTP settings along with the password. Auth emails then go out from the platform's address. To pause them, call set_smtp_settings with enabled: false.",
        "tags": [
          "auth"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "removed": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "remove_smtp_settings"
      }
    },
    "/projects/{ref}/auth/smtp/test": {
      "post": {
        "operationId": "test_smtp_settings",
        "summary": "Send an SMTP test email",
        "description": "Sends one test email through the saved SMTP server. It does not fall back to the platform, so a failure gives the server's own reason. Without to, it goes to the caller's address.",
        "tags": [
          "auth"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "sent": {},
                    "to": {},
                    "sender_email": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "test_smtp_settings",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "to": {
                    "type": "string",
                    "description": "The address to send to. Leave it out for your own."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/auth/templates": {
      "get": {
        "operationId": "get_projects_ref_auth_templates",
        "summary": "Email templates",
        "description": "The subject and HTML body of the six auth emails (confirmation, invite, magic_link, recovery, email_change, reauthentication). A type with custom false uses the default wording, in Korean, English or Japanese to match the request. Give type to see just one. The variables are the same as Supabase: {{ .ConfirmationURL }}, {{ .Token }}, {{ .TokenHash }}, {{ .SiteURL }}, {{ .Email }}, {{ .NewEmail }}, {{ .RedirectTo }}, {{ .Data.<key> }}.",
        "tags": [
          "auth"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "variables": {},
                    "templates": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_email_templates"
      }
    },
    "/projects/{ref}/auth/templates/{type}": {
      "get": {
        "operationId": "get_projects_ref_auth_templates_type",
        "summary": "Email templates",
        "description": "The subject and HTML body of the six auth emails (confirmation, invite, magic_link, recovery, email_change, reauthentication). A type with custom false uses the default wording, in Korean, English or Japanese to match the request. Give type to see just one. The variables are the same as Supabase: {{ .ConfirmationURL }}, {{ .Token }}, {{ .TokenHash }}, {{ .SiteURL }}, {{ .Email }}, {{ .NewEmail }}, {{ .RedirectTo }}, {{ .Data.<key> }}.",
        "tags": [
          "auth"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "type",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "confirmation",
                "invite",
                "magic_link",
                "recovery",
                "email_change",
                "reauthentication",
                "password_changed",
                "email_changed",
                "mfa_enrolled",
                "mfa_removed",
                "identity_linked",
                "identity_unlinked"
              ],
              "description": "confirmation, invite, magic_link, recovery, email_change or reauthentication."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "variables": {},
                    "templates": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_email_templates"
      },
      "put": {
        "operationId": "set_email_template",
        "summary": "Save an email template",
        "description": "Sets the subject and HTML body of one type. Templates copied from Supabase work as they are. Values are HTML-escaped, and the subject has to be one line. Other syntax such as {{ if }} is refused. reauthentication is stored but not sent yet (reauthenticate is not supported). Check it with preview_email_template before saving.",
        "tags": [
          "auth"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "type",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "confirmation",
                "invite",
                "magic_link",
                "recovery",
                "email_change",
                "reauthentication",
                "password_changed",
                "email_changed",
                "mfa_enrolled",
                "mfa_removed",
                "identity_linked",
                "identity_unlinked"
              ],
              "description": "confirmation, invite, magic_link, recovery, email_change or reauthentication."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "set_email_template",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "subject": {
                    "type": "string",
                    "maxLength": 200,
                    "description": "The subject line, up to 200 characters."
                  },
                  "body": {
                    "type": "string",
                    "maxLength": 50000,
                    "description": "The HTML body, e.g. <a href=\"{{ .ConfirmationURL }}\">Confirm</a>"
                  }
                },
                "required": [
                  "subject",
                  "body"
                ]
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "remove_email_template",
        "summary": "Restore an email template",
        "description": "Removes the template of one type, which goes back to the default wording (Korean, English and Japanese).",
        "tags": [
          "auth"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "type",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "confirmation",
                "invite",
                "magic_link",
                "recovery",
                "email_change",
                "reauthentication",
                "password_changed",
                "email_changed",
                "mfa_enrolled",
                "mfa_removed",
                "identity_linked",
                "identity_unlinked"
              ],
              "description": "confirmation, invite, magic_link, recovery, email_change or reauthentication."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "type": {},
                    "removed": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "remove_email_template"
      }
    },
    "/projects/{ref}/auth/templates/{type}/preview": {
      "post": {
        "operationId": "preview_email_template",
        "summary": "Preview an email template",
        "description": "Returns how the email looks with sample values (subject, HTML and text). With subject and body it shows those without saving; without them, the saved template or the default wording.",
        "tags": [
          "auth"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "type",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "confirmation",
                "invite",
                "magic_link",
                "recovery",
                "email_change",
                "reauthentication",
                "password_changed",
                "email_changed",
                "mfa_enrolled",
                "mfa_removed",
                "identity_linked",
                "identity_unlinked"
              ],
              "description": "confirmation, invite, magic_link, recovery, email_change or reauthentication."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "type": {},
                    "custom": {},
                    "subject": {},
                    "html": {},
                    "text": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-mcp-tool": "preview_email_template",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "subject": {
                    "type": "string",
                    "description": "A subject to try without saving."
                  },
                  "body": {
                    "type": "string",
                    "description": "A body to try without saving."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/auth/sso": {
      "get": {
        "operationId": "list_sso_providers",
        "summary": "SAML SSO",
        "description": "Shows the SAML IdPs registered for this project with their email domains, and the two addresses to enter in the IdP (acs_url, entity_id). The app signs in with supabase.auth.signInWithSSO({ domain }).",
        "tags": [
          "auth"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "acs_url": {},
                    "entity_id": {},
                    "metadata_url": {},
                    "new_providers_allowed": {},
                    "providers": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_sso_providers"
      }
    },
    "/projects/{ref}/{param0}/{param1}": {
      "post": {
        "operationId": "post_projects_ref_param0_param1",
        "summary": "Add SAML SSO",
        "description": "Registers a SAML IdP from its metadata (an https URL or the XML). The metadata needs an HTTP-Redirect sign-in address and a signing certificate. signInWithSSO with an email domain in domains goes to this IdP. A domain belongs to one IdP only. A new IdP can be added on the Enterprise plan only (new_providers_allowed in list_sso_providers); IdPs already added keep working on any plan.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "param0",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "param1",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {},
                    "entity_id": {},
                    "metadata_url": {},
                    "domains": {},
                    "attribute_mapping": {},
                    "created_at": {},
                    "updated_at": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "add_sso_provider",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "metadata_url": {
                    "type": "string",
                    "description": "An https URL. Give this or metadata_xml."
                  },
                  "metadata_xml": {
                    "type": "string",
                    "description": "The IdP's metadata XML. Give this or metadata_url."
                  },
                  "domains": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Email domains, e.g. [\"example.com\"]."
                  },
                  "attribute_mapping": {
                    "type": "object",
                    "description": "GoTrue form: {\"keys\": {\"email\": {\"name\": \"mail\"}}}."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/{param0}/{param1}/{param2}": {
      "put": {
        "operationId": "put_projects_ref_param0_param1_param2",
        "summary": "Add SAML SSO",
        "description": "Registers a SAML IdP from its metadata (an https URL or the XML). The metadata needs an HTTP-Redirect sign-in address and a signing certificate. signInWithSSO with an email domain in domains goes to this IdP. A domain belongs to one IdP only. A new IdP can be added on the Enterprise plan only (new_providers_allowed in list_sso_providers); IdPs already added keep working on any plan.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "param0",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "param1",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "param2",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {},
                    "entity_id": {},
                    "metadata_url": {},
                    "domains": {},
                    "attribute_mapping": {},
                    "created_at": {},
                    "updated_at": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "add_sso_provider",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "metadata_url": {
                    "type": "string",
                    "description": "An https URL. Give this or metadata_xml."
                  },
                  "metadata_xml": {
                    "type": "string",
                    "description": "The IdP's metadata XML. Give this or metadata_url."
                  },
                  "domains": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Email domains, e.g. [\"example.com\"]."
                  },
                  "attribute_mapping": {
                    "type": "object",
                    "description": "GoTrue form: {\"keys\": {\"email\": {\"name\": \"mail\"}}}."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/auth/sso/{id}": {
      "delete": {
        "operationId": "remove_sso_provider",
        "summary": "Remove SAML SSO",
        "description": "Removes one IdP. Accounts made through it remain, but can no longer sign in through SSO.",
        "tags": [
          "auth"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The id from list_sso_providers."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "id": {},
                    "removed": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "remove_sso_provider"
      }
    },
    "/projects/{ref}/config/auth": {
      "get": {
        "operationId": "get_auth_config",
        "summary": "Show the whole sign-in configuration",
        "description": "Returns this project's whole sign-in configuration under the same keys as Supabase's auth config, in lower case: sign-ups (disable_signup, mailer_autoconfirm, security_manual_linking_enabled, external_anonymous_users_enabled), the email provider and password rules, phone and the SMS provider (sms_*), SAML (saml_*), Web3, and for each social provider external_<provider>_enabled, client_id, secret, url and email_optional, and the custom providers switch. A secret is given as its last four characters, like ••••abcd; handing that back to update_auth_config leaves the stored one alone. callback_url is the address to paste into a provider's console.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_auth_config"
      },
      "patch": {
        "operationId": "update_auth_config",
        "summary": "Change the sign-in configuration",
        "description": "Changes only the keys given (GoTrue's upper-case names work too), checked by the same rules as the console's Sign In / Providers page: a provider switched on needs what it needs (external_google_client_id, a Keycloak realm url), an Apple secret must be an ES256 JWT with more than 7 days left, and an SMS message must contain {{ .Code }}. If any of it is wrong nothing is saved, and each key's reason comes back. Kakao's consent items are external_kakao_scopes (profile_nickname, account_email, gender and so on, separated by commas), the Naver fields to keep are external_naver_scopes, and Google's and GitHub's additional scopes are external_<provider>_additional_scopes. An empty string removes a secret. Only owners, admins and developers can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-mcp-tool": "update_auth_config",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {}
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/config/auth/custom-providers": {
      "get": {
        "operationId": "list_custom_providers",
        "summary": "Custom sign-in providers",
        "description": "Shows the OAuth and OIDC providers the project defined itself (custom:<identifier>), the plan’s limit (max_providers) and the switch (enabled). The app signs in with signInWithOAuth({ provider: \"custom:<identifier>\" }).",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_custom_providers"
      },
      "post": {
        "operationId": "create_custom_provider",
        "summary": "Create a custom sign-in provider",
        "description": "Creates one OAuth or OIDC provider (custom:<identifier>) and turns it on, in the same place set_auth_provider writes. With provider_type oidc the issuer alone is enough: the endpoints and jwks_uri are read from {issuer}/.well-known/openid-configuration, and each id_token's signature, issuer, audience, expiry and nonce are checked against those keys. With oauth2, give the issuer or authorization_url and token_url; endpoints left empty are {issuer}/oauth/authorize, /oauth/token and /oauth/userinfo. claim_map says which field of the answer is id, email, email_verified, name, avatar and phone (dotted paths). PKCE is on by default. Refused past the plan’s limit.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-mcp-tool": "create_custom_provider",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "pkce": {
                    "type": "boolean",
                    "description": "On by default; turn it off only if the provider refuses PKCE."
                  },
                  "pkce_enabled": {
                    "type": "string"
                  },
                  "identifier": {
                    "type": "string",
                    "description": "Lowercase letters, numbers and hyphens. custom: may be given or left off."
                  },
                  "name": {
                    "type": "string",
                    "description": "The display name, under 100 characters."
                  },
                  "label": {
                    "type": "string"
                  },
                  "provider_type": {
                    "type": "string",
                    "enum": [
                      "oidc",
                      "oauth2"
                    ],
                    "description": "oidc (endpoints discovered, id_token verified) or oauth2 (endpoints given, read through claim_map)."
                  },
                  "issuer": {
                    "type": "string",
                    "description": "The provider's base URL."
                  },
                  "discovery_url": {
                    "type": "string",
                    "description": "For oidc, when the discovery document is not at the standard path."
                  },
                  "authorization_url": {
                    "type": "string",
                    "description": "Required for oauth2 without an issuer; for oidc, empty is discovered."
                  },
                  "authorize_url": {
                    "type": "string"
                  },
                  "token_url": {
                    "type": "string",
                    "description": "Required for oauth2 without an issuer; for oidc, empty is discovered."
                  },
                  "userinfo_url": {
                    "type": "string",
                    "description": "Where the user is read; for oidc, empty is discovered."
                  },
                  "jwks_uri": {
                    "type": "string",
                    "description": "For oidc, to verify ID tokens; empty is discovered."
                  },
                  "client_id": {
                    "type": "string",
                    "description": "The client ID."
                  },
                  "client_secret": {
                    "type": "string",
                    "description": "The client secret."
                  },
                  "scopes": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "For example [\"openid\", \"email\", \"profile\"]."
                  },
                  "email_optional": {
                    "type": "boolean",
                    "description": "Allow users without an email."
                  },
                  "claim_map": {
                    "type": "object",
                    "additionalProperties": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      ]
                    },
                    "description": "Which field of the answer is id, email, email_verified, name, avatar and phone, as dotted paths. Left out: the OpenID standard names."
                  },
                  "claims": {
                    "type": "string"
                  },
                  "token_auth": {
                    "type": "string",
                    "enum": [
                      "body",
                      "basic"
                    ],
                    "description": "Send client_secret in the body (body, the default) or as HTTP Basic (basic)."
                  },
                  "enabled": {
                    "type": "boolean",
                    "description": "On by default."
                  }
                },
                "required": [
                  "identifier",
                  "name",
                  "provider_type",
                  "client_id",
                  "client_secret"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/config/auth/custom-providers/{identifier}": {
      "put": {
        "operationId": "update_custom_provider",
        "summary": "Change a custom sign-in provider",
        "description": "Changes one custom provider. The identifier cannot change. An empty client_secret keeps the stored one.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "identifier",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The identifier from list_custom_providers."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-mcp-tool": "update_custom_provider",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "pkce": {
                    "type": "boolean",
                    "description": "On by default; turn it off only if the provider refuses PKCE."
                  },
                  "pkce_enabled": {
                    "type": "string"
                  },
                  "identifier": {
                    "type": "string",
                    "description": "The identifier from list_custom_providers."
                  },
                  "name": {
                    "type": "string",
                    "description": "The display name, under 100 characters."
                  },
                  "label": {
                    "type": "string"
                  },
                  "provider_type": {
                    "type": "string",
                    "enum": [
                      "oidc",
                      "oauth2"
                    ],
                    "description": "oidc (endpoints discovered, id_token verified) or oauth2 (endpoints given, read through claim_map)."
                  },
                  "issuer": {
                    "type": "string",
                    "description": "The provider's base URL."
                  },
                  "discovery_url": {
                    "type": "string",
                    "description": "For oidc, when the discovery document is not at the standard path."
                  },
                  "authorization_url": {
                    "type": "string",
                    "description": "Required for oauth2 without an issuer; for oidc, empty is discovered."
                  },
                  "authorize_url": {
                    "type": "string"
                  },
                  "token_url": {
                    "type": "string",
                    "description": "Required for oauth2 without an issuer; for oidc, empty is discovered."
                  },
                  "userinfo_url": {
                    "type": "string",
                    "description": "Where the user is read; for oidc, empty is discovered."
                  },
                  "jwks_uri": {
                    "type": "string",
                    "description": "For oidc, to verify ID tokens; empty is discovered."
                  },
                  "client_id": {
                    "type": "string",
                    "description": "The client ID."
                  },
                  "client_secret": {
                    "type": "string",
                    "description": "Empty keeps the stored secret."
                  },
                  "scopes": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "For example [\"openid\", \"email\", \"profile\"]."
                  },
                  "email_optional": {
                    "type": "boolean",
                    "description": "Allow users without an email."
                  },
                  "claim_map": {
                    "type": "object",
                    "additionalProperties": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      ]
                    },
                    "description": "Which field of the answer is id, email, email_verified, name, avatar and phone, as dotted paths. Left out: the OpenID standard names."
                  },
                  "claims": {
                    "type": "string"
                  },
                  "token_auth": {
                    "type": "string",
                    "enum": [
                      "body",
                      "basic"
                    ],
                    "description": "Send client_secret in the body (body, the default) or as HTTP Basic (basic)."
                  },
                  "enabled": {
                    "type": "boolean",
                    "description": "Turn it on or off as it is saved."
                  }
                },
                "required": [
                  "identifier",
                  "name",
                  "provider_type",
                  "client_id"
                ]
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "set_custom_provider_enabled",
        "summary": "Turn a custom sign-in provider off or on",
        "description": "Turns one custom provider off or on. Off, existing sessions stay, but new sign-ins fail until it is turned on again.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "identifier",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The identifier from list_custom_providers."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-mcp-tool": "set_custom_provider_enabled",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean",
                    "description": "true to turn it on, false to turn it off."
                  }
                },
                "required": [
                  "enabled"
                ]
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "remove_custom_provider",
        "summary": "Delete a custom sign-in provider",
        "description": "Deletes one custom provider. It cannot be undone, and users who signed in with it can no longer get in.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "identifier",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The identifier from list_custom_providers."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-mcp-tool": "remove_custom_provider"
      }
    },
    "/projects/{ref}/config/auth/copy-from-import": {
      "post": {
        "operationId": "copy_auth_from_import",
        "summary": "Copy sign-in settings from an import",
        "description": "Copies a Supabase project's sign-in setup into a project here (ref), read with a Supabase account connected in import_sources: each social provider switched on there (client ID, secret and the rest, checked as update_auth_config checks them), the redirect allow list (uri_allow_list, as add_redirect_url adds it) and site_url only when this project's is empty. Secrets never appear in the conversation; the answer says per provider whether it was copied and why not. Sign-in fails until the answer's callback_url is registered in each provider's console. dry_run shows what would be copied and changes nothing. Owners, admins and developers only.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "source_project": {},
                    "dry_run": {},
                    "callback_url": {},
                    "providers": {},
                    "site_url": {},
                    "redirect_urls": {},
                    "console_url": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "copy_auth_from_import",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "providers": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Providers to copy (google, kakao, apple, x...). Empty means every one switched on at Supabase."
                  },
                  "dry_run": {
                    "type": "boolean",
                    "description": "true shows what would be copied without changing anything."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/config/auth/third-party-auth": {
      "get": {
        "operationId": "list_third_party_auth",
        "summary": "Third-party auth",
        "description": "The other identity services whose tokens the Data API takes: Firebase, Clerk, WorkOS, Auth0, Amazon Cognito and OpenID issuers.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_third_party_auth"
      },
      "post": {
        "operationId": "add_third_party_auth",
        "summary": "Add third-party auth",
        "description": "Takes another identity service's JWTs as sign-ins to this project. value depends on type: firebase the project ID, clerk https://clerk.<domain> or https://<name>.clerk.accounts.dev, workos the issuer URL, auth0 the tenant name (the start of <name>.auth0.com), cognito the user pool ID (with region), oidc the issuer URL. For Auth0 and Cognito, giving audiences is recommended.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-mcp-tool": "add_third_party_auth",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": [
                      "firebase",
                      "clerk",
                      "workos",
                      "auth0",
                      "cognito",
                      "oidc"
                    ],
                    "description": "firebase, clerk, workos, auth0, cognito or oidc."
                  },
                  "value": {
                    "type": "string",
                    "description": "What the type takes, as above."
                  },
                  "region": {
                    "type": "string",
                    "description": "Cognito's AWS region, e.g. ap-northeast-2."
                  },
                  "audiences": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Values a token’s aud must contain."
                  },
                  "jwks_url": {
                    "type": "string",
                    "description": "For oidc, a JWKS address to use instead of discovery."
                  }
                },
                "required": [
                  "type",
                  "value"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/config/auth/third-party-auth/{id}": {
      "delete": {
        "operationId": "remove_third_party_auth",
        "summary": "Remove third-party auth",
        "description": "Removes one third-party auth integration. Requests from users signed in with that service are refused with 401 within 30 seconds.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The id from list_third_party_auth."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-mcp-tool": "remove_third_party_auth"
      }
    },
    "/projects/{ref}/auth/anonymous": {
      "put": {
        "operationId": "set_anonymous_sign_in",
        "summary": "Turn anonymous sign-in on or off",
        "description": "Turns on or off anonymous sign-in, which gives a session straight away without an email. The current state is anonymous_sign_in in list_auth_providers.",
        "tags": [
          "auth"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "anonymous_sign_in": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "set_anonymous_sign_in",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean",
                    "description": "true to turn it on, false to turn it off."
                  }
                },
                "required": [
                  "enabled"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/git": {
      "get": {
        "operationId": "list_git_access",
        "summary": "Git connection",
        "description": "The same as \"Git connection\" in the console. Shows the repositories this project deploys (connected: whether a push deploys it), the GitHub accounts linked (github_accounts) how private repositories are fetched (the last four characters of a GitHub or GitLab token, a GitHub App installation), and for each GitHub repository whether it runs its checks on One Server (checks_on_server: available, enabled, state, permission_url, workflows_using). If a private repository build fails at the fetch step, look here first.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "access": {},
                    "repositories": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_git_access"
      }
    },
    "/projects/{ref}/git/tokens/{provider}": {
      "put": {
        "operationId": "set_repo_token",
        "summary": "Save a repository token",
        "description": "Saves an access token used to fetch private repositories (read access is enough). It is sealed and never shown again. For a self-hosted GitLab, put https://gitlab.example.com in gitlab_base. Used from the next build. Only owners and admins can do this.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "provider",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "github",
                "gitlab",
                "bitbucket"
              ],
              "description": "github or gitlab."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "provider": {},
                    "saved": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "set_repo_token",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "token": {
                    "type": "string",
                    "description": "The access token. Read access is enough."
                  },
                  "gitlab_base": {
                    "type": "string",
                    "description": "The address of a self-hosted GitLab. Empty for gitlab.com."
                  }
                },
                "required": [
                  "token"
                ]
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "remove_repo_token",
        "summary": "Remove a repository token",
        "description": "Removes the saved token. A connected GitHub App installation is kept. Only owners and admins can do this.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "provider",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "github",
                "gitlab",
                "bitbucket"
              ],
              "description": "github or gitlab."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "provider": {},
                    "removed": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "remove_repo_token"
      }
    },
    "/projects/{ref}/git/repos": {
      "post": {
        "operationId": "add_repository",
        "summary": "Add a repository",
        "description": "Attaches a repository to this project before its first push. Pushes that come through the GitHub App then come to this project, and create_deploy_hook can build without a push. repo is owner/name for GitHub and group/name for GitLab. Only owners and admins can do this.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "access": {},
                    "repositories": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "add_repository",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "provider": {
                    "type": "string",
                    "enum": [
                      "github",
                      "gitlab",
                      "bitbucket"
                    ],
                    "description": "github or gitlab."
                  },
                  "repo": {
                    "type": "string",
                    "description": "owner/name for GitHub, group/name for GitLab."
                  },
                  "branch": {
                    "type": "string",
                    "description": "The production branch. Empty means main."
                  }
                },
                "required": [
                  "provider",
                  "repo"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/git/github-app": {
      "delete": {
        "operationId": "delete_projects_ref_git_github_app",
        "summary": "Disconnect a GitHub account",
        "description": "Disconnects a GitHub account (a GitHub App installation) from this project: the one named by installation, or every one when it is empty. Saved tokens and the App installation on GitHub are kept. Connecting needs a person to confirm it on GitHub, so it can only be done in the console. Only owners and admins can do this.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "unlinked": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "unlink_github_app"
      }
    },
    "/projects/{ref}/git/github-app/{installation}": {
      "delete": {
        "operationId": "delete_projects_ref_git_github_app_installation",
        "summary": "Disconnect a GitHub account",
        "description": "Disconnects a GitHub account (a GitHub App installation) from this project: the one named by installation, or every one when it is empty. Saved tokens and the App installation on GitHub are kept. Connecting needs a person to confirm it on GitHub, so it can only be done in the console. Only owners and admins can do this.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "installation",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "description": "github_accounts[].installation_id from list_git_access. Empty means all."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "unlinked": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "unlink_github_app"
      }
    },
    "/projects/{ref}/git/importable": {
      "get": {
        "operationId": "list_importable_repositories",
        "summary": "Find repositories to import",
        "description": "The same as the import list under Git connection in the console. Shows up to 50 repositories the GitHub App can see on a linked GitHub account, most recently pushed first. With query it searches all of them, also past 300. If you just added a repository on GitHub, pass refresh: true. With several accounts, choose one with installation (github_accounts in list_git_access). Only owners and admins can see it.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "query",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Part of a repository name. Empty lists the most recently pushed."
            }
          },
          {
            "name": "installation",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Which GitHub account's installation. Empty means the default account."
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "Ask GitHub again, past its one-minute cache."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "github_account": {},
                    "installation_id": {},
                    "other_accounts": {},
                    "repositories": {},
                    "shown": {},
                    "matched": {},
                    "total": {},
                    "searched": {},
                    "add_repositories_url": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "list_importable_repositories"
      }
    },
    "/projects/{ref}/git/import": {
      "post": {
        "operationId": "import_repository",
        "summary": "Import a repository",
        "description": "The same as [Connect and deploy] in the console. Connects a repository the GitHub App can see to this project and starts the first deployment from the newest commit of its production branch. An empty branch means the repository's default branch. Build settings (framework and the rest) and environment variables (a .env text in dotenv) are saved before the first build. Importing a disconnected repository again connects it again with its settings. Only owners and admins can do this.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "app": {},
                    "repo": {},
                    "branch": {},
                    "github_account": {},
                    "deployment": {},
                    "status": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "import_repository",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "repo": {
                    "type": "string",
                    "description": "owner/name, as list_importable_repositories gives it."
                  },
                  "branch": {
                    "type": "string",
                    "description": "The production branch. Empty means the repository's default branch."
                  },
                  "root_directory": {
                    "type": "string",
                    "description": "The app folder of a monorepo (for example apps/web). Empty means the top of the repository. Another folder of a repository already connected adds a new app."
                  },
                  "installation": {
                    "type": "integer",
                    "description": "Which GitHub account's installation fetches it. Empty means the account that owns the repository."
                  },
                  "dotenv": {
                    "type": "string",
                    "description": "The contents of a .env file. Saved for production and previews."
                  },
                  "sensitive": {
                    "type": "boolean",
                    "description": "The dotenv values cannot be viewed again once saved."
                  },
                  "app": {
                    "type": "string",
                    "description": "The app name (\"App name\" in the console). Empty means the folder name, or the repository name. An app of that name has its settings changed."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/git/checks/{repo}/{repo}": {
      "put": {
        "operationId": "set_checks_on_server",
        "summary": "Run checks on One Server",
        "description": "Turns on or off running a connected GitHub repository's GitHub Actions checks on One Server's machines, as [Run checks on One Server] under Git connection in the console does. On saves the repository variable POOL_RUNNER: a job that says runs-on: ${{ vars.POOL_RUNNER || 'ubuntu-latest' }} runs on One Server. Off deletes it, and jobs go back to GitHub's machines. When state is needs_permission, approve the GitHub App's new permissions at permission_url and it turns on by itself. Only owners and admins can do this.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "repo",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "repositories[].repo (owner/name) from list_git_access."
            }
          },
          {
            "name": "repo",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "repositories[].repo (owner/name) from list_git_access."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "set_checks_on_server",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean",
                    "description": "true turns it on, false turns it off."
                  }
                },
                "required": [
                  "enabled"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/git/repos/{name}": {
      "delete": {
        "operationId": "disconnect_repository",
        "summary": "Disconnect a repository",
        "description": "The same as [Disconnect] on a repository under Git connection in the console. Pushes to this repository no longer deploy. The deployment serving now, the history, build settings and environment variables stay, and import_repository with the same repository connects it again. Only owners and admins can do this.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "repositories[].name from list_git_access."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "name": {},
                    "repo": {},
                    "connected": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "disconnect_repository"
      }
    },
    "/projects/{ref}/log-drains": {
      "get": {
        "operationId": "list_log_drains",
        "summary": "Log drains",
        "description": "Where logs are sent (https or datadog), which sources are sent, and the last delivery and error. The signing key (signing_secret) is shown once, when the drain is created (create_log_drain); the list carries only signing_secret_set and, for owners and admins, its last four characters (signing_secret_last4).",
        "tags": [
          "logs"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "sources": {},
                    "drains": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_log_drains"
      },
      "post": {
        "operationId": "create_log_drain",
        "summary": "Add a log drain",
        "description": "Sends this project's logs elsewhere, starting with logs written after it is created. kind=https POSTs signed JSON; kind=datadog needs an API key in secret. An https drain's signing_secret is in this answer only, so save it on the receiving side right away. Up to 5 per project. Only owners and admins can do this.",
        "tags": [
          "logs"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "create_log_drain",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "A name to recognise the drain by."
                  },
                  "kind": {
                    "type": "string",
                    "enum": [
                      "https",
                      "datadog"
                    ],
                    "description": "https or datadog."
                  },
                  "url": {
                    "type": "string",
                    "description": "A public https address."
                  },
                  "secret": {
                    "type": "string",
                    "description": "The Datadog API key, or the value to put in the Authorization header when sending over https."
                  },
                  "sources": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "site",
                        "server",
                        "api",
                        "auth",
                        "functions",
                        "build"
                      ]
                    },
                    "description": "Empty means all."
                  }
                },
                "required": [
                  "name",
                  "kind",
                  "url"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/log-drains/{id}": {
      "patch": {
        "operationId": "set_log_drain_enabled",
        "summary": "Turn a log drain off or on",
        "description": "Stops or restarts sending and keeps the settings. Only owners and admins can do this.",
        "tags": [
          "logs"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The id from list_log_drains."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "id": {},
                    "enabled": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "set_log_drain_enabled",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean",
                    "description": "true to send, false to stop."
                  }
                },
                "required": [
                  "enabled"
                ]
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "remove_log_drain",
        "summary": "Remove a log drain",
        "description": "Removes a log drain. Only owners and admins can do this.",
        "tags": [
          "logs"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The id from list_log_drains."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "id": {},
                    "removed": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "remove_log_drain"
      }
    },
    "/projects/{ref}/analytics": {
      "get": {
        "operationId": "get_analytics",
        "summary": "Web analytics",
        "description": "Returns page views and visitors per day, with the top pages, referrers, countries, devices, browsers and operating systems. Nothing that identifies a person is stored, so these are totals only.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "days",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "enum": [
                1,
                7,
                30,
                90
              ],
              "description": "The period in days. 7 by default."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "settings": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_analytics"
      }
    },
    "/projects/{ref}/analytics/breakdown": {
      "get": {
        "operationId": "get_analytics_breakdown",
        "summary": "Web Analytics breakdown",
        "description": "Returns campaigns (utm_source, utm_medium, utm_campaign), routes, custom events and how many bots were filtered. With event, also that event's values per property. Totals only.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "days",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "enum": [
                1,
                7,
                30,
                90
              ],
              "description": "The period. 7 by default."
            }
          },
          {
            "name": "event",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 100,
              "description": "The event whose properties to break down."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "days": {},
                    "utm_source": {},
                    "utm_medium": {},
                    "utm_campaign": {},
                    "routes": {},
                    "events": {},
                    "bots_filtered": {},
                    "crawlers": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_analytics_breakdown"
      }
    },
    "/projects/{ref}/analytics/previews": {
      "put": {
        "operationId": "set_analytics_previews",
        "summary": "Count preview visits",
        "description": "Sets whether visits to preview deployments and dpl- addresses count in Web Analytics. Off (the default), previews get no script and what they send is dropped. Only owners and admins can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "include_previews": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "set_analytics_previews",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "include_previews": {
                    "type": "boolean",
                    "description": "Count previews too."
                  }
                },
                "required": [
                  "include_previews"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/analytics/export": {
      "get": {
        "operationId": "export_analytics",
        "summary": "Export Web Analytics",
        "description": "Returns the period's totals as a CSV string, by day, dimension and value.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "days",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "enum": [
                1,
                7,
                30,
                90
              ],
              "description": "The period. 7 by default."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "days": {},
                    "format": {},
                    "csv": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "export_analytics"
      }
    },
    "/projects/{ref}/analytics/reports": {
      "get": {
        "operationId": "list_analytics_reports",
        "summary": "Custom reports",
        "description": "Returns the saved Web Analytics reports and the names of the charts a report can hold.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "widgets": {},
                    "reports": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_analytics_reports"
      },
      "post": {
        "operationId": "post_projects_ref_analytics_reports",
        "summary": "Save a custom report",
        "description": "Creates a report, or changes the one id names. Developers and above can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "report": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "save_analytics_report",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 80,
                    "description": "The name."
                  },
                  "days": {
                    "type": "integer",
                    "enum": [
                      1,
                      7,
                      30,
                      90
                    ],
                    "description": "The period. 7 by default."
                  },
                  "widgets": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "views",
                        "visitors",
                        "path",
                        "referrer",
                        "country",
                        "device",
                        "browser",
                        "os",
                        "utm_source",
                        "utm_medium",
                        "utm_campaign",
                        "route",
                        "event",
                        "bot",
                        "vitals"
                      ]
                    },
                    "minItems": 1,
                    "maxItems": 16,
                    "description": "The charts and tables to show."
                  }
                },
                "required": [
                  "name",
                  "widgets"
                ]
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "patch_projects_ref_analytics_reports",
        "summary": "Save a custom report",
        "description": "Creates a report, or changes the one id names. Developers and above can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "report": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "save_analytics_report",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 80,
                    "description": "The name."
                  },
                  "days": {
                    "type": "integer",
                    "enum": [
                      1,
                      7,
                      30,
                      90
                    ],
                    "description": "The period. 7 by default."
                  },
                  "widgets": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "views",
                        "visitors",
                        "path",
                        "referrer",
                        "country",
                        "device",
                        "browser",
                        "os",
                        "utm_source",
                        "utm_medium",
                        "utm_campaign",
                        "route",
                        "event",
                        "bot",
                        "vitals"
                      ]
                    },
                    "minItems": 1,
                    "maxItems": 16,
                    "description": "The charts and tables to show."
                  }
                },
                "required": [
                  "name",
                  "widgets"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/analytics/reports/{id}": {
      "get": {
        "operationId": "get_analytics_report",
        "summary": "Show a custom report",
        "description": "Returns one saved report with its period's totals, breakdowns and speed.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The id list_analytics_reports returned."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "report": {},
                    "totals": {},
                    "breakdown": {},
                    "speed": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_analytics_report"
      },
      "delete": {
        "operationId": "remove_analytics_report",
        "summary": "Delete a custom report",
        "description": "Deletes the report only; the analytics stay as they are. Developers and above can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The id list_analytics_reports returned."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "id": {},
                    "removed": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "remove_analytics_report"
      }
    },
    "/projects/{ref}/speed-insights": {
      "get": {
        "operationId": "get_speed_insights",
        "summary": "Speed Insights",
        "description": "Returns the 75th percentile and rating of the Core Web Vitals (LCP, INP, CLS, FCP, TTFB) that real visitors measured, and the slowest pages.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "days",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "enum": [
                1,
                7,
                30,
                90
              ],
              "description": "The period in days. 7 by default."
            }
          },
          {
            "name": "device",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "desktop",
                "mobile"
              ],
              "description": "The device. all by default."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "settings": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_speed_insights"
      }
    },
    "/projects/{ref}/insights": {
      "put": {
        "operationId": "set_insights",
        "summary": "Turn analytics on or off",
        "description": "Turns Web Analytics and Speed Insights on or off. When on, the site's HTML gets the /_oneend/insights/script.js script. Apps that use Vercel's @vercel/analytics and @vercel/speed-insights are counted in the same place with no code change. No cookies are used and no address is stored. Only owners and admins can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "settings": {},
                    "script": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "set_insights",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "analytics": {
                    "type": "boolean",
                    "description": "Web Analytics."
                  },
                  "speed_insights": {
                    "type": "boolean",
                    "description": "Speed Insights."
                  },
                  "vitals_sample_percent": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 100,
                    "description": "The share of visits whose speed is measured."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/remote-cache": {
      "get": {
        "operationId": "get_remote_cache",
        "summary": "Remote cache",
        "description": "Returns the Turborepo remote cache's address, how many outputs it holds and their size, the last 30 days' hits and uploads, and this month's metered storage (remote_cache_gb_hour) with its price. Downloads are counted as egress_gb.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "api": {},
                    "artifacts": {},
                    "bytes": {},
                    "last_30_days": {},
                    "metered": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_remote_cache"
      }
    },
    "/projects/{ref}/remote-cache/artifacts": {
      "delete": {
        "operationId": "clear_remote_cache",
        "summary": "Clear the remote cache",
        "description": "Deletes every stored output. The next builds fill it again, and the metered storage drops by what was cleared. Developers and above can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "cleared": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "clear_remote_cache"
      }
    },
    "/projects/{ref}/flags": {
      "get": {
        "operationId": "list_flags",
        "summary": "Feature flags",
        "description": "Returns the project's feature flags together with the flag-shaped values kept in its edge config. source says where each is kept and shadows whether it hides an edge config value of the same key. Where both have a key, the flag decides.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "flags": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_flags"
      }
    },
    "/projects/{ref}/flags/evaluate": {
      "get": {
        "operationId": "evaluate_flag",
        "summary": "Evaluate a feature flag",
        "description": "Returns what the app would get: with a context (e.g. {\"user\": {\"id\": \"u1\"}}) and an environment, the flag's rules decide; with no flag of that key, the edge config value does. source says which decided.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "key",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 256,
              "description": "The flag key."
            }
          },
          {
            "name": "environment",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "The environment. production by default."
            }
          },
          {
            "name": "context",
            "in": "query",
            "required": false,
            "schema": {
              "type": "object",
              "description": "The context to evaluate for (a JSON object)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "key": {},
                    "environment": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "evaluate_flag"
      }
    },
    "/projects/{ref}/flags/{key}/environments/{environment}": {
      "put": {
        "operationId": "set_flag_enabled",
        "summary": "Turn a feature flag on or off",
        "description": "Turns a flag on or off in one environment. Production takes owners and admins; other environments, developers and above.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "key",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 64,
              "description": "The flag key."
            }
          },
          {
            "name": "environment",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The environment."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "key": {},
                    "environment": {},
                    "enabled": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-mcp-tool": "set_flag_enabled",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean",
                    "description": "On."
                  }
                },
                "required": [
                  "enabled"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/edge-config": {
      "get": {
        "operationId": "get_edge_config",
        "summary": "Read edge config",
        "description": "Returns the project's edge config (values and feature flags that change without a deploy), with its version, size and limits.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "version": {},
                    "bytes": {},
                    "limits": {},
                    "items": {},
                    "read_url": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_edge_config"
      },
      "patch": {
        "operationId": "set_edge_config",
        "summary": "Change edge config",
        "description": "Sets or deletes keys. Every server has the change within a few seconds, and it is kept in the history. A flag is true or false, or {\"enabled\": true, \"percent\": 20}, or {\"enabled\": true, \"allow\": [\"user-1\"]}. Developers and above can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "version": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "set_edge_config",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "set": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Keys and values to set (values are JSON)."
                  },
                  "delete": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Keys to delete."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/edge-config/tokens": {
      "get": {
        "operationId": "list_edge_config_tokens",
        "summary": "Edge config read tokens",
        "description": "Returns the read tokens other projects read this project's edge config with, the projects each is connected to (variable name, environments), and other projects' edge configs connected to this one. The tokens themselves are not returned.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "tokens": {},
                    "connected_here": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_edge_config_tokens"
      },
      "post": {
        "operationId": "create_edge_config_token",
        "summary": "Create an edge config read token",
        "description": "Creates a read token and, with connect, connects it to a project in the same organization. From its next deployment, that project gets the connection string (https://<ref>.<zone>/config/v1?token=…) as a variable. The token is shown only this once. Project admins only.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "id": {},
                    "name": {},
                    "token": {},
                    "connection_string": {},
                    "connected": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "create_edge_config_token",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "connect": {
                    "type": "object",
                    "properties": {
                      "ref": {
                        "type": "string",
                        "pattern": "^[a-z]{20}$"
                      },
                      "variable": {
                        "type": "string",
                        "pattern": "^[A-Za-z_][A-Za-z0-9_]{0,63}$"
                      },
                      "targets": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "enum": [
                            "production",
                            "preview",
                            "development"
                          ]
                        },
                        "minItems": 1,
                        "uniqueItems": true
                      }
                    },
                    "required": [
                      "ref"
                    ],
                    "additionalProperties": false,
                    "description": "A project in the same organization to connect right away: ref, the variable name (GLOBAL_CONFIG by default) and targets (all three environments by default; production only by that project's owners and admins)."
                  },
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 60,
                    "description": "The token's name."
                  }
                },
                "required": [
                  "name"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/edge-config/tokens/{id}": {
      "delete": {
        "operationId": "revoke_edge_config_token",
        "summary": "Revoke a read token",
        "description": "Revokes a read token. It stops reading at once, and connected projects lose the variable with their next deployment.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The read token id, from list_edge_config_tokens."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "id": {},
                    "revoked": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "revoke_edge_config_token"
      }
    },
    "/projects/{ref}/edge-config/tokens/{id}/connections/{ref}": {
      "put": {
        "operationId": "connect_edge_config_token",
        "summary": "Connect a read token to a project",
        "description": "Connects a read token to another project in the organization as a variable in its deployments. If already connected, changes the variable name and environments. Takes a developer or above of that project (owners and admins for production).",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The read token id, from list_edge_config_tokens."
            }
          },
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "id": {},
                    "connected": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "connect_edge_config_token",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "variable": {
                    "type": "string",
                    "pattern": "^[A-Za-z_][A-Za-z0-9_]{0,63}$",
                    "description": "The variable deployments read. GLOBAL_CONFIG by default."
                  },
                  "targets": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "production",
                        "preview",
                        "development"
                      ]
                    },
                    "minItems": 1,
                    "uniqueItems": true,
                    "description": "Environments that get the variable. All three by default; production only by that project's owners and admins."
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "disconnect_edge_config_token",
        "summary": "Disconnect a read token",
        "description": "Takes a read token out of one project. The variable leaves with that project's next deployment.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The read token id, from list_edge_config_tokens."
            }
          },
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "A project in the same organization to connect."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "id": {},
                    "disconnected": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "disconnect_edge_config_token"
      }
    },
    "/projects/{ref}/edge-config/history": {
      "get": {
        "operationId": "get_edge_config_history",
        "summary": "Edge config history",
        "description": "Returns who changed which key, when, from what to what, most recent first.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "description": "How many. 50 by default."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "changes": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_edge_config_history"
      }
    },
    "/projects/{ref}/rolling-releases": {
      "get": {
        "operationId": "get_rolling_releases",
        "summary": "Rolling releases",
        "description": "Returns the rolling release settings, the release in progress (the share of visitors the new deployment gets), and recent ones.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "config": {},
                    "active": {},
                    "recent": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_rolling_releases"
      },
      "put": {
        "operationId": "set_rolling_releases",
        "summary": "Rolling release settings",
        "description": "Decides whether new production deployments go out in stages. stages is a rising list of shares (for example [10, 50]), stage_minutes the length of each, and with auto_advance false each stage waits for approval. Above abort_error_rate (0.05 is 5%) the release is rolled back automatically. Only owners and admins can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "config": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "set_rolling_releases",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean",
                    "description": "On."
                  },
                  "stages": {
                    "type": "array",
                    "items": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 99
                    },
                    "description": "The share at each stage (%)."
                  },
                  "stage_minutes": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 1440,
                    "description": "Stage length in minutes."
                  },
                  "auto_advance": {
                    "type": "boolean",
                    "description": "Move on automatically as time passes."
                  },
                  "abort_error_rate": {
                    "type": [
                      "number",
                      "null"
                    ],
                    "minimum": 0.001,
                    "maximum": 1,
                    "description": "The 5xx rate that stops it automatically. null turns it off."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/rolling-releases/{action}": {
      "post": {
        "operationId": "advance_rolling_release",
        "summary": "Advance a rolling release",
        "description": "Moves the release in progress to its next stage. From the last stage it goes to everybody. Only owners and admins can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "action",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "release": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "advance_rolling_release",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/kv": {
      "get": {
        "operationId": "list_kv_keys",
        "summary": "KV keys",
        "description": "Returns the KV store's keys by prefix, 50 at a time, with usage, limits and the REST address. Only roles that may see secrets can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "prefix",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "A prefix."
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "The cursor from the previous answer."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "usage": {},
                    "keys": {},
                    "cursor": {},
                    "rest_url": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-permissions": [
          "secrets.read (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "list_kv_keys"
      }
    },
    "/projects/{ref}/kv/{id}": {
      "get": {
        "operationId": "get_kv",
        "summary": "Read a KV value",
        "description": "Returns one key's value and the seconds it has left (ttl, -1 for no expiry).",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "key": {},
                    "value": {},
                    "ttl": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-permissions": [
          "secrets.read (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "get_kv"
      },
      "put": {
        "operationId": "set_kv",
        "summary": "Save a KV value",
        "description": "Stores a JSON value at a key. ttl is the seconds until it expires. Developers and above can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "key": {},
                    "saved": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "set_kv",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "value": {
                    "description": "The value (JSON)."
                  },
                  "ttl": {
                    "type": "integer",
                    "minimum": 1,
                    "description": "Seconds until it expires."
                  }
                },
                "required": [
                  "value"
                ]
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete_kv",
        "summary": "Delete a KV key",
        "description": "Deletes a key. Developers and above can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "key": {},
                    "removed": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "delete_kv"
      }
    },
    "/projects/{ref}/ai-gateway": {
      "get": {
        "operationId": "get_ai_gateway",
        "summary": "AI gateway",
        "description": "Returns the AI gateway's OpenAI-compatible address, its settings, its providers (keys as their last four characters only), and the last 30 days of use.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "base_url": {},
                    "settings": {},
                    "providers": {},
                    "usage_30d": {},
                    "top_users_30d": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_ai_gateway"
      },
      "put": {
        "operationId": "set_ai_gateway",
        "summary": "AI gateway settings",
        "description": "Turns the AI gateway on or off and sets whether signed-in users may call it, the cache in seconds, the requests per minute, the fallback to the platform's provider (billed per token), and the daily requests and tokens one user of the app may use. The user is a signed-in user's id, or, with the secret key, the x-oneend-user header or the body's user. Only owners and admins can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "settings": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "set_ai_gateway",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean",
                    "description": "On."
                  },
                  "allow_users": {
                    "type": "boolean",
                    "description": "Allow signed-in users."
                  },
                  "cache_seconds": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 86400,
                    "description": "Cache seconds."
                  },
                  "rate_per_minute": {
                    "type": "integer",
                    "minimum": 1,
                    "description": "Requests per minute."
                  },
                  "platform_fallback": {
                    "type": "boolean",
                    "description": "Fall back to the platform provider."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/ai-gateway/logs": {
      "get": {
        "operationId": "get_ai_gateway_logs",
        "summary": "AI gateway calls",
        "description": "Returns recent calls with their provider, model, status, tokens, latency and whether they fell back. Conversations are not stored.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "description": "How many. 50 by default."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "logs": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_ai_gateway_logs"
      }
    },
    "/projects/{ref}/ai-gateway/providers": {
      "post": {
        "operationId": "add_ai_provider",
        "summary": "Add an AI provider",
        "description": "Adds a provider with its key: OpenAI-compatible, Anthropic (translated to and from its Messages API) or Google Gemini. Only public https addresses are accepted. The key is sealed and never shown again. Only owners and admins can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "add_ai_provider",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "pattern": "^[a-z][a-z0-9-]{0,39}$",
                    "description": "A name; calling name/model calls this provider only."
                  },
                  "kind": {
                    "type": "string",
                    "enum": [
                      "openai",
                      "anthropic",
                      "google",
                      "deepseek",
                      "openai-compatible"
                    ],
                    "description": "The type."
                  },
                  "base_url": {
                    "type": "string",
                    "description": "The address. Optional for openai, anthropic, google and deepseek."
                  },
                  "key": {
                    "type": "string",
                    "description": "The API key."
                  },
                  "models": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "The models it takes. Empty for any."
                  },
                  "priority": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 1000,
                    "description": "Priority, lowest first."
                  }
                },
                "required": [
                  "name",
                  "kind"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/ai-gateway/providers/{id}": {
      "patch": {
        "operationId": "set_ai_provider_enabled",
        "summary": "Turn an AI provider off or on",
        "description": "Stops or resumes using a provider and keeps its settings and key. Only owners and admins can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The id get_ai_gateway returned."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "id": {},
                    "enabled": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "set_ai_provider_enabled",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean",
                    "description": "Use it."
                  }
                },
                "required": [
                  "enabled"
                ]
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "remove_ai_provider",
        "summary": "Remove an AI provider",
        "description": "Removes a provider and its sealed key. Only owners and admins can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The id get_ai_gateway returned."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "id": {},
                    "removed": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "remove_ai_provider"
      }
    },
    "/projects/{ref}/ai-gateway/budgets": {
      "put": {
        "operationId": "set_ai_budgets",
        "summary": "AI gateway budgets",
        "description": "Sets the project's AI gateway budgets in dollars (day, week and month, UTC). Once one is spent, calls are refused until the next period. A value left out is kept. Only owners and admins can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "budgets": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "set_ai_budgets",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "daily_usd": {
                    "type": [
                      "number",
                      "null"
                    ],
                    "minimum": 0,
                    "maximum": 1000000,
                    "description": "The daily (UTC) budget in dollars. null for none."
                  },
                  "weekly_usd": {
                    "type": [
                      "number",
                      "null"
                    ],
                    "minimum": 0,
                    "maximum": 1000000,
                    "description": "The weekly (from Monday, UTC) budget in dollars. null for none."
                  },
                  "monthly_usd": {
                    "type": [
                      "number",
                      "null"
                    ],
                    "minimum": 0,
                    "maximum": 1000000,
                    "description": "The monthly (UTC) budget in dollars. null for none."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/ai-gateway/keys": {
      "get": {
        "operationId": "list_ai_gateway_keys",
        "summary": "AI gateway keys",
        "description": "Returns the gateway keys with their names, prefixes, budgets, this month's spend and when each was last used. Never the keys themselves.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "keys": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_ai_gateway_keys"
      },
      "post": {
        "operationId": "create_ai_gateway_key",
        "summary": "Create an AI gateway key",
        "description": "Creates a gateway key (bwai_…) for one app, or for one customer the project resells AI to, with its own budgets, tag and limits per minute. The key is in this answer once and never again. Keys with a tag (external_ref) do not count toward the 50 keys a project may have. Only owners and admins can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "id": {},
                    "name": {},
                    "key": {},
                    "base_url": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "create_ai_gateway_key",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 60,
                    "description": "The key's name."
                  },
                  "daily_usd": {
                    "type": [
                      "number",
                      "null"
                    ],
                    "minimum": 0,
                    "maximum": 1000000,
                    "description": "The daily (UTC) budget in dollars. null for none."
                  },
                  "weekly_usd": {
                    "type": [
                      "number",
                      "null"
                    ],
                    "minimum": 0,
                    "maximum": 1000000,
                    "description": "The weekly (from Monday, UTC) budget in dollars. null for none."
                  },
                  "monthly_usd": {
                    "type": [
                      "number",
                      "null"
                    ],
                    "minimum": 0,
                    "maximum": 1000000,
                    "description": "The monthly (UTC) budget in dollars. null for none."
                  },
                  "external_ref": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 200,
                    "description": "Who the key stands for in the project's own books, such as a customer's user id. Sent to the hooks."
                  },
                  "labels": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string",
                      "maxLength": 100
                    },
                    "description": "Up to 20 free labels, such as {\"tier\": \"1\"}. Sent to the hooks."
                  },
                  "rate_per_minute": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "minimum": 1,
                    "maximum": 100000,
                    "description": "Requests per minute. null for none."
                  },
                  "tokens_per_minute": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "minimum": 1,
                    "maximum": 100000000,
                    "description": "Tokens per minute, prompt and completion. null for none."
                  }
                },
                "required": [
                  "name"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/ai-gateway/keys/{id}/limits": {
      "put": {
        "operationId": "set_ai_gateway_key_limits",
        "summary": "AI gateway key limits",
        "description": "Changes one gateway key's limits on requests and tokens per minute. Every server counts the same minute. A value left out is kept; null removes the limit. Only owners and admins can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The id list_ai_gateway_keys returned."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "id": {},
                    "limits": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "set_ai_gateway_key_limits",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "rate_per_minute": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "minimum": 1,
                    "maximum": 100000,
                    "description": "Requests per minute. null for none."
                  },
                  "tokens_per_minute": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "minimum": 1,
                    "maximum": 100000000,
                    "description": "Tokens per minute, prompt and completion. null for none."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/ai-gateway/aliases": {
      "put": {
        "operationId": "set_ai_model_aliases",
        "summary": "AI model aliases",
        "description": "Sets the model names callers use (aliases) and the model each is sent to, each with an optional system prompt put first. Answers carry the alias as their model. The list given replaces the whole list. With aliases_only on, nothing but an alias can be asked for and /models lists only the aliases. Only owners and admins can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "aliases_only": {},
                    "aliases": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "set_ai_model_aliases",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "aliases": {
                    "type": "array",
                    "maxItems": 50,
                    "items": {
                      "type": "object",
                      "properties": {
                        "alias": {
                          "type": "string",
                          "pattern": "^[a-z0-9][a-z0-9._-]{0,63}$"
                        },
                        "target": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 160
                        },
                        "system_prompt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "maxLength": 20000
                        }
                      },
                      "required": [
                        "alias",
                        "target"
                      ],
                      "additionalProperties": false
                    },
                    "description": "Every alias. An empty list removes them all."
                  },
                  "aliases_only": {
                    "type": "boolean",
                    "description": "Allow aliases only. Kept as it is when left out."
                  }
                },
                "required": [
                  "aliases"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/ai-gateway/hooks": {
      "put": {
        "operationId": "set_ai_gateway_hooks",
        "summary": "AI gateway hooks",
        "description": "Sets the https address asked before, and told after, every call made with a gateway key. If ai.before does not answer 2xx within timeout_ms, the call is refused (a 402 is passed on as a low balance). ai.after carries the usage, cost and status, and is sent again for a day until it is taken. The answer holds the signing secret. A null url turns hooks off. Only owners and admins can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "url": {},
                    "timeout_ms": {},
                    "signing_secret": {},
                    "events": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "set_ai_gateway_hooks",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 500,
                    "description": "The hook address (https). null turns hooks off."
                  },
                  "timeout_ms": {
                    "type": "integer",
                    "minimum": 200,
                    "maximum": 10000,
                    "description": "How long ai.before may take to answer, in milliseconds. 2000 by default."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/ai-gateway/keys/{id}": {
      "patch": {
        "operationId": "set_ai_gateway_key_budgets",
        "summary": "AI gateway key budgets",
        "description": "Changes one gateway key's budgets. A value left out is kept. Only owners and admins can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The id list_ai_gateway_keys returned."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "id": {},
                    "budgets": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "set_ai_gateway_key_budgets",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "daily_usd": {
                    "type": [
                      "number",
                      "null"
                    ],
                    "minimum": 0,
                    "maximum": 1000000,
                    "description": "The daily (UTC) budget in dollars. null for none."
                  },
                  "weekly_usd": {
                    "type": [
                      "number",
                      "null"
                    ],
                    "minimum": 0,
                    "maximum": 1000000,
                    "description": "The weekly (from Monday, UTC) budget in dollars. null for none."
                  },
                  "monthly_usd": {
                    "type": [
                      "number",
                      "null"
                    ],
                    "minimum": 0,
                    "maximum": 1000000,
                    "description": "The monthly (UTC) budget in dollars. null for none."
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "revoke_ai_gateway_key",
        "summary": "Revoke an AI gateway key",
        "description": "Revokes a gateway key. Every server refuses it within 30 seconds. Only owners and admins can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The id list_ai_gateway_keys returned."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "id": {},
                    "revoked": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "revoke_ai_gateway_key"
      }
    },
    "/projects/{ref}/ai-gateway/spend": {
      "get": {
        "operationId": "get_ai_spend",
        "summary": "AI gateway spend",
        "description": "Returns today's, this week's and this month's spend against the budgets, and spend per day, model and key, in dollars. Calls to a provider with the project's own key are estimated at list price.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "days",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 400,
              "description": "How many days. 30 by default."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "spent_usd": {},
                    "budgets": {},
                    "days": {},
                    "models": {},
                    "keys": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_ai_spend"
      }
    },
    "/projects/{ref}/middleware": {
      "get": {
        "operationId": "get_middleware",
        "summary": "Middleware settings",
        "description": "Returns whether the site's middleware (middleware.ts) runs and its time limit.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "enabled": {},
                    "timeout_ms": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_middleware"
      },
      "put": {
        "operationId": "set_middleware",
        "summary": "Change middleware settings",
        "description": "Turns the site's middleware off or on and sets its time limit (100 to 5000ms). Off serves without middleware, with no new deploy. Only owners and admins can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "enabled": {},
                    "timeout_ms": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "set_middleware",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean",
                    "description": "Run it."
                  },
                  "timeout_ms": {
                    "type": "integer",
                    "minimum": 100,
                    "maximum": 5000,
                    "description": "Time limit (ms)."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/function-egress": {
      "put": {
        "operationId": "set_function_egress",
        "summary": "Functions' outbound requests",
        "description": "Allows or blocks functions from calling public HTTPS addresses with fetch(). The current state is egress in list_functions. Takes effect within 30 seconds. Only owners and admins can do this.",
        "tags": [
          "functions"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "egress": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "set_function_egress",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean",
                    "description": "true to allow outbound requests, false to block them."
                  }
                },
                "required": [
                  "enabled"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/function-secrets": {
      "get": {
        "operationId": "list_function_secrets",
        "summary": "Function secrets",
        "description": "The names of the secrets only functions see, and when each changed. No tool can read a value back. readable false means the value no longer opens and is left out of functions, so save it again. Only owners and admins can see them.",
        "tags": [
          "functions"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "secrets": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "list_function_secrets"
      },
      "post": {
        "operationId": "set_function_secrets",
        "summary": "Save function secrets",
        "description": "Saves one or more secrets only functions see (a webhook signing key, a mail service's API key). They never reach a site build, and they win over an environment variable of the same name. Functions read them from process.env from their next call. A name already there is overwritten; if any one is wrong, nothing is saved. A saved value cannot be read back: the answer holds names only. Names starting with SUPABASE_ or BLACKWALL, and NODE_ENV, HOME, PATH, NODE_OPTIONS and TZ, are refused. Up to 100 per project and 32KB per value. Only owners and admins can do this.",
        "tags": [
          "functions"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "saved": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "set_function_secrets",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "secrets": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string"
                    },
                    "description": "Names and values, for example {\"STRIPE_WEBHOOK_SECRET\": \"whsec_…\"}. The values are not shown again."
                  },
                  "dotenv": {
                    "type": "string",
                    "description": "The whole of a .env file. Comments and blank lines are skipped."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/function-secrets/copy": {
      "post": {
        "operationId": "copy_function_secrets",
        "summary": "Copy function secrets",
        "description": "Copies function secrets by name from another of your projects (from) into this one (ref). The values move inside the server and the answer holds names only, so the same key need not be pasted again. A name this project already has is skipped (skipped) unless overwrite is true. Names from does not have are listed in missing and the rest are copied. Up to 50 at a time. You must be an owner or admin of both projects (they may be in different organisations).",
        "tags": [
          "functions"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "from": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "copy_function_secrets",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "from": {
                    "type": "string",
                    "description": "The ref of the project to copy from. list_projects gives it."
                  },
                  "names": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "maxItems": 50,
                    "description": "The secret names to copy: name in list_function_secrets of the from project. For example [\"ANTHROPIC_API_KEY\"]."
                  },
                  "overwrite": {
                    "type": "boolean",
                    "description": "Whether to replace a name this project already has. Defaults to false (skipped)."
                  }
                },
                "required": [
                  "from",
                  "names"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/function-secrets/{name}": {
      "delete": {
        "operationId": "delete_function_secret",
        "summary": "Delete a function secret",
        "description": "Deletes one function secret. The value cannot be brought back, and functions run without it from their next call. Only owners and admins can do this.",
        "tags": [
          "functions"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "name in list_function_secrets."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "name": {},
                    "deleted": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "delete_function_secret"
      }
    },
    "/projects/{ref}/volumes": {
      "get": {
        "operationId": "list_volumes",
        "summary": "Volumes",
        "description": "Returns the app volumes (disk that stays when a server restarts or a new deployment goes out) and their backups, how much the plan allows in total (max_gb) and how much is used (used_gb), and the port each app's server listens on (apps[].listens_on). Volumes are mounted on production servers only.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "max_gb": {},
                    "used_gb": {},
                    "volumes": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_volumes"
      },
      "post": {
        "operationId": "create_volume",
        "summary": "Create a volume",
        "description": "Adds a volume to an app's production servers, mounted read-write at mount_path in the container; its size is a hard cap. For WordPress use /var/www/html. System paths such as /etc, /usr, /proc and /tmp are refused. Ready within a minute; the servers restart with it. Only owners and admins can do this.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "volume": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "create_volume",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "app": {
                    "type": "string",
                    "description": "The name from list_apps."
                  },
                  "mount_path": {
                    "type": "string",
                    "description": "An absolute path inside the container, for example /var/www/html."
                  },
                  "size_gb": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 500,
                    "description": "Size in GB, 1 to 500. 1 by default."
                  }
                },
                "required": [
                  "app",
                  "mount_path"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/volumes/{id}": {
      "patch": {
        "operationId": "resize_volume",
        "summary": "Grow a volume",
        "description": "Makes a volume larger without stopping the server. A volume cannot shrink. Only owners and admins can do this.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The volume id from list_volumes."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "volume": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "resize_volume",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "size_gb": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 500,
                    "description": "Size in GB, 1 to 500."
                  }
                },
                "required": [
                  "size_gb"
                ]
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete_volume",
        "summary": "Delete a volume",
        "description": "Deletes a volume, every file on it and its backups. Production servers restart without it. This cannot be undone, so use it only when the user clearly asks, and put the volume path (mount_path) exactly in confirm. Only owners and admins can do this.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The volume id from list_volumes."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "volume": {},
                    "deleted": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "delete_volume",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "confirm": {
                    "type": "string",
                    "description": "The volume path. Must equal mount_path from list_volumes exactly."
                  }
                },
                "required": [
                  "confirm"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/volumes/{id}/backups": {
      "post": {
        "operationId": "create_volume_backup",
        "summary": "Back up a volume",
        "description": "Packs the volume's files now and keeps them for 30 days. Finishes within a few minutes and appears in list_volumes under backups. Only owners and admins can do this.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The volume id from list_volumes."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "volume_id": {},
                    "backup": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "create_volume_backup"
      }
    },
    "/projects/{ref}/volumes/{id}/restore": {
      "post": {
        "operationId": "restore_volume_backup",
        "summary": "Restore a volume",
        "description": "Replaces the volume's current files with a backup's. Files changed after the backup are lost, but the current files are backed up first and kept for 7 days, so that backup undoes it. Use it only when the user asks. Only owners and admins can do this.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The volume id from list_volumes."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "volume": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "restore_volume_backup",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "backup_id": {
                    "type": "string",
                    "description": "A backups[].id from list_volumes whose status is ready."
                  }
                },
                "required": [
                  "backup_id"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/server-memory": {
      "get": {
        "operationId": "get_server_memory",
        "summary": "Server memory",
        "description": "The memory (MB) and CPUs this project's server deployments run with, the most its plan allows, the price per GB-hour and what a server held all month costs. Servers at production and branch addresses always run, requests or not (minimum one instance), so that is what one of them costs a month.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "server_memory_mb": {},
                    "cpus": {},
                    "max_server_memory_mb": {},
                    "sizes": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_server_memory"
      },
      "put": {
        "operationId": "set_server_memory",
        "summary": "Change server memory",
        "description": "Chooses the memory this project's server deployments (Node servers, workers) run with: 512, 1024, 2048 or 4096 MB. Above 1024 MB they get two CPUs. Metered as runtime_gb_hour. Servers restart with the new size within a minute. Only owners and admins can do this.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "set_server_memory",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "memory_mb": {
                    "type": "integer",
                    "enum": [
                      512,
                      1024,
                      2048,
                      4096
                    ],
                    "description": "Memory in MB: 512, 1024, 2048 or 4096."
                  }
                },
                "required": [
                  "memory_mb"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/gpu": {
      "get": {
        "operationId": "list_gpu",
        "summary": "GPU jobs and servers",
        "description": "This project's GPU jobs (the latest 50), GPU servers and GPU storage, the hourly price of each card and the price of a GB-month of storage, the regions and data centers to choose from, and how many GPUs the organisation may run at once and runs now. The free plan has no GPUs.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "prices": {},
                    "max_gpus": {},
                    "in_use": {},
                    "jobs": {},
                    "servers": {},
                    "volumes": {},
                    "volume_price": {},
                    "max_volume_gb": {},
                    "volume_gb": {},
                    "regions": {},
                    "datacenters": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_gpu"
      }
    },
    "/projects/{ref}/gpu/jobs": {
      "post": {
        "operationId": "create_gpu_job",
        "summary": "Create a GPU job",
        "description": "Rents a GPU and runs a command in a public container image to its end (training, a batch). The GPU is let go when the command ends or max_minutes passes, and the seconds used are billed at the card's hourly price. Results last only if the job uploads them somewhere, such as the project's storage. The image needs curl, wget or python3 to report its start and end. Pulling the image is GPU time too: it is billed and counts toward max_minutes.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "create_gpu_job",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "gpu": {
                    "type": "string",
                    "enum": [
                      "rtx4090",
                      "l40s",
                      "a100",
                      "h100"
                    ],
                    "description": "rtx4090, l40s, a100 or h100"
                  },
                  "image": {
                    "type": "string",
                    "description": "A public image, e.g. pytorch/pytorch:2.4.0-cuda12.1-cudnn9-runtime"
                  },
                  "command": {
                    "type": "string",
                    "description": "Run with sh"
                  },
                  "name": {
                    "type": "string",
                    "description": "A name"
                  },
                  "env": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string"
                    },
                    "description": "Environment variables, kept sealed"
                  },
                  "max_minutes": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 10080,
                    "description": "60 by default"
                  },
                  "region": {
                    "type": "string",
                    "enum": [
                      "auto",
                      "asia",
                      "us",
                      "eu"
                    ],
                    "description": "Where to rent: auto (any data center with a free card, the default), asia (Japan, India), us or eu. With a volume, the GPU is rented in its data center."
                  },
                  "volume": {
                    "type": "string",
                    "description": "The GPU storage to mount at /workspace, by name (made with create_gpu_volume)"
                  }
                },
                "required": [
                  "gpu",
                  "image",
                  "command"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/gpu/jobs/{id}": {
      "get": {
        "operationId": "get_gpu_job",
        "summary": "A GPU job",
        "description": "One GPU job's status, the time and money it used, its exit code and the end of its output (up to 64KB).",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The job id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {},
                    "name": {},
                    "gpu": {},
                    "image": {},
                    "command": {},
                    "max_minutes": {},
                    "status": {},
                    "created_at": {},
                    "started_at": {},
                    "ended_at": {},
                    "seconds": {},
                    "cost_minor": {},
                    "exit_code": {},
                    "error": {},
                    "region": {},
                    "volume": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_gpu_job"
      }
    },
    "/projects/{ref}/gpu/jobs/{id}/cancel": {
      "post": {
        "operationId": "cancel_gpu_job",
        "summary": "Stop a GPU job",
        "description": "Stops a GPU job. One not started yet never starts; a running one lets its GPU go. The time until the GPU is let go is billed.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The job id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {},
                    "name": {},
                    "gpu": {},
                    "image": {},
                    "command": {},
                    "max_minutes": {},
                    "status": {},
                    "created_at": {},
                    "started_at": {},
                    "ended_at": {},
                    "seconds": {},
                    "cost_minor": {},
                    "exit_code": {},
                    "error": {},
                    "region": {},
                    "volume": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "cancel_gpu_job"
      }
    },
    "/projects/{ref}/gpu/servers": {
      "post": {
        "operationId": "create_gpu_server",
        "summary": "Create a GPU server",
        "description": "Creates a GPU server that hosts a model from a public image. Called with the secret key at https://<ref>.<zone>/gpu/v1/servers/<name>/, it starts when stopped (answering 503 meanwhile) and passes the request on. It stops after idle_minutes without a request (0 keeps it up). Billed by the second from when it starts turning on until it is off, image download included. The server receives the x-oneend-gpu-token header, the same value as ONEEND_GPU_TOKEN.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "create_gpu_server",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Lowercase letters, digits and hyphens"
                  },
                  "gpu": {
                    "type": "string",
                    "enum": [
                      "rtx4090",
                      "l40s",
                      "a100",
                      "h100"
                    ],
                    "description": "rtx4090, l40s, a100 or h100"
                  },
                  "image": {
                    "type": "string",
                    "description": "A public image, e.g. vllm/vllm-openai:latest"
                  },
                  "command": {
                    "type": "string",
                    "description": "Empty runs the image's own"
                  },
                  "env": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string"
                    },
                    "description": "Environment variables, kept sealed"
                  },
                  "port": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 65535,
                    "description": "8000 by default"
                  },
                  "idle_minutes": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 1440,
                    "description": "15 by default, 0 keeps it up"
                  },
                  "region": {
                    "type": "string",
                    "enum": [
                      "auto",
                      "asia",
                      "us",
                      "eu"
                    ],
                    "description": "Where to rent: auto (any data center with a free card, the default), asia (Japan, India), us or eu. With a volume, the GPU is rented in its data center."
                  },
                  "volume": {
                    "type": "string",
                    "description": "The GPU storage to mount at /workspace, by name (made with create_gpu_volume)"
                  }
                },
                "required": [
                  "name",
                  "gpu",
                  "image"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/gpu/servers/{name}/stop": {
      "post": {
        "operationId": "stop_gpu_server",
        "summary": "Stop a GPU server",
        "description": "Stops a GPU server now. The time until it is off is billed. The next request starts it again.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The server name"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "stop_gpu_server"
      }
    },
    "/projects/{ref}/gpu/servers/{name}": {
      "delete": {
        "operationId": "delete_gpu_server",
        "summary": "Delete a GPU server",
        "description": "Deletes a GPU server, stopping it first when it runs. This cannot be undone, so put the GPU server name exactly in confirm.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The server name"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "name": {},
                    "deleted": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "delete_gpu_server",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "confirm": {
                    "type": "string",
                    "description": "The GPU server name. It must be exactly the same as name."
                  }
                },
                "required": [
                  "confirm"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/gpu/volumes": {
      "post": {
        "operationId": "create_gpu_volume",
        "summary": "Create GPU storage",
        "description": "Creates GPU storage in one data center to keep models and data. Name it as volume on a job or server and it is mounted at /workspace, so nothing has to be downloaded again. Billed by the GB-month for as long as it exists, used or not. Jobs and servers that use it rent their GPU in its data center only. Not on the free plan.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "create_gpu_volume",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Lowercase letters, digits and hyphens"
                  },
                  "size_gb": {
                    "type": "integer",
                    "minimum": 10,
                    "maximum": 4000,
                    "description": "50 GB by default"
                  },
                  "datacenter": {
                    "type": "string",
                    "description": "A data center, e.g. AP-JP-1 (Japan); list_gpu lists them"
                  }
                },
                "required": [
                  "name",
                  "datacenter"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/gpu/volumes/{name}": {
      "delete": {
        "operationId": "delete_gpu_volume",
        "summary": "Delete GPU storage",
        "description": "Deletes GPU storage and every file on it. Not while a job or server uses it. This cannot be undone. Storage is billed until it is deleted.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The storage name"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "name": {},
                    "deleted": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "delete_gpu_volume"
      }
    },
    "/projects/{ref}/mysql": {
      "get": {
        "operationId": "list_mysql_databases",
        "summary": "List MySQL databases",
        "description": "Returns this project's MySQL databases (MariaDB 11.4), which app each goes to (app; null is the whole project), their status and size, and how many the plan allows (max). available false means this server has no MySQL yet.",
        "tags": [
          "database"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "available": {},
                    "max": {},
                    "apps": {},
                    "databases": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_mysql_databases"
      },
      "post": {
        "operationId": "create_mysql_database",
        "summary": "Create a MySQL database",
        "description": "Creates a database and its own login for an app that uses MySQL, such as WordPress. Usually ready within a minute. With app, only that app's deployments get it; without, every app of the project does (while it is the project's only one). That app's servers start with MYSQL_URL, MYSQL_HOST, MYSQL_PORT, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE and WORDPRESS_DB_HOST, WORDPRESS_DB_USER, WORDPRESS_DB_PASSWORD, WORDPRESS_DB_NAME (never in a build). Backed up every night.",
        "tags": [
          "database"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "create_mysql_database",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "pattern": "^[a-z][a-z0-9_]{0,31}$",
                    "description": "Starts with a lowercase letter; lowercase letters, digits and underscores (_), up to 32. For example: wordpress"
                  },
                  "app": {
                    "type": "string",
                    "description": "The app that gets this database. Empty for the whole project"
                  }
                },
                "required": [
                  "name"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/mysql/{name}": {
      "patch": {
        "operationId": "bind_mysql_database",
        "summary": "Connect a MySQL database to an app",
        "description": "Changes which app gets a MySQL database. app null makes it the whole project's. One app has at most one database. Running servers get the change when they restart or are deployed again.",
        "tags": [
          "database"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The MySQL database name"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "bind_mysql_database",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "app": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "An app name, or null for the whole project"
                  }
                },
                "required": [
                  "app"
                ]
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete_mysql_database",
        "summary": "Delete a MySQL database",
        "description": "Deletes a MySQL database with its login and every backup. This cannot be undone: use it only when the user clearly asked, and put the database name exactly in confirm. The app that got it no longer gets MYSQL_* variables from its next start. Only owners and admins can do this.",
        "tags": [
          "database"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The MySQL database name"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "name": {},
                    "deleted": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "delete_mysql_database",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "confirm": {
                    "type": "string",
                    "description": "The MySQL database name. It must be exactly the same as name."
                  }
                },
                "required": [
                  "confirm"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/mysql/{name}/connection": {
      "get": {
        "operationId": "get_mysql_connection",
        "summary": "MySQL connection",
        "description": "Returns a MySQL database's address, port, database name, login, password and the variables its app gets (variables). The address is reachable only from apps on this server. The password is shown to a write token only.",
        "tags": [
          "database"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The MySQL database name"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "name": {},
                    "host": {},
                    "port": {},
                    "database": {},
                    "user": {},
                    "password": {},
                    "url": {},
                    "variables": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-permissions": [
          "secrets.read (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "get_mysql_connection"
      }
    },
    "/projects/{ref}/mysql/{name}/backups": {
      "get": {
        "operationId": "list_mysql_backups",
        "summary": "List MySQL backups",
        "description": "Returns a MySQL database's backups (nightly, made by hand, and taken just before a restore) and its restores.",
        "tags": [
          "database"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The MySQL database name"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "name": {},
                    "backups": {},
                    "restores": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_mysql_backups"
      },
      "post": {
        "operationId": "create_mysql_backup",
        "summary": "Back up MySQL now",
        "description": "Backs up a MySQL database now. Make one before updating plugins or changing a lot at once. Kept for 7 days. The nightly backup happens on its own as well.",
        "tags": [
          "database"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The MySQL database name"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "name": {},
                    "id": {},
                    "status": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "create_mysql_backup"
      }
    },
    "/projects/{ref}/mysql/{name}/restore": {
      "post": {
        "operationId": "restore_mysql_backup",
        "summary": "Restore MySQL from a backup",
        "description": "Puts a MySQL database back to when a backup was taken. Every change since is lost, so use it only when the user clearly asked, and put the database name exactly in confirm. The state just before is backed up first, so undo_backup_id restores it again. Only owners and admins can do this.",
        "tags": [
          "database"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The MySQL database name"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "name": {},
                    "restore_id": {},
                    "status": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "restore_mysql_backup",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "backup_id": {
                    "type": "string",
                    "description": "A backup id from list_mysql_backups"
                  },
                  "confirm": {
                    "type": "string",
                    "description": "The MySQL database name. It must be exactly the same as name."
                  }
                },
                "required": [
                  "backup_id",
                  "confirm"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/concurrent-builds": {
      "get": {
        "operationId": "get_concurrent_builds",
        "summary": "Concurrent builds",
        "description": "How many of this project's builds may run at once. null means as many as the builders allow.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "concurrent_builds": {},
                    "max": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_concurrent_builds"
      },
      "put": {
        "operationId": "set_concurrent_builds",
        "summary": "Change concurrent builds",
        "description": "Sets how many of this project's builds may run at once, 1 to 20, or null for no limit. Builds over the limit wait in the queue and start when one ahead of them finishes; a waiting build is not billed for build minutes. Only owners and admins can do this.",
        "tags": [
          "deployments"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "concurrent_builds": {},
                    "max": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "set_concurrent_builds",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "concurrent_builds": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "minimum": 1,
                    "maximum": 20,
                    "description": "A whole number from 1 to 20, or null for no limit."
                  }
                },
                "required": [
                  "concurrent_builds"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/network": {
      "get": {
        "operationId": "get_projects_ref_network",
        "summary": "Network addresses",
        "description": "The addresses the project receives requests on (inbound: a custom domain's A record) and, for a project with the static outbound IP turned on, the static addresses it sends from (outbound.addresses). For a project without it the outbound address is shared and not static, so it is not returned. Do not put it on an allow list.",
        "tags": [
          "network"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "region": {},
                    "inbound": {},
                    "outbound": {},
                    "static_outbound_ip": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_network"
      }
    },
    "/projects/{ref}/network/ips": {
      "get": {
        "operationId": "get_projects_ref_network_ips",
        "summary": "Network addresses",
        "description": "The addresses the project receives requests on (inbound: a custom domain's A record) and, for a project with the static outbound IP turned on, the static addresses it sends from (outbound.addresses). For a project without it the outbound address is shared and not static, so it is not returned. Do not put it on an allow list.",
        "tags": [
          "network"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "region": {},
                    "inbound": {},
                    "outbound": {},
                    "static_outbound_ip": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_network"
      }
    },
    "/projects/{ref}/network/static-outbound-ip": {
      "post": {
        "operationId": "post_projects_ref_network_static_outbound_ip",
        "summary": "Static outbound IP",
        "description": "Turns the static outbound IP, a paid add-on, on or off. When on, server deployments, functions' fetch() and database webhooks leave from a static address, and a monthly price is billed for the time it is on. Pro plan and above; only owners, admins and billing members can do it. It costs money, so use it only when the user clearly asks. The price and the current state are in get_network. In a region whose address does not exist yet the outcome is provisioning: the address is being made (usually under an hour), and until it is ready nothing is billed and no address is returned.",
        "tags": [
          "network"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "active": {},
                    "status": {},
                    "outcome": {},
                    "addresses": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "billing.manage (owner or admin or billing)"
        ],
        "x-oneend-mcp-tool": "set_static_outbound_ip"
      },
      "delete": {
        "operationId": "delete_projects_ref_network_static_outbound_ip",
        "summary": "Static outbound IP",
        "description": "Turns the static outbound IP, a paid add-on, on or off. When on, server deployments, functions' fetch() and database webhooks leave from a static address, and a monthly price is billed for the time it is on. Pro plan and above; only owners, admins and billing members can do it. It costs money, so use it only when the user clearly asks. The price and the current state are in get_network. In a region whose address does not exist yet the outcome is provisioning: the address is being made (usually under an hour), and until it is ready nothing is billed and no address is returned.",
        "tags": [
          "network"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "active": {},
                    "status": {},
                    "outcome": {},
                    "addresses": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "billing.manage (owner or admin or billing)"
        ],
        "x-oneend-mcp-tool": "set_static_outbound_ip"
      }
    },
    "/projects/{ref}/team": {
      "get": {
        "operationId": "list_team",
        "summary": "Team members",
        "description": "The members of the organisation that owns this project, with their roles, whether they use two-step verification, and invitations not accepted yet.",
        "tags": [
          "team"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "mfa_required": {},
                    "members": {},
                    "invitations": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_team"
      }
    },
    "/projects/{ref}/team/invitations": {
      "post": {
        "operationId": "invite_member",
        "summary": "Invite a member",
        "description": "Sends an invitation link by email. A person joins by opening the link, so nobody is added straight away. For an address that is already a member, only the role changes. Only owners and admins can do this.",
        "tags": [
          "team"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "id": {},
                    "email": {},
                    "role": {},
                    "outcome": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "team.manage (owner or admin)"
        ],
        "x-oneend-mcp-tool": "invite_member",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "description": "The email address to invite."
                  },
                  "role": {
                    "type": "string",
                    "enum": [
                      "admin",
                      "developer",
                      "billing",
                      "viewer"
                    ],
                    "description": "Empty means developer."
                  }
                },
                "required": [
                  "email"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/team/invitations/{id}": {
      "delete": {
        "operationId": "cancel_invitation",
        "summary": "Cancel an invitation",
        "description": "Cancels a sent invitation. Its link stops opening at once. id is in the invitations of list_team.",
        "tags": [
          "team"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The invitation id from list_team."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "id": {},
                    "cancelled": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "team.manage (owner or admin)"
        ],
        "x-oneend-mcp-tool": "cancel_invitation"
      }
    },
    "/projects/{ref}/team/members/{email}": {
      "patch": {
        "operationId": "set_member_role",
        "summary": "Change a member's role",
        "description": "Changes the role of someone who is already a member. The owner's role cannot be changed. Only owners and admins can do this.",
        "tags": [
          "team"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "email",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The member's email address."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "email": {},
                    "role": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "team.manage (owner or admin)"
        ],
        "x-oneend-mcp-tool": "set_member_role",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "role": {
                    "type": "string",
                    "enum": [
                      "admin",
                      "developer",
                      "billing",
                      "viewer"
                    ],
                    "description": "The new role."
                  }
                },
                "required": [
                  "role"
                ]
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "remove_member",
        "summary": "Remove a member",
        "description": "Removes someone from the organisation. The owner cannot be removed. Only owners and admins can do this.",
        "tags": [
          "team"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "email",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The member's email address."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "email": {},
                    "removed": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "team.manage (owner or admin)"
        ],
        "x-oneend-mcp-tool": "remove_member"
      }
    },
    "/projects/{ref}/team/mfa": {
      "put": {
        "operationId": "set_mfa_required",
        "summary": "Require two-step verification",
        "description": "Requires two-step verification from every member of the organisation, or stops requiring it. To turn it on, this token's owner must have two-step verification on first. Members without it cannot open this organisation until they turn it on, and are listed in without_mfa in the response. Only owners and admins can do this.",
        "tags": [
          "team"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "mfa_required": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "team.manage (owner or admin)"
        ],
        "x-oneend-mcp-tool": "set_mfa_required",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "required": {
                    "type": "boolean",
                    "description": "true to require it, false to stop requiring it."
                  }
                },
                "required": [
                  "required"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/channels": {
      "get": {
        "operationId": "list_channels",
        "summary": "Notification channels",
        "description": "The Slack, KakaoWork and webhook channels that receive news about deployments, domains, usage and billing, with the result of the last delivery. Organisation wide. A webhook channel's signing key (signing_secret) is shown once, when the channel is created (create_channel); the list carries only signing_secret_set and its last four characters (signing_secret_last4).",
        "tags": [
          "team"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "notices": {},
                    "channels": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_channels"
      },
      "post": {
        "operationId": "create_channel",
        "summary": "Add a notification channel",
        "description": "Sends notifications to Slack (an Incoming Webhook address), KakaoWork (a bot webhook address), a signed webhook, or email (1 to 10 addresses in emails). An email channel mails each address a confirmation link and sends notifications only to addresses that opened it. Leave notices empty to receive every kind (usage covers limit warnings and traffic spike alerts). The signing_secret of a webhook channel is in this answer only, so save it on the receiving side right away. Check it with test_channel after creating it. Only owners and admins can do this.",
        "tags": [
          "team"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "id": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "team.manage (owner or admin)"
        ],
        "x-oneend-mcp-tool": "create_channel",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "kind": {
                    "type": "string",
                    "enum": [
                      "slack",
                      "kakaowork",
                      "webhook",
                      "email"
                    ],
                    "description": "slack, kakaowork, webhook or email."
                  },
                  "name": {
                    "type": "string",
                    "description": "A name to recognise the channel by."
                  },
                  "url": {
                    "type": "string",
                    "description": "The webhook address to send to. Not used by an email channel."
                  },
                  "emails": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "maxItems": 10,
                    "description": "For an email channel, the addresses to send to, e.g. [\"ops@example.com\"]."
                  },
                  "notices": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "deployments",
                        "domains",
                        "usage",
                        "billing"
                      ]
                    },
                    "description": "Which kinds to receive: deployments, domains, usage, billing. Empty means all."
                  }
                },
                "required": [
                  "kind",
                  "name"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/channels/{id}/test": {
      "post": {
        "operationId": "test_channel",
        "summary": "Test a notification channel",
        "description": "Sends a test message to that one channel only. For an email channel it goes to confirmed addresses only, and addresses still waiting are sent the confirmation again. Only owners and admins can do this.",
        "tags": [
          "team"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The id from list_channels."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "id": {},
                    "sent": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "team.manage (owner or admin)"
        ],
        "x-oneend-mcp-tool": "test_channel"
      }
    },
    "/projects/{ref}/channels/{id}": {
      "patch": {
        "operationId": "set_channel_enabled",
        "summary": "Turn a notification channel off or on",
        "description": "Stops or resumes notifications and keeps the settings. Only owners and admins can do this.",
        "tags": [
          "team"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The id from list_channels."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "id": {},
                    "enabled": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "team.manage (owner or admin)"
        ],
        "x-oneend-mcp-tool": "set_channel_enabled",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean",
                    "description": "true to send, false to stop."
                  }
                },
                "required": [
                  "enabled"
                ]
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "remove_channel",
        "summary": "Remove a notification channel",
        "description": "Removes a notification channel. Only owners and admins can do this.",
        "tags": [
          "team"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The id from list_channels."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "id": {},
                    "removed": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "team.manage (owner or admin)"
        ],
        "x-oneend-mcp-tool": "remove_channel"
      }
    },
    "/projects/{ref}/extensions": {
      "get": {
        "operationId": "list_extensions",
        "summary": "Database extensions",
        "description": "The PostgreSQL extensions you can turn on (vector from pgvector, postgis, citext, pgcrypto and others), and for each whether this server has it (available), whether it is on (enabled), and its version. Extensions are installed in the extensions schema and used in SQL just as vector(1536) or geometry.",
        "tags": [
          "database"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "extensions": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_extensions"
      }
    },
    "/projects/{ref}/extensions/{name}": {
      "put": {
        "operationId": "enable_extension",
        "summary": "Turn on a database extension",
        "description": "Turns on one extension (create extension ... with schema extensions). vector for embedding search, postgis for maps and distances. Extensions not on the list are refused. Only owners and admins can do this.",
        "tags": [
          "database"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The extension name: vector, postgis, citext, hstore, uuid-ossp, pgcrypto, ltree, fuzzystrmatch, btree_gin, btree_gist, intarray, tablefunc"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "extension": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "enable_extension"
      },
      "delete": {
        "operationId": "disable_extension",
        "summary": "Turn off a database extension",
        "description": "Turns off one extension. Refused while columns, indexes or functions that use it remain. If another project on the same database uses it, it stays installed and only this project's record is removed (note). pg_trgm and unaccent are built in and cannot be turned off. Put the extension name exactly in confirm. Only owners and admins can do this.",
        "tags": [
          "database"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The extension name, as in list_extensions."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "extension": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "disable_extension",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "confirm": {
                    "type": "string",
                    "description": "The extension name. It must be exactly the same as name."
                  }
                },
                "required": [
                  "confirm"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/branches": {
      "get": {
        "operationId": "list_branches",
        "summary": "Database branches",
        "description": "This project's database branches: name, the branch's own project ref (use it with every other tool), the git branch it is wired to, status (creating, ready, merging, resetting, failed, deleting), size and when it expires. Also returns the automatic branching settings.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "automatic": {},
                    "lifetime_days": {},
                    "has_seed": {},
                    "branches": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_branches"
      },
      "post": {
        "operationId": "create_branch",
        "summary": "Create a database branch",
        "description": "Makes a preview database from the project's schema: the project's migrations (the history apply_migrations records) are replayed in order and the seed is run. Rows are copied only with with_data. A branch is a project with a ref of its own; use that ref with run_sql, get_project_keys and every other tool. With git_branch, that branch's preview deployments use this database. Available from the Pro plan.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "branch": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "create_branch",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "The branch name (lower-case letters, digits and -, up to 30). Made from git_branch when absent."
                  },
                  "git_branch": {
                    "type": "string",
                    "description": "The git branch to wire it to. That branch's preview deployments get this database's address, keys and connection string."
                  },
                  "with_seed": {
                    "type": "boolean",
                    "description": "false to skip the seed."
                  },
                  "with_data": {
                    "type": "boolean",
                    "description": "true to copy the project's rows too, instead of replaying the migrations and running the seed. Files and their rows are not copied. Refused when the data is past 512MB. Progress is under copy in list_branches."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/branching": {
      "put": {
        "operationId": "set_branching",
        "summary": "Automatic database branches",
        "description": "Whether a database branch is made automatically for every git branch deployed as a preview, the seed SQL every branch gets, and how many days an unused branch is kept (1 to 90, extended by every deployment). Only owners and admins can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "automatic": {},
                    "lifetime_days": {},
                    "has_seed": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "set_branching",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "automatic": {
                    "type": "boolean",
                    "description": "true to make one for every preview branch."
                  },
                  "seed_sql": {
                    "type": "string",
                    "description": "SQL run in every new branch after the migrations (up to 1MB). An empty string removes it."
                  },
                  "lifetime_days": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 90,
                    "description": "How many days a branch is kept after its last deployment."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/branches/{name}/merge": {
      "post": {
        "operationId": "merge_branch",
        "summary": "Merge a database branch",
        "description": "Applies the migrations only the branch has to the project (production), in version order, each in a transaction of its own; stops at the first failure, rolling back only that one. Rows do not move. Change the schema in a branch with apply_migrations, not run_sql, for it to be merged.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The branch name (name in list_branches)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "422": {
            "$ref": "#/components/responses/E422"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "merge_branch"
      }
    },
    "/projects/{ref}/branches/{name}/reset": {
      "post": {
        "operationId": "reset_branch",
        "summary": "Reset a database branch",
        "description": "Drops the branch's database and makes it again from the project's migrations and seed. All the branch's rows and users are lost and no backup is kept. Put the branch name exactly in confirm.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The branch name."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "branch": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "reset_branch",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "confirm": {
                    "type": "string",
                    "description": "The branch name. It must be exactly the same as name."
                  }
                },
                "required": [
                  "confirm"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/branches/{name}": {
      "delete": {
        "operationId": "delete_branch",
        "summary": "Delete a database branch",
        "description": "Deletes the branch with its database and keys. It cannot be undone, so put the branch name exactly in confirm. Deleting the git branch or closing its pull request deletes it automatically.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The branch name."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "branch": {},
                    "deleted": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "delete_branch",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "confirm": {
                    "type": "string",
                    "description": "The branch name. It must be exactly the same as name."
                  }
                },
                "required": [
                  "confirm"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/queues": {
      "get": {
        "operationId": "list_queues",
        "summary": "Queues",
        "description": "The queues (the same SQL functions as pgmq: pgmq.send, pgmq.read, pgmq.pop, pgmq.archive, pgmq.delete), with how many messages each holds, how many can be read now, how many are archived and the age of the oldest. enabled says whether pgmq is installed, exposed whether the data API (pgmq_public) can call it.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_queues"
      },
      "post": {
        "operationId": "create_queue",
        "summary": "Create a queue",
        "description": "Makes one queue (pgmq.create), installing pgmq the first time. Messages are kept in the table pgmq.q_<name>; in SQL, put one in with pgmq.send(name, message) and read with pgmq.read(name, seconds, count). Only in a database of its own.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "create_queue",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "The queue name (lower-case letters, digits and _, up to 47)."
                  },
                  "unlogged": {
                    "type": "boolean",
                    "description": "true for a faster table that writes no WAL (messages are lost if the server stops abnormally)."
                  }
                },
                "required": [
                  "name"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/queues/metrics": {
      "get": {
        "operationId": "get_queue_metrics",
        "summary": "Queue metrics",
        "description": "From the queue samples taken every five minutes: each queue's current depth, ready messages, oldest wait and archived count, and across all queues the depth, messages sent and messages processed over time. 24 hours by default, up to 168.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "hours",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 168,
              "description": "How many hours. 24 by default."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "hours": {},
                    "queues": {},
                    "points": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_queue_metrics"
      }
    },
    "/projects/{ref}/queues/api": {
      "put": {
        "operationId": "set_queues_api",
        "summary": "Open queues to the data API",
        "description": "true makes the pgmq_public schema (send, send_batch, read, pop, archive, delete) so the data API can call it as supabase.schema(\"pgmq_public\").rpc(\"send\", ...). It runs as the caller, so for the publishable key or signed-in users to use it, grant privileges and write access rules on the queue tables. Only owners and admins can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "set_queues_api",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "exposed": {
                    "type": "boolean",
                    "description": "true to open, false to close."
                  }
                },
                "required": [
                  "exposed"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/queues/{name}": {
      "delete": {
        "operationId": "delete_queue",
        "summary": "Delete a queue",
        "description": "Deletes a queue with its messages and archive (pgmq.drop_queue). It cannot be undone, so put the queue name exactly in confirm.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The queue name."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "queue": {},
                    "dropped": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "delete_queue",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "confirm": {
                    "type": "string",
                    "description": "The queue name. It must be exactly the same as name."
                  }
                },
                "required": [
                  "confirm"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/queues/{name}/purge": {
      "post": {
        "operationId": "purge_queue",
        "summary": "Empty a queue",
        "description": "Deletes all of a queue's messages (pgmq.purge_queue). The archive is kept. It cannot be undone, so put the queue name exactly in confirm.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The queue name."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "queue": {},
                    "purged": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "purge_queue",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "confirm": {
                    "type": "string",
                    "description": "The queue name. It must be exactly the same as name."
                  }
                },
                "required": [
                  "confirm"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/queues/{name}/messages": {
      "post": {
        "operationId": "send_queue_message",
        "summary": "Send a message to a queue",
        "description": "Puts one JSON message on a queue (pgmq.send). It cannot be read for delay seconds.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The queue name."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "queue": {},
                    "msg_id": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "send_queue_message",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "message": {
                    "description": "The message. Any JSON value."
                  },
                  "delay": {
                    "type": "integer",
                    "minimum": 0,
                    "description": "Seconds before it can be read."
                  }
                },
                "required": [
                  "message"
                ]
              }
            }
          }
        }
      },
      "get": {
        "operationId": "peek_queue",
        "summary": "Look at queue messages",
        "description": "Shows the messages at the front of a queue without taking them. Neither the read count nor the visibility time changes, so it never takes a message a worker was about to get.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The queue name."
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "description": "How many messages to show (20 by default)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "queue": {},
                    "messages": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "peek_queue"
      }
    },
    "/projects/{ref}/vault": {
      "get": {
        "operationId": "list_vault_secrets",
        "summary": "Vault secrets",
        "description": "The names and descriptions of the secrets in Vault. Values are never returned. The project's code reads one with the secret key: select decrypted_secret from vault.decrypted_secrets where name = ...",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "enabled": {},
                    "secrets": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-permissions": [
          "secrets.read (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "list_vault_secrets"
      },
      "post": {
        "operationId": "create_vault_secret",
        "summary": "Store a Vault secret",
        "description": "Encrypts one secret and stores it in vault.secrets in the project's database (vault.create_secret). The platform holds the key and it is never stored in the database, so dumps and backups hold only ciphertext. Turns Vault on the first time. Only owners and admins can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "secret": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "create_vault_secret",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "The secret name (starts with a letter or _, up to 128)."
                  },
                  "value": {
                    "type": "string",
                    "description": "The value to store (up to 64KB). It is not shown again."
                  },
                  "description": {
                    "type": "string",
                    "description": "A description (up to 500 characters)."
                  }
                },
                "required": [
                  "name",
                  "value"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/vault/{name}": {
      "patch": {
        "operationId": "update_vault_secret",
        "summary": "Change a Vault secret",
        "description": "Changes a secret's value or description (vault.update_secret). Only owners and admins can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The secret name."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "secret": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "update_vault_secret",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "value": {
                    "type": "string",
                    "description": "The new value."
                  },
                  "description": {
                    "type": "string",
                    "description": "The new description."
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete_vault_secret",
        "summary": "Delete a Vault secret",
        "description": "Deletes one secret. Only owners and admins can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The secret name."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "name": {},
                    "deleted": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "delete_vault_secret"
      }
    },
    "/projects/{ref}/database/move": {
      "get": {
        "operationId": "get_database_move",
        "summary": "Move to a dedicated database: status",
        "description": "Whether this project is on a dedicated database (dedicated), whether its plan includes one (plan_allows), and whether a move was requested, is under way or failed and stopped (stopped, last_error). When size_bytes is above auto_move_max_bytes the project is not moved automatically; request it with move_to_dedicated_database.",
        "tags": [
          "database"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_database_move"
      },
      "post": {
        "operationId": "move_to_dedicated_database",
        "summary": "Move to a dedicated database",
        "description": "Requests the move of a project on the shared database to a database of its own, as the console's \"Move now\" does. It moves when its turn comes; writes pause during the move and reads carry on. The project as it was just before is kept as a backup, and if the move fails the project stays where it was (a stopped move is tried again when requested again). Needed for Vault and for large databases. Included from the Pro plan. Only owners and admins can do this.",
        "tags": [
          "database"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "402": {
            "$ref": "#/components/responses/E402"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "move_to_dedicated_database"
      }
    },
    "/projects/{ref}/database/dedicated-disk": {
      "get": {
        "operationId": "get_dedicated_disk",
        "summary": "Dedicated disk",
        "description": "The disk and Postgres of this project's own, used once its database has grown: its size (size_gb), what is used, the monthly cost, 30 days of history, a request in progress and the suggestion to make it smaller (shrink). While the project is on the shared disk, the size that moves it (threshold_gb) and the database's size now.",
        "tags": [
          "database"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_dedicated_disk"
      },
      "post": {
        "operationId": "request_dedicated_disk",
        "summary": "Move to a dedicated disk",
        "description": "Requests the move of this project's database to a disk of its own (max(1.2 x the database, 20 GB)), as the console's \"Move to a dedicated disk\" does. The disk is billed on its provisioned size at KRW 1,200 (75 cents) per GB a month, and while it moves writes fail and reads work (expected_downtime_seconds in get_dedicated_disk). Enterprise may ask at any time; other paid plans once past the threshold. Only owners and admins can do this.",
        "tags": [
          "database"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "402": {
            "$ref": "#/components/responses/E402"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "request_dedicated_disk"
      }
    },
    "/projects/{ref}/database/dedicated-disk/shrink": {
      "post": {
        "operationId": "shrink_dedicated_disk",
        "summary": "Make the disk smaller",
        "description": "Makes the dedicated disk smaller: a new, smaller disk (1.2 x the database, at least 20 GB) is made, the data moves onto it and the old disk is deleted. Only a disk under 25% used for 7 days can be made smaller (shrink.suggested in get_dedicated_disk). While it moves writes fail and reads work. It is never made smaller on its own. Only owners and admins can do this.",
        "tags": [
          "database"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "402": {
            "$ref": "#/components/responses/E402"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "shrink_dedicated_disk"
      }
    },
    "/projects/{ref}/network-restrictions": {
      "get": {
        "operationId": "get_network_restrictions",
        "summary": "Database network restrictions",
        "description": "The addresses that may connect to the database directly (5432 and 6543) and whether TLS is required. restricted false means every address may connect. your_address_allowed says whether the address this request came from is allowed.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_network_restrictions"
      },
      "put": {
        "operationId": "update_network_restrictions",
        "summary": "Change database network restrictions",
        "description": "Changes the addresses allowed to connect directly (a list of CIDRs, up to 100) and whether TLS is required. allow_all allows every address again. Refused without confirm when the address this request came from is not on the list. The console, the API and run_sql do not go through the pooler, so a restriction can always be undone. Only owners and admins can do this.",
        "tags": [
          "other"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "update_network_restrictions",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "allowed_cidrs": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Addresses or CIDRs to allow (for example 203.0.113.0/24). An empty array lifts the restriction."
                  },
                  "allow_all": {
                    "type": "boolean",
                    "description": "true to lift the restriction and allow every address."
                  },
                  "enforce_ssl": {
                    "type": "boolean",
                    "description": "true to accept only TLS connections (sslmode=require). The default is true."
                  },
                  "confirm": {
                    "type": "boolean",
                    "description": "Saves even when the address this request came from is not on the list."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/realtime": {
      "get": {
        "operationId": "list_realtime_tables",
        "summary": "Tables with realtime on",
        "description": "The tables whose changes are sent in real time. Subscribing to a table not listed here receives nothing.",
        "tags": [
          "database"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "tables": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "list_realtime_tables"
      }
    },
    "/projects/{ref}/realtime/{table}": {
      "put": {
        "operationId": "set_realtime",
        "summary": "Turn realtime on or off for a table",
        "description": "Turns change notifications for one table on or off. Notifications also go only for rows that pass the access rules.",
        "tags": [
          "database"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "table",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The table name."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "tables": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "data.write (owner or admin or developer)"
        ],
        "x-oneend-mcp-tool": "set_realtime",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean",
                    "description": "true to turn it on, false to turn it off."
                  }
                },
                "required": [
                  "enabled"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/metrics": {
      "get": {
        "operationId": "get_metrics",
        "summary": "Metrics",
        "description": "Returns requests, failures and latency (p50/p95/p99) by surface and by time, and the database size, connections and cache hit rate.",
        "tags": [
          "logs"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "range",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "1h",
                "24h",
                "7d"
              ],
              "description": "Empty means 24h."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "range": {},
                    "requests": {},
                    "failures": {},
                    "latency_ms": {},
                    "by_surface": {},
                    "points": {},
                    "database": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_metrics"
      }
    },
    "/projects/{ref}/billing/plan": {
      "get": {
        "operationId": "get_plan",
        "summary": "Plan",
        "description": "The organisation's current plan, any scheduled change, the plans it can choose and their monthly prices, and the paid add-ons running in the organisation (addons). On the Free plan, free holds its limits (one person, no custom domains, deployments a day, paused after 3 unused days, build minutes and traffic) and what is Pro's. Each add-on is turned on and off with its own tool (set_static_outbound_ip). Changing the plan needs a payment, so it is done only on the console's billing page. Only owners, admins and billing members can see it.",
        "tags": [
          "billing"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "currency": {},
                    "plan": {},
                    "scheduled": {},
                    "options": {},
                    "billed_by": {},
                    "addons": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-permissions": [
          "billing.manage (owner or admin or billing)"
        ],
        "x-oneend-mcp-tool": "get_plan"
      }
    },
    "/projects/{ref}/billing/spend": {
      "get": {
        "operationId": "get_spend_controls",
        "summary": "Spend controls",
        "description": "The spend cap (on: usage stops at what the plan includes and no overage is charged), the monthly overage limit and its alert webhook, and this month's usage. Only owners, admins and billing members can see it.",
        "tags": [
          "billing"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "spend_cap": {},
                    "spend_cap_applies": {},
                    "spend_limit_minor": {},
                    "spend_limit_floor_minor": {},
                    "webhook_url": {},
                    "progress": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-permissions": [
          "billing.manage (owner or admin or billing)"
        ],
        "x-oneend-mcp-tool": "get_spend_controls"
      }
    },
    "/projects/{ref}/billing/spend-cap": {
      "put": {
        "operationId": "set_spend_cap",
        "summary": "Turn the spend cap on or off",
        "description": "Turns the spend cap of a paid plan on or off. On, usage stops at what is included and there is no overage (the console spend limit's \"Allowances only\"). Off, what goes over is billed, so turning it off takes the project name (name from list_projects) exactly in confirm. Only owners, admins and billing members can do this.",
        "tags": [
          "billing"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "spend_cap": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "billing.manage (owner or admin or billing)"
        ],
        "x-oneend-mcp-tool": "set_spend_cap",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean",
                    "description": "true turns it on."
                  },
                  "confirm": {
                    "type": "string",
                    "description": "Only when turning it off (enabled: false): the project name. It must be exactly the same as name in list_projects."
                  }
                },
                "required": [
                  "enabled"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/billing/spend-limit": {
      "put": {
        "operationId": "set_spend_limit",
        "summary": "Monthly spend limit",
        "description": "Sets the limit on a month's overage (in the currency's smallest unit, won) and the webhook address to alert as it is approached. With the spend cap off, this is the console spend limit's \"Allow overage up to an amount\" (null: \"No limit\"). spend_limit_minor null removes the limit. Leave webhook_url out to keep the current address. New alert addresses are better added as notification channels (create_channel). Only owners, admins and billing members can do this.",
        "tags": [
          "billing"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "spend_cap": {},
                    "spend_cap_applies": {},
                    "spend_limit_minor": {},
                    "spend_limit_floor_minor": {},
                    "webhook_url": {},
                    "progress": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "billing.manage (owner or admin or billing)"
        ],
        "x-oneend-mcp-tool": "set_spend_limit",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "spend_limit_minor": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "minimum": 0,
                    "description": "The limit. null for none."
                  },
                  "webhook_url": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "The https address to alert. An empty string removes it."
                  }
                },
                "required": [
                  "spend_limit_minor"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/billing": {
      "get": {
        "operationId": "get_billing",
        "summary": "Bill and usage",
        "description": "One month's bill (usage, included amount and charge per item) and usage by day. Empty period means this month (UTC). Amounts are in the smallest unit of currency (KRW: won, USD: cents). included is what the plans held this month allow, split by the days on each; list_included is the Pro allowance. amount_minor and total_minor are what is charged; list_amount_minor and list_total_minor are the list price. An organisation with billing_exempt true (the operator's own) is charged 0 and is never stopped for payment; its list price is the Pro rate card. Cards and payment history are only in the console. Only owners, admins and billing members can see it.",
        "tags": [
          "billing"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "period",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "YYYY-MM"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "period": {},
                    "plan": {},
                    "period_start": {},
                    "period_end": {},
                    "currency": {},
                    "list_total_minor": {},
                    "billing_exempt": {},
                    "lines": {},
                    "usage": {},
                    "months": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-permissions": [
          "billing.manage (owner or admin or billing)"
        ],
        "x-oneend-mcp-tool": "get_billing"
      }
    },
    "/projects/{ref}/audit": {
      "get": {
        "operationId": "get_audit_log",
        "summary": "Audit log",
        "description": "tab=activity is who changed what in the organisation; tab=access is who accessed personal data. Newest first, up to 200 at a time; when has_more is true, call again with a higher offset. from and to are YYYY-MM-DD (dates in Korea). Only owners and admins can do this.",
        "tags": [
          "logs"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "tab",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "activity",
                "access"
              ],
              "description": "activity for changes, access for access to personal data."
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "The first date, YYYY-MM-DD."
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "The last date, YYYY-MM-DD."
            }
          },
          {
            "name": "actor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Part of an email address."
            }
          },
          {
            "name": "action",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Actions starting with these words. For example: member."
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "description": "How many entries to get, up to 200."
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "description": "How many entries to skip."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "tab": {},
                    "total": {},
                    "has_more": {},
                    "records": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-permissions": [
          "audit.read (owner or admin)"
        ],
        "x-oneend-mcp-tool": "get_audit_log"
      }
    },
    "/projects/{ref}/signing": {
      "get": {
        "operationId": "get_jwt_signing",
        "summary": "Token signing",
        "description": "Shows whether sign-in tokens are signed with HS256 or ES256, and the old keys still accepted for now (keys in their grace period).",
        "tags": [
          "keys"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "alg": {},
                    "keys": {},
                    "grace_hours": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "read",
        "x-oneend-mcp-tool": "get_jwt_signing"
      },
      "put": {
        "operationId": "set_jwt_signing",
        "summary": "Change token signing",
        "description": "With ES256, new sign-ins are signed with an asymmetric key and other servers can check tokens with the public keys (JWKS). Tokens already issued keep working until they expire. Only owners and admins can do this.",
        "tags": [
          "keys"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "alg": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "set_jwt_signing",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "alg": {
                    "type": "string",
                    "enum": [
                      "HS256",
                      "ES256"
                    ],
                    "description": "HS256 or ES256."
                  }
                },
                "required": [
                  "alg"
                ]
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/signing/rotate": {
      "post": {
        "operationId": "rotate_signing_key",
        "summary": "Rotate the key",
        "description": "Creates a new key for signing the publishable and secret keys. The old key is still accepted for grace_hours (0, 1, 24, 168); 0 (or empty) makes it invalid at once (when it leaked). With 0 every app using it stops within 30 seconds, so put the project name (name from list_projects) exactly in confirm. Every key put in an app has to be replaced, so use this only when the user clearly asks. Only owners and admins can do this.",
        "tags": [
          "keys"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "key_version": {},
                    "grace_hours": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "rotate_signing_key",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "grace_hours": {
                    "type": "integer",
                    "enum": [
                      0,
                      1,
                      24,
                      168
                    ],
                    "description": "How many hours the old key is still accepted: 0, 1, 24 or 168."
                  },
                  "confirm": {
                    "type": "string",
                    "description": "Only when grace_hours is 0 or empty: the project name. It must be exactly the same as name in list_projects."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/signing/keys/{kid}": {
      "delete": {
        "operationId": "retire_signing_key",
        "summary": "Retire an old key",
        "description": "Ends an old key in its grace period now. kid is one in the keys of get_jwt_signing whose state is rotating. Only owners and admins can do this.",
        "tags": [
          "keys"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "kid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The kid from get_jwt_signing."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ref": {},
                    "kid": {},
                    "retired": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "retire_signing_key"
      }
    },
    "/projects/{ref}/domains/{hostname}/certificate": {
      "put": {
        "operationId": "upload_certificate",
        "summary": "Upload a certificate",
        "description": "Uses your own TLS certificate for a connected domain. certificate is the PEM chain (the server certificate first), key is the PEM private key. The domain name must be in the certificate. Takes effect within 1 minute. Only owners and admins can do this.",
        "tags": [
          "domains"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "hostname",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The connected domain."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "upload_certificate",
        "x-oneend-max-body-bytes": 262144,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "certificate": {
                    "type": "string",
                    "description": "The PEM certificate chain, the server certificate first."
                  },
                  "key": {
                    "type": "string",
                    "description": "The PEM private key."
                  }
                },
                "required": [
                  "certificate",
                  "key"
                ]
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "remove_certificate",
        "summary": "Remove an uploaded certificate",
        "description": "Removes the uploaded certificate and goes back to the automatically issued one. Only owners and admins can do this.",
        "tags": [
          "domains"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{20}$",
              "description": "The project identifier. Find it with list_projects."
            }
          },
          {
            "name": "hostname",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The connected domain."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is the result as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        },
        "x-oneend-scope": "write",
        "x-oneend-permissions": [
          "project.admin (owner or admin)"
        ],
        "x-oneend-mcp-tool": "remove_certificate"
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearer": {
        "type": "http",
        "scheme": "bearer",
        "description": "bwk_… personal access token, or an OAuth access token (ADR 0016)."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "message"
            ],
            "properties": {
              "message": {
                "type": "string"
              }
            }
          }
        }
      }
    },
    "responses": {
      "E400": {
        "description": "The request is not valid or the operation was refused. error.message says why.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "E401": {
        "description": "No token, or the token is not valid or has expired.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "E402": {
        "description": "402",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "E403": {
        "description": "The token lacks the scope (read/write) or the role, or the organisation requires two-factor authentication.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "E404": {
        "description": "The project or the target does not exist, or this token cannot see it.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "E409": {
        "description": "Not possible right now, for example while the project database is still being created.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "E413": {
        "description": "The body is larger than this route accepts.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "E422": {
        "description": "422",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "E429": {
        "description": "429",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "E500": {
        "description": "The server could not read back the result. Try again shortly.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "E502": {
        "description": "502",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    }
  }
}
