# HostBase Management API (llms-full) > HostBase is a Polish Supabase-compatible backend platform: every project gets its own Postgres 17, Auth, Storage, Realtime and Edge Functions, plus Workers (containers), Sites (frontend hosting), one-click Apps, transactional Email, an OpenAI-compatible AI Gateway and Feature Flags. Everything is controllable through a REST Management API, a CLI, an MCP server and typed SDKs. ## Conventions - Base URL: https://host.ulewicz.space/api/v1 - Auth: `Authorization: Bearer `. Token types: personal access token `hb_pat_...` (Account -> Access tokens) or OAuth 2.1 access token `hb_oat_...` (authorization code + PKCE S256; discovery at /.well-known/oauth-authorization-server; client registration POST /api/oauth/register). - Scoped tokens: scopes are `resource:action`; `write` implies `read`; `projects:delete` must be granted explicitly; `*` is full access. Tokens can be bound to one organization or project. A missing scope returns 403. - Requests/responses are JSON unless noted. Errors: `{"error":{"status":404,"message":"..."}}`. 401 = bad/expired/revoked token, 403 = scope/role/IP policy, 404 = not found or no access, 409 = exists/wrong state, 402 = plan limit, 503 = capacity. - Long operations (project creation, builds, backups, moves) return 202; poll the matching GET until status is final. - `{ref}` is the 20-character project reference returned by `GET /projects`. - Never log tokens, service_role keys or secrets. The API never returns secret values or database passwords. - Safety for agents: DELETE /projects/{ref}, POST /database/query and PITR restore are destructive; confirm with the user first. Scopes: *, orgs:read, projects:read, projects:write, projects:delete, keys:read, keys:write, db:read, db:write, functions:read, functions:deploy, secrets:read, secrets:write, workers:read, workers:write, branches:read, branches:write, backups:read, backups:write, infra:read, infra:write, email:read, email:write, ai:read, ai:write, sites:read, sites:write, sandboxes:read, sandboxes:write ## Example ```sh curl -H "Authorization: Bearer $HOSTBASE_TOKEN" https://host.ulewicz.space/api/v1/projects curl -X POST https://host.ulewicz.space/api/v1/projects/$REF/database/query -H "Authorization: Bearer $HOSTBASE_TOKEN" -H "Content-Type: application/json" -d '{"query":"select now()"}' ``` ## AI Gateway ### GET /projects/{ref}/ai-gateway Gateway status (operationId: getAiGateway) Scope: ai:read Success: 200 ### GET /projects/{ref}/ai-gateway/end-users Per end-user usage (x-hb-user header) (operationId: listAiEndUsers) Scope: ai:read Success: 200 ### DELETE /projects/{ref}/ai-gateway/evals Delete an eval set (operationId: deleteAiEvalSet) Scope: ai:write Query: id (Set id) Success: 200 ### GET /projects/{ref}/ai-gateway/evals Eval sets and recent runs (operationId: listAiEvals) Scope: ai:read Success: 200 ### POST /projects/{ref}/ai-gateway/evals Create or update an eval set (operationId: saveAiEvalSet) Scope: ai:write Body: {"name":"string"} Success: 201 ### GET /projects/{ref}/ai-gateway/evals/runs Eval runs (operationId: listAiEvalRuns) Scope: ai:read Success: 200 ### POST /projects/{ref}/ai-gateway/evals/runs Start an eval run in the background (operationId: startAiEvalRun) Scope: ai:write Body: {"set_id":"string","models":["string"]} Success: 202 ### DELETE /projects/{ref}/ai-gateway/evals/runs/{id} Delete a run (operationId: deleteAiEvalRun) Scope: ai:write Success: 200 ### GET /projects/{ref}/ai-gateway/evals/runs/{id} Eval run with results (operationId: getAiEvalRun) Scope: ai:read Success: 200 ### GET /projects/{ref}/ai-gateway/keys Gateway keys (hbai_...) (operationId: listAiKeys) Scope: ai:read Success: 200 ### POST /projects/{ref}/ai-gateway/keys Create a gateway key (secret shown once) (operationId: createAiKey) Scope: ai:write Body: {"name":"string"} Success: 201 ### DELETE /projects/{ref}/ai-gateway/keys/{id} Revoke a key (operationId: revokeAiKey) Scope: ai:write Success: 200 ### DELETE /projects/{ref}/ai-gateway/providers Delete a provider (operationId: deleteAiProvider) Scope: ai:write Query: id (Provider id) Success: 200 ### GET /projects/{ref}/ai-gateway/providers Upstream providers (BYOK) (operationId: listAiProviders) Scope: ai:read Success: 200 ### PUT /projects/{ref}/ai-gateway/providers Save a provider (key encrypted at rest) (operationId: saveAiProvider) Scope: ai:write Body: {"kind":"anthropic"} Success: 200 ### GET /projects/{ref}/ai-gateway/settings Cache TTL, PII redaction, budget, fallbacks (operationId: getAiGatewaySettings) Scope: ai:read Success: 200 ### PUT /projects/{ref}/ai-gateway/settings Update settings (operationId: setAiGatewaySettings) Scope: ai:write Body: {"pii":false,"cache_ttl_seconds":0,"retention_days":1,"log_bodies":false} Success: 200 ### GET /projects/{ref}/ai-gateway/usage Aggregated usage (operationId: getAiUsage) Scope: ai:read Query: range=24h|7d|30d (Time range) Success: 200 ## Apps ### GET /apps One-click app catalog (operationId: listAppCatalog) Scope: * Success: 200 ### GET /projects/{ref}/apps Installed apps (operationId: listApps) Scope: * Success: 200 ### POST /projects/{ref}/apps Install an app - First-login credentials are returned once. (operationId: installApp) Scope: * Body: {"app":"metabase"} Success: 202 ### DELETE /projects/{ref}/apps/{app} Remove an app and its data (operationId: removeApp) Scope: * Success: 200 ### GET /projects/{ref}/apps/{app} Get an installed app (operationId: getApp) Scope: * Success: 200 ### POST /projects/{ref}/apps/{app}/{action} Start, stop, restart or upgrade an app (operationId: appAction) Scope: * action: start | stop | restart | upgrade Body (optional): {"version":"string"} Success: 200 ### GET /projects/{ref}/apps/{app}/logs Runtime logs (operationId: getAppLogs) Scope: * Query: lines (Number of log lines (default 200)); q (Substring filter) Success: 200 ## Backups ### GET /projects/{ref}/backups List backups (operationId: listBackups) Scope: backups:read Success: 200 ### POST /projects/{ref}/backups Start a manual backup (operationId: createBackup) Scope: backups:read Success: 202 ### GET /projects/{ref}/backups/{id}/download Download a pg_dump file (operationId: downloadBackup) Scope: backups:read Success: 200 ### GET /projects/{ref}/pitr PITR status and restore window (operationId: getPitr) Scope: backups:read Success: 200 ### PUT /projects/{ref}/pitr Enable/disable PITR and set retention (operationId: setPitr) Scope: backups:write Body: {"enabled":false} Success: 200 ### POST /projects/{ref}/pitr/restore Restore to a point in time (operationId: restorePitr) Scope: backups:write Body: {"target_time":"string"} Success: 202 ## Billing ### GET /organizations/{slug}/costs Cost explorer (PLN net, per project, service and day) (operationId: getOrganizationCosts) Scope: orgs:read Query: period (YYYY-MM); project (Limit to one project ref); detail (1 = per-day detail) Success: 200 ### GET /organizations/{slug}/credits Prepaid credit balance, lots and ledger (operationId: getOrganizationCredits) Scope: orgs:read Success: 200 ### DELETE /organizations/{slug}/spend-limits Delete a spend limit (operationId: deleteSpendLimit) Scope: orgs:read Query: project (Project ref; omit for the org-wide limit) Success: 200 ### GET /organizations/{slug}/spend-limits List spend limits (operationId: listSpendLimits) Scope: orgs:read Success: 200 ### PUT /organizations/{slug}/spend-limits Create or update a spend limit (operationId: setSpendLimit) Scope: orgs:read Body: {"amount":0} Success: 200 ## Branches ### GET /projects/{ref}/branches List database branches (operationId: listBranches) Scope: branches:read Success: 200 ### POST /projects/{ref}/branches Create a branch (operationId: createBranch) Scope: branches:write Body: {"name":"string"} Success: 202 ### DELETE /projects/{ref}/branches/{branch} Delete a branch (operationId: deleteBranch) Scope: branches:write Success: 200 ### GET /projects/{ref}/branches/{branch}/merge Dry-run merge plan (operationId: getMergePlan) Scope: branches:read Success: 200 ### POST /projects/{ref}/branches/{branch}/merge Merge the branch into main (one transaction) (operationId: mergeBranch) Scope: branches:write Success: 200 ## Config as code ### POST /projects/{ref}/config/apply Apply a config - 200 when everything applied, 207 on partial success. (operationId: applyConfig) Scope: * Body: {"config":{}} Success: 200 ### GET /projects/{ref}/config/export Export settings in hostbase.config.ts shape (operationId: exportConfig) Scope: * Success: 200 ### POST /projects/{ref}/config/plan Plan (diff) a config (operationId: planConfig) Scope: * Body: {"config":{}} Success: 200 ## Database ### GET /projects/{ref}/database/migrations Applied migrations (operationId: listMigrations) Scope: db:read Success: 200 ### POST /projects/{ref}/database/migrations Apply a migration atomically - 409 if the version already exists. (operationId: applyMigration) Scope: db:write Body: {"name":"string","sql":"string"} Success: 201 ### POST /projects/{ref}/database/query Run SQL - Runs with database-owner privileges; the project must be active. Needs `db:write`. (operationId: runSql) Scope: db:write Body: {"query":"string"} Success: 200 ### POST /projects/{ref}/database/tests/run Run pgTAP tests (operationId: runDatabaseTests) Scope: db:read Body (optional): {"files":[{"name":"string","sql":"string"}],"label":"string","source":"api"} Success: 200 ### GET /projects/{ref}/postgres-version Postgres version, upgrade targets, schedule and history (operationId: getPostgresVersion) Scope: infra:read Success: 200 ### POST /projects/{ref}/postgres-version/check Compatibility report for an upgrade (changes nothing) (operationId: checkPostgresUpgrade) Scope: infra:write Body: {"to":"string"} Success: 200 ### POST /projects/{ref}/postgres-version/confirm Confirm a major upgrade (deletes the old data directory) (operationId: confirmPostgresUpgrade) Scope: infra:write Success: 200 ### POST /projects/{ref}/postgres-version/rollback Roll an unconfirmed major upgrade back - Writes made after the upgrade are lost; requires acknowledge_data_loss. (operationId: rollbackPostgresUpgrade) Scope: infra:write Body: {"acknowledge_data_loss":false} Success: 202 ### POST /projects/{ref}/postgres-version/upgrade Start or schedule a Postgres upgrade - Patch/variant swaps and 15 → 17 major upgrades; automatic backup and rollback. scheduled_for (ISO 8601, 10 min – 30 days ahead) books a maintenance window; dry_run rehearses a major upgrade on a copy. (operationId: upgradePostgres) Scope: infra:write Body: {"to":"string"} Success: 202 ### DELETE /projects/{ref}/postgres-version/upgrades/{id} Cancel a scheduled upgrade (operationId: cancelPostgresUpgrade) Scope: infra:write Success: 200 ### GET /projects/{ref}/postgres-version/upgrades/{id} Upgrade progress and log (operationId: getPostgresUpgrade) Scope: infra:read Success: 200 ### GET /projects/{ref}/types/kysely Kysely DB interface (operationId: getKyselyTypes) Scope: db:read Query: schemas (Comma-separated schemas) Success: 200 ### GET /projects/{ref}/types/typescript TypeScript types (supabase gen types compatible) (operationId: getTypescriptTypes) Scope: db:read Query: schemas (Comma-separated schemas (default public)) Success: 200 ### GET /projects/{ref}/types/zod Zod schemas (Row/Insert/Update per table) (operationId: getZodTypes) Scope: db:read Query: schemas (Comma-separated schemas) Success: 200 ## Email ### GET /projects/{ref}/email/domains Sending domains (operationId: listEmailDomains) Scope: email:read Success: 200 ### POST /projects/{ref}/email/domains Add a sending domain (DNS records returned) or re-verify (operationId: addEmailDomain) Scope: email:write Body: {"domain":"string"} Success: 201 ### GET /projects/{ref}/email/messages Message log (operationId: listEmailMessages) Scope: email:read Query: status (Delivery status); q (Substring filter); limit (Max rows) Success: 200 ### GET /projects/{ref}/email/suppressions Suppression list (operationId: listEmailSuppressions) Scope: email:read Success: 200 ## Feature flags ### GET /projects/{ref}/flags List flags with SDK keys (operationId: listFlags) Scope: * Success: 200 ### POST /projects/{ref}/flags Create a flag (operationId: createFlag) Scope: * Body: {"key":"string","name":"string"} Success: 201 ### DELETE /projects/{ref}/flags/{key} Delete a flag (operationId: deleteFlag) Scope: * Success: 200 ### GET /projects/{ref}/flags/{key} Get a flag (operationId: getFlag) Scope: * Success: 200 ### PUT /projects/{ref}/flags/{key} Update a flag (operationId: updateFlag) Scope: * Body: {"name":"string","description":"string","variants":[{"key":"string","value":null}],"archived":false} Success: 200 ## Functions ### GET /projects/{ref}/functions List Edge Functions (operationId: listFunctions) Scope: functions:read Success: 200 ### POST /projects/{ref}/functions Create an Edge Function - 409 if it already exists. (operationId: createFunction) Scope: functions:deploy Body: {"name":"string"} Success: 201 ### DELETE /projects/{ref}/functions/{name} Delete a function (operationId: deleteFunction) Scope: functions:deploy Success: 200 ### GET /projects/{ref}/functions/{name} Get function source and config (operationId: getFunction) Scope: functions:read Success: 200 ### PUT /projects/{ref}/functions/{name} Deploy (create or update) a function (operationId: deployFunction) Scope: functions:deploy Body: {"files":[{"path":"string","content":"string"}],"code":"string","body":"string","verify_jwt":false} Success: 200 ### GET /projects/{ref}/functions/{name}/logs Runtime logs (operationId: getFunctionLogs) Scope: functions:read Query: lines (Number of log lines (default 200)) Success: 200 ### GET /projects/{ref}/functions/{name}/versions Deploy history (operationId: listFunctionVersions) Scope: functions:read Success: 200 ### POST /projects/{ref}/functions/{name}/versions Roll back to a version (operationId: rollbackFunction) Scope: functions:deploy Body: {"rollback_to":1} Success: 200 ### DELETE /projects/{ref}/secrets Delete a secret (operationId: deleteSecret) Scope: secrets:write Query: name (Secret name) Success: 200 ### GET /projects/{ref}/secrets Secret names (values are never returned) (operationId: listSecrets) Scope: secrets:read Success: 200 ### PUT /projects/{ref}/secrets Set secrets (merged) - Body is `{secrets: {NAME: value}}` or the bare map. (operationId: setSecrets) Scope: secrets:write Body: {"secrets":{}} Success: 200 ## Infrastructure ### GET /projects/{ref}/autoscaling Compute autoscaling settings and history (operationId: getAutoscaling) Scope: infra:read Success: 200 ### PUT /projects/{ref}/autoscaling Update autoscaling (operationId: setAutoscaling) Scope: infra:write Body: {"enabled":false} Success: 200 ### GET /projects/{ref}/domains Custom API domains (operationId: listDomains) Scope: infra:read Success: 200 ### POST /projects/{ref}/domains Add a custom domain (CNAME, TLS automatic) (operationId: addDomain) Scope: infra:write Body: {"hostname":"string"} Success: 202 ### DELETE /projects/{ref}/domains/{hostname} Remove a custom domain (operationId: removeDomain) Scope: infra:write Success: 200 ### GET /projects/{ref}/network IP allowlist for Postgres and the pooler (operationId: getNetwork) Scope: infra:read Success: 200 ### PUT /projects/{ref}/network Set the IP allowlist (operationId: setNetwork) Scope: infra:write Body: {"allowed_cidrs":["string"]} Success: 200 ### GET /projects/{ref}/rate-limits API rate limits (operationId: getRateLimits) Scope: infra:read Success: 200 ### PUT /projects/{ref}/rate-limits Set API rate limits (operationId: setRateLimits) Scope: infra:write Body: {"rules":[{"path_prefix":"string","rps":1,"burst":1,"scope":"ip"}]} Success: 200 ### GET /projects/{ref}/replicas Read replicas with lag (operationId: listReplicas) Scope: infra:read Success: 200 ### POST /projects/{ref}/replicas Create a read replica (operationId: createReplica) Scope: infra:write Body: {"region":"pl-waw-1"} Success: 202 ### DELETE /projects/{ref}/replicas/{replica} Delete a replica (operationId: deleteReplica) Scope: infra:write Success: 200 ### GET /projects/{ref}/replicas/{replica} Get a replica (operationId: getReplica) Scope: infra:read Success: 200 ## Meta ### GET /openapi.json OpenAPI 3.1 document of this API (operationId: getOpenApiDocument) Auth: none Success: 200 ## Observability ### GET /projects/{ref}/issues Error issues grouped from logs (operationId: listIssues) Scope: * Query: status=open|resolved|ignored (Filter) Success: 200 ### GET /projects/{ref}/issues/{id} Issue with occurrences and an agent brief (operationId: getIssue) Scope: * Success: 200 ### PATCH /projects/{ref}/issues/{id} Set issue status (operationId: setIssueStatus) Scope: * Body: {"status":"open"} Success: 200 ### GET /projects/{ref}/monitors Synthetic HTTP monitors (operationId: listMonitors) Scope: * Success: 200 ### POST /projects/{ref}/monitors Create a monitor (operationId: createMonitor) Scope: * Body: {"name":"string","url":"https://example.com"} Success: 201 ### DELETE /projects/{ref}/monitors/{id} Delete a monitor (operationId: deleteMonitor) Scope: * Success: 200 ### GET /projects/{ref}/runtime-advisors Health check advisors (operationId: getRuntimeAdvisors) Scope: * Success: 200 ### GET /projects/{ref}/traffic Traffic from the edge access log: requests, status classes, bytes, p50/p95/p99 per service; optional previous period (operationId: getProjectTraffic) Scope: * Query: range=1h|6h|24h|48h|7d|30d (Time range); kind=api|rest|auth|storage|realtime|functions|worker|site (Service kind); name (Worker or site name); compare (Include the previous period (1)) Success: 200 ## Organizations ### GET /organizations List organizations (operationId: listOrganizations) Scope: orgs:read Success: 200 ## Projects ### GET /projects List projects across your organizations (operationId: listProjects) Scope: projects:read Success: 200 ### POST /projects Create a project (operationId: createProject) Scope: projects:write Body: {"name":"string","organization_slug":"string","region":"pl-waw-1"} Success: 201 ### DELETE /projects/{ref} Delete a project (irreversible) - Deletes the project, its database, files and backups. Owner or admin only; needs the explicit `projects:delete` scope. (operationId: deleteProject) Scope: projects:delete Success: 200 ### GET /projects/{ref} Get a project (operationId: getProject) Scope: projects:read Success: 200 ### GET /projects/{ref}/api-keys Get the anon and service_role keys (operationId: getProjectApiKeys) Scope: keys:read Success: 200 ### GET /projects/{ref}/import Latest import job (operationId: getImportStatus) Scope: projects:write Success: 200 ### POST /projects/{ref}/import Import an external Postgres/Supabase database (operationId: startImport) Scope: projects:write Body: {"db_url":"string"} Success: 202 ### GET /projects/{ref}/move Latest region-move job (operationId: getMoveStatus) Scope: projects:write Success: 200 ### POST /projects/{ref}/move Move the project to another region (operationId: moveProject) Scope: projects:write Body: {"region":"pl-waw-1"} Success: 202 ### POST /projects/{ref}/pause Pause a project (operationId: pauseProject) Scope: projects:write Success: 200 ### POST /projects/{ref}/resume Resume a paused project (operationId: resumeProject) Scope: projects:write Success: 200 ### GET /projects/{ref}/templates History of template applications (operationId: listTemplateJobs) Scope: projects:read Success: 200 ### POST /projects/{ref}/templates/{id} Apply a starter template (operationId: applyTemplate) Scope: projects:write Query: async (1 = return 202 with the job immediately) Success: 200 ### GET /templates Starter templates (operationId: listTemplates) Scope: projects:read Success: 200 ## Sandboxes ### GET /projects/{ref}/sandboxes List sandboxes (operationId: listSandboxes) Scope: sandboxes:read Query: all (1 = include recently ended sandboxes) Success: 200 ### POST /projects/{ref}/sandboxes Create a sandbox (microVM or gVisor) - Templates python-3.12, node-22, bun, ubuntu, playwright-chromium. Default-sized sandboxes are claimed from a warm pool (tens of ms); custom sizes cold-start in ~2 s. (operationId: createSandbox) Scope: sandboxes:write Body (optional): {"template":"python-3.12","runtime":"microvm","vcpu":0.25,"memory_mb":256} Success: 201 ### DELETE /projects/{ref}/sandboxes/{id} Close a sandbox (destroys VM, disk and network) (operationId: closeSandbox) Scope: sandboxes:write Success: 200 ### GET /projects/{ref}/sandboxes/{id} Get a sandbox (operationId: getSandbox) Scope: sandboxes:read Success: 200 ### POST /projects/{ref}/sandboxes/{id}/egress Set the egress policy (open, allowlist, none) (operationId: setSandboxEgress) Scope: sandboxes:write Body: {"mode":"open"} Success: 200 ### POST /projects/{ref}/sandboxes/{id}/exec Run a command (sync, SSE stream or background) - stream=true answers with text/event-stream events {type: stdout|stderr|exit}. (operationId: execSandbox) Scope: sandboxes:write Body: {"cmd":"string"} Success: 200 ### GET /projects/{ref}/sandboxes/{id}/files/archive Download a directory as tar (operationId: downloadSandboxArchive) Scope: sandboxes:read Query: path (Directory (default /workspace)) Success: 200 ### PUT /projects/{ref}/sandboxes/{id}/files/archive Extract a tar body into a directory (operationId: uploadSandboxArchive) Scope: sandboxes:write Query: path (Directory (default /workspace)) Success: 200 ### DELETE /projects/{ref}/sandboxes/{id}/files/content Delete a file or directory (operationId: deleteSandboxFile) Scope: sandboxes:write Query: path (Path) Success: 200 ### GET /projects/{ref}/sandboxes/{id}/files/content Download a file (operationId: readSandboxFile) Scope: sandboxes:read Query: path (File path) Success: 200 ### PUT /projects/{ref}/sandboxes/{id}/files/content Upload a file (raw body) (operationId: writeSandboxFile) Scope: sandboxes:write Query: path (File path) Success: 200 ### GET /projects/{ref}/sandboxes/{id}/files/list List a directory (operationId: listSandboxFiles) Scope: sandboxes:read Query: path (Directory (default /workspace)) Success: 200 ### POST /projects/{ref}/sandboxes/{id}/files/mkdir Create a directory (operationId: mkdirSandbox) Scope: sandboxes:write Query: path (Directory path) Success: 200 ### GET /projects/{ref}/sandboxes/{id}/logs Event log and kernel console (operationId: getSandboxLogs) Scope: sandboxes:read Success: 200 ### GET /projects/{ref}/sandboxes/{id}/metrics CPU, memory, network and disk samples (operationId: getSandboxMetrics) Scope: sandboxes:read Success: 200 ### POST /projects/{ref}/sandboxes/{id}/pause Pause (freeze) or stop a sandbox (operationId: pauseSandbox) Scope: sandboxes:write Body (optional): {"mode":"freeze"} Success: 200 ### POST /projects/{ref}/sandboxes/{id}/ports List a preview URL for a port (operationId: exposeSandboxPort) Scope: sandboxes:write Body: {"port":1} Success: 200 ### POST /projects/{ref}/sandboxes/{id}/resume Resume a paused or stopped sandbox (operationId: resumeSandbox) Scope: sandboxes:write Success: 200 ### POST /projects/{ref}/sandboxes/{id}/run-code Run a code cell (Jupyter-like Python kernel with PNG charts) (operationId: runSandboxCode) Scope: sandboxes:write Body: {"code":"string"} Success: 200 ### POST /projects/{ref}/sandboxes/{id}/terminal Open an interactive terminal session (operationId: openSandboxTerminal) Scope: sandboxes:write Success: 201 ### DELETE /projects/{ref}/sandboxes/{id}/terminal/{sid} Close a terminal session (operationId: closeSandboxTerminal) Scope: sandboxes:write Success: 200 ### POST /projects/{ref}/sandboxes/{id}/terminal/{sid}/input Send keystrokes to the terminal (operationId: sendSandboxTerminalInput) Scope: sandboxes:write Success: 200 ### POST /projects/{ref}/sandboxes/{id}/terminal/{sid}/resize Resize the terminal (operationId: resizeSandboxTerminal) Scope: sandboxes:write Success: 200 ### GET /projects/{ref}/sandboxes/{id}/terminal/{sid}/stream Terminal output (SSE, base64 chunks) (operationId: streamSandboxTerminal) Scope: sandboxes:read Success: 200 ### POST /projects/{ref}/sandboxes/{id}/timeout Change idle timeout / lifetime (max 24 h) (operationId: setSandboxTimeout) Scope: sandboxes:write Body: {"idle_timeout_s":30,"lifetime_s":60} Success: 200 ### GET /projects/{ref}/sandboxes/templates Sandbox templates, defaults and limits (operationId: listSandboxTemplates) Scope: sandboxes:read Success: 200 ### GET /projects/{ref}/sandboxes/usage Month-to-date vCPU-hours and GB-hours vs the plan allowance (operationId: getSandboxUsage) Scope: sandboxes:read Success: 200 ## Security ### GET /projects/{ref}/security/egress Static egress IP of the project (operationId: getStaticEgress) Scope: infra:read Success: 200 ### PUT /projects/{ref}/security/egress Enable or disable the static egress IP (operationId: setStaticEgress) Scope: infra:write Body: {"enabled":false} Success: 200 ### GET /projects/{ref}/security/waf WAF (OWASP CRS) and bot-protection settings (operationId: getWaf) Scope: infra:read Success: 200 ### PUT /projects/{ref}/security/waf Update WAF / bot protection (partial update) (operationId: setWaf) Scope: infra:write Body: {"mode":"off","paranoia":1,"anomaly_threshold":1,"body_limit_kb":8} Success: 200 ### GET /projects/{ref}/security/waf/bans Active IP bans (automatic and manual) (operationId: listWafBans) Scope: infra:read Success: 200 ### POST /projects/{ref}/security/waf/bans Ban an IP address (operationId: banIp) Scope: infra:write Body: {"ip":"string"} Success: 200 ### DELETE /projects/{ref}/security/waf/bans/{ip} Remove an IP ban (operationId: unbanIp) Scope: infra:write Success: 200 ### GET /projects/{ref}/security/waf/events Recent WAF events (rule id, redacted matched data, client IP) (operationId: listWafEvents) Scope: infra:read Query: limit (1-500); kind (crs | custom | rate_limit | ban); ip (Client IP); rule_id (CRS rule id); since (ISO timestamp) Success: 200 ### GET /projects/{ref}/security/waf/stats WAF time series and top rules / IPs / paths (operationId: getWafStats) Scope: infra:read Query: hours (1-336 (default 24)) Success: 200 ## Sites ### GET /projects/{ref}/sites List sites (operationId: listSites) Scope: * Success: 200 ### DELETE /projects/{ref}/sites/{name} Delete a site (operationId: deleteSite) Scope: * Success: 200 ### GET /projects/{ref}/sites/{name} Get a site (operationId: getSite) Scope: * Success: 200 ### PUT /projects/{ref}/sites/{name} Create a site or update its settings (operationId: saveSite) Scope: * Body: {"framework":"auto","install_command":"string","build_command":"string","output_dir":"string"} Success: 200 ### POST /projects/{ref}/sites/{name}/{action} Redeploy or restart a site (operationId: siteAction) Scope: * action: redeploy | restart Success: 200 ### GET /projects/{ref}/sites/{name}/analytics Requests, bandwidth, status classes, top paths (operationId: getSiteAnalytics) Scope: * Query: range=24h|7d|30d (Time range) Success: 200 ### GET /projects/{ref}/sites/{name}/auto/{path} Read a Sites automation resource (automation, env-groups, env-pull, pipeline-runs, scripts, checks, runs/{id}, rum) (operationId: getSiteAutomationResource) Scope: * Success: 200 ### POST /projects/{ref}/sites/{name}/auto/{path} Run a script or check, approve/reject a pipeline run (operationId: postSiteAutomationResource) Scope: * Success: 200 ### PUT /projects/{ref}/sites/{name}/auto/{path} Save automation config, an env group or RUM settings (operationId: putSiteAutomationResource) Scope: * Success: 200 ### GET /projects/{ref}/sites/{name}/cdn CDN status of a site (Cloudflare proxy hostname, last purge) (operationId: getSiteCdn) Scope: * Success: 200 ### POST /projects/{ref}/sites/{name}/cdn Purge the site's CDN cache (operationId: purgeSiteCdn) Scope: * Success: 200 ### PUT /projects/{ref}/sites/{name}/cdn Enable or disable the CDN for a site (operationId: setSiteCdn) Scope: * Success: 200 ### GET /projects/{ref}/sites/{name}/cdn/analytics CDN cache analytics (hit ratio, bytes, origin requests) (operationId: getSiteCdnAnalytics) Scope: * Success: 200 ### GET /projects/{ref}/sites/{name}/comments Comments pinned on preview deployments (operationId: listSiteComments) Scope: * Success: 200 ### POST /projects/{ref}/sites/{name}/comments Reply to a comment thread (operationId: replySiteComment) Scope: * Success: 200 ### DELETE /projects/{ref}/sites/{name}/comments/{id} Delete a comment thread (operationId: deleteSiteComment) Scope: * Success: 200 ### POST /projects/{ref}/sites/{name}/comments/{id} Resolve or reopen a comment thread (operationId: resolveSiteComment) Scope: * Success: 200 ### GET /projects/{ref}/sites/{name}/cutover DNS cut-over guide and live verification of custom domains (operationId: getSiteCutover) Scope: * Success: 200 ### GET /projects/{ref}/sites/{name}/deployments List deployments (operationId: listSiteDeployments) Scope: * Success: 200 ### POST /projects/{ref}/sites/{name}/deployments Create a deployment (async build) (operationId: deploySite) Scope: * Body (optional): {"mode":"dist","target":"production","files":[{"path":"string","content":"string"}],"archive_base64":"string"} Success: 202 ### DELETE /projects/{ref}/sites/{name}/deployments/{id} Delete a deployment (operationId: deleteSiteDeployment) Scope: * Success: 200 ### POST /projects/{ref}/sites/{name}/deployments/{id}/{action} Promote (rollback) or wake a deployment (operationId: siteDeploymentAction) Scope: * action: promote | wake Success: 200 ### GET /projects/{ref}/sites/{name}/domains Custom domains of a site (operationId: listSiteDomains) Scope: * Success: 200 ### POST /projects/{ref}/sites/{name}/domains Add a custom domain (operationId: addSiteDomain) Scope: * Body: {"hostname":"string"} Success: 202 ### DELETE /projects/{ref}/sites/{name}/domains/{hostname} Remove a custom domain (operationId: removeSiteDomain) Scope: * Success: 200 ### GET /projects/{ref}/sites/{name}/env Environment variables (operationId: getSiteEnv) Scope: * Success: 200 ### PUT /projects/{ref}/sites/{name}/env Replace environment variables (operationId: setSiteEnv) Scope: * Body: {"env":{}} Success: 200 ### GET /projects/{ref}/sites/{name}/freeze Deploy freeze state (operationId: getSiteFreeze) Scope: * Success: 200 ### PUT /projects/{ref}/sites/{name}/freeze Set the deploy freeze (manual and weekly / one-off windows) (operationId: setSiteFreeze) Scope: * Success: 200 ### DELETE /projects/{ref}/sites/{name}/github Unlink GitHub (operationId: unlinkSiteGithub) Scope: * Success: 200 ### GET /projects/{ref}/sites/{name}/github GitHub link status (operationId: getSiteGithub) Scope: * Success: 200 ### PUT /projects/{ref}/sites/{name}/github Link to GitHub (push to deploy, PR previews) (operationId: linkSiteGithub) Scope: * Body (optional): {"branch":"string","root_dir":"string","previews":false,"auto_deploy":false} Success: 200 ### DELETE /projects/{ref}/sites/{name}/hook Remove the deploy hook (operationId: deleteSiteHook) Scope: * Success: 200 ### GET /projects/{ref}/sites/{name}/hook Deploy hook URL (operationId: getSiteHook) Scope: * Success: 200 ### POST /projects/{ref}/sites/{name}/hook Create or rotate the deploy hook (operationId: createSiteHook) Scope: * Success: 201 ### GET /projects/{ref}/sites/{name}/logs Build or runtime logs (operationId: getSiteLogs) Scope: * Query: build (1 = build log); deployment (Deployment id, e.g. d3); lines (Number of log lines (default 200)); q (Substring filter) Success: 200 ### POST /projects/{ref}/sites/{name}/move Move a site to another project / region (settings, env, rules, domains, latest deployments) (operationId: moveSite) Scope: * Success: 200 ### GET /projects/{ref}/sites/{name}/notifications Deploy / comment notifications, bandwidth alert, revalidation endpoint (operationId: getSiteNotifications) Scope: * Success: 200 ### PUT /projects/{ref}/sites/{name}/notifications Update site notifications and alerts (operationId: setSiteNotifications) Scope: * Success: 200 ### GET /projects/{ref}/sites/{name}/platform Platform config: protection, maintenance, redirects, rewrites, headers, rules (geo / A-B), error pages, skew, images, OG (operationId: getSitePlatform) Scope: * Success: 200 ### PUT /projects/{ref}/sites/{name}/platform Partially update the platform config (password is write-only) (operationId: updateSitePlatform) Scope: * Success: 200 ### POST /projects/{ref}/sites/{name}/platform/test Rules tester: what the gateway does for a request (optionally on unsaved config) (operationId: testSiteRules) Scope: * Success: 200 ### POST /projects/{ref}/sites/{name}/revalidate On-demand revalidation: purge the CDN for paths and call the app's revalidation endpoint (operationId: revalidateSite) Scope: * Success: 200 ### POST /projects/{ref}/sites/import/{action} Migrate from Vercel / Netlify / Cloudflare Pages (action: list | preview | run) (operationId: importSite) Scope: * Success: 200 ## Workers ### GET /projects/{ref}/jobs All worker jobs in the project (operationId: listProjectJobs) Scope: * Query: limit (Default 50) Success: 200 ### GET /projects/{ref}/workers List workers (operationId: listWorkers) Scope: workers:read Success: 200 ### DELETE /projects/{ref}/workers/{name} Delete a worker (operationId: deleteWorker) Scope: workers:write Success: 200 ### GET /projects/{ref}/workers/{name} Get a worker (operationId: getWorker) Scope: workers:read Success: 200 ### PUT /projects/{ref}/workers/{name} Create or redeploy a worker (async build) (operationId: deployWorker) Scope: workers:write Body: {"runtime":"auto","type":"http","size":"w-small","replicas":0} Success: 202 ### POST /projects/{ref}/workers/{name}/{action} Worker lifecycle action - start | stop | restart | run (cron, now) | scale | activate | move (to the dedicated workers host or back, body placement). (operationId: workerAction) Scope: workers:write action: start | stop | restart | run | scale | activate | move Body (optional): {"replicas":0,"min":-9007199254740991,"max":-9007199254740991,"auto":false} Success: 200 ### GET /projects/{ref}/workers/{name}/capture Request capture settings (operationId: getWorkerCapture) Scope: workers:read Success: 200 ### PUT /projects/{ref}/workers/{name}/capture Enable or disable capturing the last N requests (redacted headers, size-limited bodies) (operationId: setWorkerCapture) Scope: workers:write Success: 200 ### POST /projects/{ref}/workers/{name}/capture/replay Replay a captured request against the current version, an older version or another worker; returns the response diff (operationId: replayWorkerRequest) Scope: workers:write Success: 200 ### DELETE /projects/{ref}/workers/{name}/capture/requests Delete all captured requests (operationId: clearWorkerCapturedRequests) Scope: workers:write Success: 200 ### GET /projects/{ref}/workers/{name}/capture/requests Captured requests, newest first (operationId: listWorkerCapturedRequests) Scope: workers:read Query: limit (Max requests (1-100)) Success: 200 ### PUT /projects/{ref}/workers/{name}/config Partial update of scaling, health, egress, ... (operationId: setWorkerConfig) Scope: workers:write Body: {"scaling":{"min":0,"max":1,"auto":false,"idle_timeout_s":60},"health":{"type":"http"},"grace_s":1,"pre_deploy":"string"} Success: 200 ### GET /projects/{ref}/workers/{name}/events Scaling, wake, OOM, restart and job events (operationId: listWorkerEvents) Scope: workers:read Query: limit (Max events (default 100)) Success: 200 ### DELETE /projects/{ref}/workers/{name}/git Unlink a worker from GitHub (operationId: deleteWorkerGit) Scope: workers:write Success: 200 ### GET /projects/{ref}/workers/{name}/git GitHub link of a worker (branch, root dir, auto-deploy) and its live PR previews (operationId: getWorkerGit) Scope: workers:read Success: 200 ### PUT /projects/{ref}/workers/{name}/git Link a worker to the connected GitHub repository (branch, root_dir, previews, auto_deploy) (operationId: setWorkerGit) Scope: workers:write Success: 200 ### PUT /projects/{ref}/workers/{name}/job-schedules Cron schedules for jobs (operationId: setWorkerJobSchedules) Scope: workers:write Body: {"schedules":[{"id":"string","schedule":"string"}]} Success: 200 ### GET /projects/{ref}/workers/{name}/jobs Jobs of a worker (operationId: listWorkerJobs) Scope: workers:read Query: limit (Default 50) Success: 200 ### POST /projects/{ref}/workers/{name}/jobs Run a one-off job (operationId: runWorkerJob) Scope: workers:write Body (optional): {"command":"string","args":["string"],"env":{},"timeout_s":5} Success: 202 ### GET /projects/{ref}/workers/{name}/jobs/{id} Get a job (operationId: getWorkerJob) Scope: workers:read Success: 200 ### GET /projects/{ref}/workers/{name}/jobs/{id}/artifacts List job artifacts (operationId: listJobArtifacts) Scope: workers:read Success: 200 ### GET /projects/{ref}/workers/{name}/jobs/{id}/artifacts/{path} Download a job artifact (operationId: getJobArtifact) Scope: workers:read Query: json (1 = JSON with base64 content) Success: 200 ### POST /projects/{ref}/workers/{name}/jobs/{id}/cancel Cancel a job (operationId: cancelWorkerJob) Scope: workers:write Success: 200 ### GET /projects/{ref}/workers/{name}/jobs/{id}/logs Job logs (operationId: getWorkerJobLogs) Scope: workers:read Query: lines (Number of log lines (default 200)) Success: 200 ### GET /projects/{ref}/workers/{name}/logs Runtime or build logs (operationId: getWorkerLogs) Scope: workers:read Query: lines (Number of log lines (default 200)); since (Unix ms); q (Substring filter); build (1 = build log); version (Build log of a version) Success: 200 ### PUT /projects/{ref}/workers/{name}/scaling Autoscaling settings (operationId: setWorkerScaling) Scope: workers:write Body: {"min":0,"max":1,"auto":false,"idle_timeout_s":60} Success: 200 ### POST /projects/{ref}/workers/{name}/transfer Copy a worker to another project of the organisation or change its placement; returns a mapping report (operationId: transferWorker) Scope: workers:write Success: 200 ### DELETE /projects/{ref}/workers/{name}/volume Destroy the volume and its data (operationId: deleteWorkerVolume) Scope: workers:write Success: 200 ### PUT /projects/{ref}/workers/{name}/volume Create or grow the /data volume (operationId: setWorkerVolume) Scope: workers:write Body: {"size_gb":1} Success: 200 ### DELETE /projects/{ref}/workers/db-triggers Remove a database trigger (operationId: deleteWorkerDbTrigger) Scope: workers:write Success: 200 ### GET /projects/{ref}/workers/db-triggers List database triggers that enqueue to queue workers (operationId: listWorkerDbTriggers) Scope: workers:read Success: 200 ### POST /projects/{ref}/workers/db-triggers Create a table trigger feeding a pgmq queue (dry_run returns SQL) (operationId: createWorkerDbTrigger) Scope: workers:write Success: 200 ### POST /projects/{ref}/workers/deploy-git Create a worker from a public Git URL - github.com, gitlab.com, bitbucket.org and codeberg.org (https). Private repositories: connect GitHub in the project and use git auto-deploy. (operationId: deployWorkerFromGit) Scope: workers:write Body: {"url":"string"} Success: 202 ### POST /projects/{ref}/workers/from-template Deploy a gallery template as a new worker (operationId: deployWorkerFromTemplate) Scope: workers:write Body: {"template":"string"} Success: 202 ### POST /projects/{ref}/workers/generate Generate a worker (code, deps, env schema) from a prompt (operationId: generateWorker) Scope: workers:write Success: 200 ### POST /projects/{ref}/workers/image/inspect Pull a registry image and report size, ports and user (operationId: inspectWorkerImage) Scope: workers:write Body: {"image":"string"} Success: 200 ### POST /projects/{ref}/workers/import Import a service from another platform (dry run or deploy) - Converts Procfile/app.json (Heroku, Dokku), render.yaml, railway.json/toml, fly.toml, docker-compose, Vercel/Netlify functions, Supabase Edge Functions, Cloud Run YAML or an AWS Lambda handler into a worker and returns a mapping report (converted / needs attention / unsupported). Pass `apply: true` to deploy (202). (operationId: importWorker) Scope: workers:write Body: {"files":[{"path":"string","content":"string"}],"archive_base64":"string","archive_format":"zip","service":"string"} Success: 200 ### GET /projects/{ref}/workers/insights Right-sizing, scale-to-zero and crash-loop suggestions (operationId: getWorkerInsights) Scope: workers:read Success: 200 ### GET /projects/{ref}/workers/volumes All worker volumes (operationId: listWorkerVolumes) Scope: workers:read Success: 200 ### GET /projects/{ref}/workers/workflows List durable workflow runs (operationId: listWorkflowRuns) Scope: workers:read Success: 200 ### POST /projects/{ref}/workers/workflows Workflow actions: install, start, event, retry, cancel (operationId: workflowAction) Scope: workers:write Success: 200 ### GET /projects/{ref}/workers/workflows/{id} Get one workflow run with its steps (operationId: getWorkflowRun) Scope: workers:read Success: 200 ### GET /worker-templates Worker template gallery (metadata) (operationId: listWorkerTemplates) Scope: * Query: q (Text search); language (Language); category (Category); runtime (Runtime id) Success: 200 ### GET /worker-templates/{id} Template with source files (operationId: getWorkerTemplate) Scope: * Success: 200