{
  "openapi": "3.1.0",
  "info": {
    "title": "Totalum App Builder API",
    "version": "1.0.0",
    "summary": "Create, build and deploy full-stack AI-generated apps programmatically.",
    "description": "The Totalum App Builder API lets you create a project, run the AI agent with a natural-language prompt, and deploy the result to a public URL.\n\nEvery response uses the same envelope: `{ \"errors\": null | { \"errorCode\", \"errorMessage\" }, \"data\": ... }` — the one exception is a rejected API key, which returns `401 { \"error\": \"Unauthorized api key\" }`. Branch on the status code, not only on `errors`.\n\nThe agent and deployment endpoints are asynchronous: they return immediately, and you poll the matching status endpoint every 10 to 15 seconds. An agent run takes 5 to 40 minutes; a deploy takes 2 to 5 minutes.\n\nKeep your `tlm_sk_` key on your backend — it must never reach browser code.\n\nThis document is generated from the published documentation at https://www.totalum.app/docs/api/overview, so it always matches it.\nRunnable quickstart: https://www.totalum.app/docs/quickstart",
    "contact": {
      "name": "Totalum",
      "url": "https://www.totalum.app/docs",
      "email": "contacto@totalum.app"
    },
    "license": {
      "name": "Totalum Terms of Service",
      "url": "https://www.totalum.app/terms-of-service"
    }
  },
  "externalDocs": {
    "description": "Totalum API documentation",
    "url": "https://www.totalum.app/docs/api/overview"
  },
  "servers": [
    {
      "url": "https://builder-api.totalum.app",
      "description": "Production"
    },
    {
      "url": "https://api-accounts.totalum.app",
      "description": "Legacy alias, still works (identical behaviour)"
    }
  ],
  "security": [
    {
      "apiKey": []
    }
  ],
  "tags": [
    {
      "name": "Projects",
      "description": "Launch a project (create it and start building in one call), create an empty one, list, read, update, pause, resume and delete projects, read their live state and rotate the preview address.",
      "externalDocs": {
        "url": "https://www.totalum.app/docs/api/projects"
      }
    },
    {
      "name": "AI Agent",
      "description": "Send prompts to the Totalum AI agent, follow a run in real time (status, messages and step-by-step progress), read the conversation, stop a run, run multi-prompt batches, and set the agent's own instructions and MCP servers.",
      "externalDocs": {
        "url": "https://www.totalum.app/docs/api/agent"
      }
    },
    {
      "name": "Publishing",
      "description": "Publish a project's current version to its live address, follow the publish step by step, and take a project offline.",
      "externalDocs": {
        "url": "https://www.totalum.app/docs/api/deployments"
      }
    },
    {
      "name": "Versions",
      "description": "List a project's saved versions, read the diff each one introduced, and restore an earlier version to the development preview.",
      "externalDocs": {
        "url": "https://www.totalum.app/docs/api/versions"
      }
    },
    {
      "name": "Database",
      "description": "Read the schema of a project's SQL database and query, insert, update, delete, bulk-write and link rows, run one SQL statement, turn a question into SQL, read the database's usage and undo an agent run's database change.",
      "externalDocs": {
        "url": "https://www.totalum.app/docs/api/database"
      }
    },
    {
      "name": "Database Backups & Restore",
      "description": "Scheduled and manual backups of a project's database, downloadable SQL dumps, restore points, point-in-time restore over the last 30 days, and the one-way move to Turso.",
      "externalDocs": {
        "url": "https://www.totalum.app/docs/api/database-backups"
      }
    },
    {
      "name": "Project Files",
      "description": "Browse a project's file tree, read one file and write one file through the API; every write is saved as a version and deployed to the development preview.",
      "externalDocs": {
        "url": "https://www.totalum.app/docs/api/project-files"
      }
    },
    {
      "name": "Source Code & Uploads",
      "description": "Download a project's complete source code, and upload files (images, designs, documents) to attach to a prompt or store in the project.",
      "externalDocs": {
        "url": "https://www.totalum.app/docs/api/source-files"
      }
    },
    {
      "name": "Secrets, Keys & .env",
      "description": "Store environment variables (third-party API keys) for a project, create and rotate the project's own API keys for calling its database and built-in features from your servers, and download its .env file to run it locally.",
      "externalDocs": {
        "url": "https://www.totalum.app/docs/api/secrets"
      }
    },
    {
      "name": "Logs & Preview Server",
      "description": "Read the logs of the development preview and of the published site, filter them by level, text, status, path or request, and restart or wake the project's development environment.",
      "externalDocs": {
        "url": "https://www.totalum.app/docs/api/server"
      }
    },
    {
      "name": "Usage & Analytics",
      "description": "Credits a project or the whole account used per feature, daily spending for charts, and the visits, pages, referrers and countries of a published site.",
      "externalDocs": {
        "url": "https://www.totalum.app/docs/api/analytics"
      }
    },
    {
      "name": "Spending & Rate Limits",
      "description": "Cap what a project may spend each month, switch the app's built-in features on or off with their own budgets, and set how many requests each visitor may send to the published site.",
      "externalDocs": {
        "url": "https://www.totalum.app/docs/api/limits"
      }
    },
    {
      "name": "Scheduled Jobs",
      "description": "Create cron jobs that call your app's own routes on a schedule, in UTC or any time zone, run them on demand and read their executions.",
      "externalDocs": {
        "url": "https://www.totalum.app/docs/api/cron-jobs"
      }
    },
    {
      "name": "Custom Domains",
      "description": "Serve a published project from your own domain or subdomain — add it, get the DNS records to create, follow its status until it is active, or remove it.",
      "externalDocs": {
        "url": "https://www.totalum.app/docs/api/domains"
      }
    },
    {
      "name": "Buy a Domain",
      "description": "Search for a domain, buy it with the card on your Totalum account, attach it to a project with no DNS work, and manage its DNS records, e-mail forwarding, renewal and transfer.",
      "externalDocs": {
        "url": "https://www.totalum.app/docs/api/domain-registration"
      }
    },
    {
      "name": "Mobile Apps",
      "description": "Build Android and iOS apps of a published project, manage signing keys and store accounts, and upload builds to Google Play and TestFlight.",
      "externalDocs": {
        "url": "https://www.totalum.app/docs/api/mobile"
      }
    },
    {
      "name": "Payments",
      "description": "Connect your own Stripe account so the app can take payments and subscriptions, check the account's status, and switch the published site to real payments. Or use your own Stripe keys.",
      "externalDocs": {
        "url": "https://www.totalum.app/docs/api/payments"
      }
    },
    {
      "name": "Webhooks",
      "description": "Receive an HTTPS call when a prompt finishes, a publish ends, a project reaches a limit or changes state — instead of polling — and set the project's own webhook for its integration events.",
      "externalDocs": {
        "url": "https://www.totalum.app/docs/api/webhooks"
      }
    },
    {
      "name": "Export & Import",
      "description": "Copy a project — code, database schema, optionally its data, files and scheduled jobs — into a new project, on the same account or another, with a secret import code.",
      "externalDocs": {
        "url": "https://www.totalum.app/docs/api/transfer"
      }
    },
    {
      "name": "GitHub",
      "description": "Connect a GitHub repo to a Totalum project, sync branches, pull changes, check status, and download env vars.",
      "externalDocs": {
        "url": "https://www.totalum.app/docs/api/github"
      }
    },
    {
      "name": "Figma",
      "description": "Connect a Figma account to a project so the agent reads your designs — frames, layout, colours, text — and builds from them.",
      "externalDocs": {
        "url": "https://www.totalum.app/docs/api/figma"
      }
    },
    {
      "name": "Visual Edits",
      "description": "Apply a batch of point-and-click edits (text, styles, images, links, visibility) to elements of the development preview, saved as one version, without a prompt.",
      "externalDocs": {
        "url": "https://www.totalum.app/docs/api/visual-edit"
      }
    },
    {
      "name": "Project Groups",
      "description": "Create optional folders for your Totalum projects, list them with project counts, rename them, and delete a folder without ever deleting the projects inside it.",
      "externalDocs": {
        "url": "https://www.totalum.app/docs/api/project-groups"
      }
    },
    {
      "name": "Account",
      "description": "Your credit balance, the price of every fixed-price action and the monthly fees, and the account's default data residency for new projects.",
      "externalDocs": {
        "url": "https://www.totalum.app/docs/api/account"
      }
    }
  ],
  "paths": {
    "/api/v1/vcaas/projects/launch": {
      "post": {
        "operationId": "launchProject",
        "summary": "Launch Project",
        "description": "Create a project and start building it with its first prompt, in one call. Secrets, attachments, credit limits and a Figma token sent here are in place before the first build starts, which is the order the build needs.\n\nFull reference: https://www.totalum.app/docs/api/projects#launch-project",
        "tags": [
          "Projects"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "projectId": {
                    "type": "string",
                    "description": "Your preferred id: 4–35 characters, lowercase letters, digits and single hyphens, starting with a letter, never containing -dev-. It becomes the address <projectId>.totalum-project.com. If it is taken, a short random suffix is added and requestedProjectId is returned"
                  },
                  "prompt": {
                    "type": "string",
                    "description": "What to build (the first prompt, up to 40,000 characters)"
                  },
                  "tier": {
                    "type": "string",
                    "description": "\"auto\" (default), \"cheap\", \"normal\" or \"expensive\" — see agent tiers. Also accepted as model or modelTier"
                  },
                  "engineVersion": {
                    "type": "string",
                    "description": "\"v2\" to require the current engine. A request that cannot get it is refused (ENGINE_V2_DISABLED, ENGINE_REQUEST_NOT_ELIGIBLE, ENGINE_V2_REQUIRES_PLATFORM_ACCOUNT) and nothing is created. New accounts create every project on the current engine, with or without it (\"legacy\" is refused: ENGINE_LEGACY_UNAVAILABLE); on an older account a create without it can be a legacy project"
                  },
                  "label": {
                    "type": "string",
                    "description": "Display name, up to 80 characters. Can be changed later; the id cannot"
                  },
                  "description": {
                    "type": "string",
                    "description": "Up to 500 characters"
                  },
                  "groupId": {
                    "type": "string",
                    "description": "An existing project group"
                  },
                  "ownerEmail": {
                    "type": "string",
                    "description": "The e-mail of the app's owner: the person who may use the app's admin and staff pages once they sign up with it and confirm it in the app. Default: none — then the first person who signs up in the app becomes its admin after entering the 8-digit code e-mailed to them (the preview and the published app each have their own first sign-up). Builders on Totalum (your users build apps through your product): send your user's e-mail. Change it later with Set App Owner"
                  },
                  "dataResidency": {
                    "type": "string",
                    "description": "\"global\" or \"eu\" (data kept in the EU only). Default: your account's setting (Set Data Residency), else \"global\". Fixed for the project's life"
                  },
                  "audienceCountry": {
                    "type": "string",
                    "description": "Two-letter country code of the app's users (\"US\"); the database is placed nearest them. Default: your account's country. Never makes a project EU-only"
                  },
                  "files": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "name": {
                          "type": "string",
                          "description": "File name, e.g. logo.png"
                        },
                        "description": {
                          "type": "string",
                          "description": "What the file is for (\"use as the logo\"). imageDescription is accepted too"
                        },
                        "url": {
                          "type": "string",
                          "description": "Public http(s) URL of a hosted file"
                        },
                        "content": {
                          "type": "string",
                          "description": "The file as base64 (a data:…;base64, prefix is accepted). Uploaded for you, free"
                        }
                      },
                      "required": [
                        "name"
                      ],
                      "additionalProperties": true
                    },
                    "description": "Up to 10 attachments for the first prompt. Each has exactly one of url or content"
                  },
                  "secrets": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "secretName": {
                          "type": "string",
                          "description": "Uppercase letters, digits and _, starting with a letter (STRIPE_KEY)"
                        },
                        "secretValue": {
                          "type": "string",
                          "description": "1–10,000 characters. Never returned again"
                        },
                        "environment": {
                          "type": "string",
                          "description": "\"development\", \"production\" or \"both\" (default)"
                        }
                      },
                      "required": [
                        "secretName",
                        "secretValue"
                      ],
                      "additionalProperties": true
                    },
                    "description": "Up to 50 environment variables, stored before the build starts"
                  },
                  "creditLimits": {
                    "type": "object",
                    "description": "Monthly caps applied from the first prompt. Set them to control your costs — see Spending & Rate Limits",
                    "properties": {
                      "maxDevelopmentCreditsPerMonth": {
                        "type": [
                          "number",
                          "null"
                        ],
                        "description": "Cap on what the AI agent and project actions spend (prompts, builds, publishing). Default 5000 for projects created through the API; null = no cap"
                      },
                      "maxInfrastructureCreditsPerMonth": {
                        "type": [
                          "number",
                          "null"
                        ],
                        "description": "Cap on what the running app spends (hosting, database, AI, e-mail…). Default 300 for projects created through the API; null = no cap"
                      }
                    },
                    "additionalProperties": true
                  },
                  "figma": {
                    "type": "object",
                    "description": "Connect Figma so the agent can read designs linked in the prompt",
                    "properties": {
                      "token": {
                        "type": "string",
                        "description": "A Figma personal access token, checked before anything is created"
                      }
                    },
                    "required": [
                      "token"
                    ],
                    "additionalProperties": true
                  }
                },
                "required": [
                  "projectId",
                  "prompt"
                ],
                "additionalProperties": true
              },
              "example": {
                "projectId": "barber-bookings",
                "prompt": "Build a booking site for a barbershop with online payments",
                "label": "Barber bookings",
                "creditLimits": {
                  "maxDevelopmentCreditsPerMonth": 500
                }
              }
            }
          }
        },
        "x-totalum-cost": "2 credits + the first prompt",
        "externalDocs": {
          "description": "Launch Project — Totalum docs",
          "url": "https://www.totalum.app/docs/api/projects#launch-project"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "projectId": {
                          "type": "string",
                          "description": "The id that was created. Use this one from now on"
                        },
                        "requestedProjectId": {
                          "type": "string",
                          "description": "The id you asked for, only when the created one differs"
                        },
                        "description": {
                          "type": "string",
                          "description": "Project description"
                        },
                        "plan": {
                          "type": "string",
                          "description": "Always \"api\""
                        },
                        "createdAt": {
                          "type": "string",
                          "description": "ISO 8601 creation time"
                        },
                        "label": {
                          "type": "string",
                          "description": "The label, when one was given"
                        },
                        "groupId": {
                          "type": "string",
                          "description": "The group, when one was given"
                        },
                        "dataResidency": {
                          "type": "string",
                          "description": "\"global\" or \"eu\""
                        },
                        "engineVersion": {
                          "type": "string",
                          "description": "\"v2\""
                        },
                        "engineState": {
                          "type": "string",
                          "description": "Present only when the project was still being set up when the call answered (\"provisioning\"); the build starts by itself"
                        },
                        "creditLimits": {
                          "type": "object",
                          "description": "The caps stored on the project, defaults included",
                          "additionalProperties": true
                        },
                        "files": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "The attachments the agent received: { name, imageDescription, url }"
                        },
                        "secrets": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "The secrets stored: { _id, secretName, environment } (never the value)"
                        },
                        "figma": {
                          "type": "object",
                          "description": "{ connected: true, account } when Figma was connected",
                          "additionalProperties": true
                        },
                        "agent": {
                          "type": "object",
                          "properties": {
                            "started": {
                              "type": "boolean",
                              "description": "false = the project exists but the first prompt did not start (see warnings)"
                            },
                            "status": {
                              "type": "string",
                              "description": "\"init\" when the run started"
                            },
                            "runId": {
                              "type": "string",
                              "description": "The run's id"
                            },
                            "message": {
                              "type": "string",
                              "description": "What to do next"
                            },
                            "expectedMinutes": {
                              "type": "number",
                              "description": "Estimated minutes for the first prompt — an estimate, never a deadline"
                            },
                            "expectedFinishAt": {
                              "type": "string",
                              "description": "Start time + expectedMinutes (ISO 8601)"
                            },
                            "warnings": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "Run options that were ignored"
                            }
                          },
                          "additionalProperties": true
                        },
                        "warnings": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "Steps that did not happen after the project was created: { step, errorCode, errorMessage }; step is \"secrets\", \"figma\", \"files\" or \"agent\", and the message names the endpoint that retries it"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "projectId": "barber-bookings",
                    "description": "",
                    "plan": "api",
                    "createdAt": "2026-10-08T10:30:00.000Z",
                    "label": "Barber bookings",
                    "dataResidency": "global",
                    "creditLimits": {
                      "maxDevelopmentCreditsPerMonth": 500,
                      "maxInfrastructureCreditsPerMonth": 300
                    },
                    "files": [],
                    "secrets": [],
                    "agent": {
                      "started": true,
                      "status": "init",
                      "runId": "run_01k6x8m2c9",
                      "message": "Process started. Estimated time: about 9 minutes. This is only an approximation…",
                      "expectedMinutes": 9,
                      "expectedFinishAt": "2026-10-08T10:39:00.000Z"
                    },
                    "warnings": [],
                    "engineVersion": "v2"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`MISSING_PROMPT` — prompt is missing or empty\n`MISSING_PROJECT_ID` — projectId is missing\n`INVALID_PROJECT_NAME` — Not lowercase letters, digits and single hyphens starting with a letter\n`INVALID_PROJECT_NAME_LENGTH` — Not 4–35 characters\n`RESERVED_PROJECT_NAME` — The id contains -dev-\n`INVALID_FILES / TOO_MANY_FILES` — files is not an array of objects, or has more than 10 items\n`INVALID_FILE_NAME / INVALID_FILE_SOURCE / INVALID_FILE_URL / INVALID_FILE_CONTENT` — An attachment has no name, has both or neither of url/content, a non-http(s) URL, or invalid base64\n`INVALID_SECRETS / TOO_MANY_SECRETS / MISSING_SECRET_FIELDS / DUPLICATE_SECRET_NAME / INVALID_SECRET_ENVIRONMENT` — A malformed secrets list\n`INVALID_CREDIT_LIMITS / INVALID_LIMIT` — creditLimits is not an object, or a cap is not a positive number or null\n`INVALID_FIGMA / MISSING_FIGMA_TOKEN / FIGMA_TOKEN_MALFORMED / FIGMA_TOKEN_INVALID / FIGMA_TOKEN_FORBIDDEN` — The Figma token is missing or was rejected\n`INVALID_PROJECT_GROUP` — The group does not exist, is not yours, or is full\n`INVALID_DATA_RESIDENCY` — dataResidency is not \"global\" or \"eu\"\n`INVALID_AUDIENCE_COUNTRY` — audienceCountry is not a two-letter code\n`INVALID_ENGINE_VERSION` — engineVersion has an unknown value",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "`INSUFFICIENT_CREDITS` — Your balance cannot pay the project (or is below 1 credit, needed to start the agent)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "`MAX_PROJECTS_REACHED` — Your plan's project limit is in use. errorDetails: maxProjects, projectsUsed, plan, upgradePlan\n`ENGINE_REQUEST_NOT_ELIGIBLE` — engineVersion: \"v2\" was asked but this account cannot create projects on it yet\n`ENGINE_V2_REQUIRES_PLATFORM_ACCOUNT` — engineVersion: \"v2\" (or a current-engine export code) from an account with no Totalum platform account: sign in once at platform.totalum.app, then retry\n`VCAAS_INSUFFICIENT_CREDITS` — Your balance is below 1 credit",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "`PROJECT_ALREADY_EXISTS` — The name and every suffixed candidate were taken\n`ENGINE_V2_DISABLED` — New projects cannot be created on the current engine right now\n`ENGINE_LEGACY_UNAVAILABLE` — engineVersion: \"legacy\", or a legacy (.zip) export code, on a new account: it creates only on the current engine",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "`RATE_LIMIT_EXCEEDED` — You are creating projects faster than your plan allows (new projects and prompts share one per-minute allowance, see Limits) — retry after Retry-After seconds\n`RATE_LIMITED` — Your account has the most prompts running at once its plan allows, or too many Figma token checks (10 a minute) — retry after Retry-After seconds",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "`LAUNCH_PROJECT_ERROR` — A temporary failure; nothing was created. Retry after Retry-After seconds",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects": {
      "post": {
        "operationId": "createProject",
        "summary": "Create Project",
        "description": "Create an empty project: no prompt, nothing built. Use it only when you will import a project into it, connect GitHub first, or write the files yourself; otherwise use Launch Project.\n\nFull reference: https://www.totalum.app/docs/api/projects#create-project",
        "tags": [
          "Projects"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "projectId": {
                    "type": "string",
                    "description": "Same rules as Launch Project; a taken id gets a suffix"
                  },
                  "label": {
                    "type": "string",
                    "description": "Display name, up to 80 characters"
                  },
                  "description": {
                    "type": "string",
                    "description": "Up to 500 characters"
                  },
                  "groupId": {
                    "type": "string",
                    "description": "An existing project group"
                  },
                  "ownerEmail": {
                    "type": "string",
                    "description": "The e-mail of the app's owner (its admin once confirmed in the app). Default: none — then the first person who signs up in the app becomes its admin after entering the 8-digit code e-mailed to them (the preview and the published app each have their own first sign-up); see Set App Owner"
                  },
                  "engineVersion": {
                    "type": "string",
                    "description": "\"v2\" to require the current engine (new accounts always get it), as in Launch Project"
                  },
                  "dataResidency": {
                    "type": "string",
                    "description": "\"global\" or \"eu\", as in Launch Project"
                  },
                  "audienceCountry": {
                    "type": "string",
                    "description": "Two-letter country code of the app's users"
                  },
                  "sourceImportCode": {
                    "type": "string",
                    "description": "An importCode from Export Project: the new project is created to receive it (checked before anything is created)"
                  },
                  "creditLimits": {
                    "type": "object",
                    "description": "The project's monthly spending caps, as in Launch Project",
                    "properties": {
                      "maxDevelopmentCreditsPerMonth": {
                        "type": [
                          "number",
                          "null"
                        ],
                        "description": "Cap on what the AI agent and project actions spend. Default 5000; null = no cap"
                      },
                      "maxInfrastructureCreditsPerMonth": {
                        "type": [
                          "number",
                          "null"
                        ],
                        "description": "Cap on what the running app spends. Default 300; null = no cap"
                      }
                    },
                    "additionalProperties": true
                  }
                },
                "required": [
                  "projectId"
                ],
                "additionalProperties": true
              },
              "example": {
                "projectId": "crm-import",
                "label": "CRM (imported)",
                "creditLimits": {
                  "maxDevelopmentCreditsPerMonth": 1000,
                  "maxInfrastructureCreditsPerMonth": 500
                }
              }
            }
          }
        },
        "x-totalum-cost": "2 credits",
        "externalDocs": {
          "description": "Create Project — Totalum docs",
          "url": "https://www.totalum.app/docs/api/projects#create-project"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "projectId": {
                          "type": "string",
                          "description": "The id that was created. Use this one"
                        },
                        "requestedProjectId": {
                          "type": "string",
                          "description": "The id you asked for, when it differs"
                        },
                        "description": {
                          "type": "string",
                          "description": "Project description"
                        },
                        "plan": {
                          "type": "string",
                          "description": "Always \"api\""
                        },
                        "createdAt": {
                          "type": "string",
                          "description": "ISO 8601 creation time"
                        },
                        "label": {
                          "type": "string",
                          "description": "The label, when given"
                        },
                        "groupId": {
                          "type": "string",
                          "description": "The group, when given"
                        },
                        "dataResidency": {
                          "type": "string",
                          "description": "\"global\" or \"eu\""
                        },
                        "engineVersion": {
                          "type": "string",
                          "description": "\"v2\""
                        },
                        "engineState": {
                          "type": "string",
                          "description": "\"provisioning\" — the project is being set up"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "projectId": "crm-import",
                    "description": "",
                    "plan": "api",
                    "createdAt": "2026-10-08T10:30:00.000Z",
                    "label": "CRM (imported)",
                    "dataResidency": "global",
                    "engineVersion": "v2",
                    "engineState": "provisioning"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`MISSING_PROJECT_ID / INVALID_PROJECT_NAME / INVALID_PROJECT_NAME_LENGTH / RESERVED_PROJECT_NAME` — The id is missing or malformed\n`INVALID_PROJECT_GROUP` — Unknown or full group\n`INVALID_DATA_RESIDENCY / INVALID_AUDIENCE_COUNTRY / INVALID_ENGINE_VERSION` — An invalid option\n`INVALID_CREDIT_LIMITS / INVALID_LIMIT` — creditLimits is not an object, or a cap is not a positive number or null",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "`INSUFFICIENT_CREDITS` — Not enough credits for the project",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "`MAX_PROJECTS_REACHED` — Your plan's project limit is in use\n`ENGINE_V2_REQUIRES_PLATFORM_ACCOUNT` — engineVersion: \"v2\" (or a current-engine export code) from an account with no Totalum platform account: sign in once at platform.totalum.app, then retry",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "`PROJECT_ALREADY_EXISTS` — The name and every suffixed candidate were taken\n`ENGINE_V2_DISABLED` — New projects cannot be created on the current engine right now\n`ENGINE_LEGACY_UNAVAILABLE` — engineVersion: \"legacy\", or a legacy (.zip) export code, on a new account: it creates only on the current engine",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "`RATE_LIMIT_EXCEEDED` — Too many creates for your plan (new projects and prompts share one per-minute allowance, see Limits); retry after Retry-After seconds",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "`CREATE_PROJECT_ERROR` — A temporary failure; nothing was created. Retry after Retry-After seconds",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listProjects",
        "summary": "List Projects",
        "description": "Your projects, newest first, up to 100 per page. The total is in the X-Total-Count header and X-Has-More says whether another page exists.\n\nFull reference: https://www.totalum.app/docs/api/projects#list-projects",
        "tags": [
          "Projects"
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number"
            },
            "description": "1–100 (default 100)"
          },
          {
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number"
            },
            "description": "Projects to skip, for paging (default 0)"
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Case-insensitive match on id, label and description"
          },
          {
            "name": "sortField",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "date (default, creation time) or lastModified"
          },
          {
            "name": "sortDirection",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "desc (default) or asc"
          },
          {
            "name": "groupId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Only the projects of one group; none = only ungrouped projects"
          },
          {
            "name": "createdFrom",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Created at or after this date (ISO 8601; a bare day is UTC)"
          },
          {
            "name": "createdTo",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Created at or before this date (a bare day includes the whole day)"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "List Projects — Totalum docs",
          "url": "https://www.totalum.app/docs/api/projects#list-projects"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "projectId": {
                            "type": "string",
                            "description": "Project id"
                          },
                          "description": {
                            "type": "string",
                            "description": "Description"
                          },
                          "plan": {
                            "type": "string",
                            "description": "\"api\""
                          },
                          "createdAt": {
                            "type": "string",
                            "description": "ISO 8601 creation time"
                          },
                          "label": {
                            "type": "string",
                            "description": "Display name, when set"
                          },
                          "groupId": {
                            "type": "string",
                            "description": "Group, when filed in one"
                          },
                          "previewImageUrl": {
                            "type": "string",
                            "description": "Screenshot of the home page, once a prompt has finished"
                          },
                          "lastModifiedAt": {
                            "type": "string",
                            "description": "Last change (prompt, publish, edit); never null"
                          },
                          "productionProjectUrl": {
                            "type": "string",
                            "description": "The published host, as on Get Project: the custom domain once it is active, else <projectId>.totalum-project.com (or <projectId>.webapp-project.com when chosen)"
                          },
                          "engineVersion": {
                            "type": "string",
                            "description": "\"v2\""
                          },
                          "liveHostSuffix": {
                            "type": "string",
                            "description": "\"webapp-project.com\" when chosen (Update Project); absent otherwise"
                          }
                        },
                        "additionalProperties": true
                      }
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": [
                    {
                      "projectId": "barber-bookings",
                      "description": "",
                      "plan": "api",
                      "createdAt": "2026-10-08T10:30:00.000Z",
                      "label": "Barber bookings",
                      "previewImageUrl": "https://files.totalum.app/previews/barber-bookings.png",
                      "lastModifiedAt": "2026-10-08T10:41:00.000Z",
                      "productionProjectUrl": "barber-bookings.totalum-project.com",
                      "engineVersion": "v2"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}": {
      "get": {
        "operationId": "getProject",
        "summary": "Get Project",
        "description": "Everything about one project: its URLs, the agent's state, the last publish, its domain, secrets and spending. Read it again after every prompt: the preview address can change.\n\nFull reference: https://www.totalum.app/docs/api/projects#get-project",
        "tags": [
          "Projects"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Project — Totalum docs",
          "url": "https://www.totalum.app/docs/api/projects#get-project"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "projectId": {
                          "type": "string",
                          "description": "Project id"
                        },
                        "label": {
                          "type": "string",
                          "description": "Display name, when set"
                        },
                        "groupId": {
                          "type": "string",
                          "description": "Group, when filed in one"
                        },
                        "description": {
                          "type": "string",
                          "description": "Description"
                        },
                        "plan": {
                          "type": "string",
                          "description": "\"api\""
                        },
                        "createdAt": {
                          "type": "string",
                          "description": "ISO 8601 creation time"
                        },
                        "agentProcessStatus": {
                          "type": "string",
                          "description": "\"init\" (a prompt is running), \"done\" (the last one finished) or \"idle\" (never prompted)"
                        },
                        "agentServerStatus": {
                          "type": "string",
                          "description": "\"Creating\" while the project is set up, \"Archived\" while it sleeps after a long inactivity (the next prompt wakes it), else \"Active\""
                        },
                        "temporalDevelopmentProjectUrl": {
                          "type": "string",
                          "description": "The development preview URL"
                        },
                        "developmentUrlFieldToUse": {
                          "type": "string",
                          "description": "Always \"temporalDevelopmentProjectUrl\""
                        },
                        "productionProjectUrl": {
                          "type": "string",
                          "description": "The published host: the custom domain once it is active, else <projectId>.totalum-project.com (it answers only after the first publish)"
                        },
                        "deployment": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "The last publish: { createdAt, status, versionId }, status = \"deploying\", \"success\" or \"error\", versionId = the version it put online (or tried to); null if never published",
                          "additionalProperties": true
                        },
                        "customDomain": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "{ _id, projectId, deploymentId, hostname, status, sslStatus, dnsRecordsToAdd, createdAt, updatedAt, source? } — see Custom Domains",
                          "additionalProperties": true
                        },
                        "secrets": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "{ _id, secretName, environment } (values are never returned)"
                        },
                        "versionRecovery": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "While a version restore runs or after it failed: { status: \"recovering\" | \"error\", versionId, startedAt, errorMessage? }",
                          "additionalProperties": true
                        },
                        "importInProgress": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "{ startedAt } while an import runs",
                          "additionalProperties": true
                        },
                        "previewImageUrl": {
                          "type": "string",
                          "description": "Screenshot of the home page"
                        },
                        "totalCreditsSpent": {
                          "type": "number",
                          "description": "Credits this project has spent in total"
                        },
                        "creditLimits": {
                          "type": "object",
                          "description": "{ maxDevelopmentCreditsPerMonth, maxInfrastructureCreditsPerMonth }, null = no cap",
                          "additionalProperties": true
                        },
                        "multiPrompt": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "The multi-prompt batch, as on Get Agent Status",
                          "additionalProperties": true
                        },
                        "engineVersion": {
                          "type": "string",
                          "description": "\"v2\""
                        },
                        "engineState": {
                          "type": "string",
                          "description": "\"queued\", \"provisioning\", \"ready\", \"error\", \"suspended\" or \"deleting\""
                        },
                        "liveHostSuffix": {
                          "type": "string",
                          "description": "\"totalum-project.com\" or \"webapp-project.com\": the domain of the main published address and preview (Update Project)"
                        },
                        "dataResidency": {
                          "type": "string",
                          "description": "\"global\" or \"eu\""
                        },
                        "sandbox": {
                          "type": "object",
                          "description": "The builder: { state, lastPromptAt }",
                          "additionalProperties": true
                        },
                        "lifecycle": {
                          "type": "object",
                          "description": "{ state, nextStep, lastActivityAt, pausedAt, resumable } — see Pause Project",
                          "additionalProperties": true
                        },
                        "preview": {
                          "type": "object",
                          "description": "{ url, token8, status, deployState }: the preview address and whether its latest build is live (status: \"live\", \"deploying\", \"failed\", \"parked\", \"none\")",
                          "additionalProperties": true
                        },
                        "lastDeployError": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "Why the last preview or publish build failed, when it did",
                          "additionalProperties": true
                        },
                        "currentRun": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "The running prompt: { id, state, startedAt, batchId?, promptPreview }",
                          "additionalProperties": true
                        },
                        "state": {
                          "type": "string",
                          "description": "\"active\" or \"paused-by-user\""
                        },
                        "pausedAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "When it was paused"
                        },
                        "resumable": {
                          "type": "boolean",
                          "description": "Whether a paused project can be resumed"
                        },
                        "runawayPause": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "Set while the emergency stop has paused the site: { pausedAt, resumesAt, metric, value?, threshold? } — see Release Runaway Pause",
                          "additionalProperties": true
                        },
                        "contextClearPending": {
                          "type": "boolean",
                          "description": "The next prompt starts with a fresh context"
                        },
                        "operations": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "Long operations running now (publish, restore, import…): { kind, id, status, startedAt, errorMessage?, versionId?, progress? }"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "projectId": "barber-bookings",
                    "label": "Barber bookings",
                    "description": "",
                    "plan": "api",
                    "agentProcessStatus": "done",
                    "createdAt": "2026-10-08T10:30:00.000Z",
                    "agentServerStatus": "Active",
                    "deployment": {
                      "createdAt": "2026-10-08T11:02:00.000Z",
                      "status": "success",
                      "versionId": "ver_01k6xd2m4n6p8q0r2s4t6v8w0y"
                    },
                    "versionRecovery": null,
                    "importInProgress": null,
                    "secrets": [
                      {
                        "_id": "sec_01k6x9",
                        "secretName": "STRIPE_KEY",
                        "environment": "production"
                      }
                    ],
                    "customDomain": null,
                    "developmentUrlFieldToUse": "temporalDevelopmentProjectUrl",
                    "temporalDevelopmentProjectUrl": "https://barber-bookings-dev-temporal-link-preview-k3y9x2ab.totalum-project.com",
                    "productionProjectUrl": "barber-bookings.totalum-project.com",
                    "totalCreditsSpent": 24.6,
                    "creditLimits": {
                      "maxDevelopmentCreditsPerMonth": 500,
                      "maxInfrastructureCreditsPerMonth": 300
                    },
                    "multiPrompt": null,
                    "engineVersion": "v2",
                    "engineState": "ready",
                    "dataResidency": "global",
                    "sandbox": {
                      "state": "active",
                      "lastPromptAt": "2026-10-08T10:30:05.000Z"
                    },
                    "preview": {
                      "url": "https://barber-bookings-dev-temporal-link-preview-k3y9x2ab.totalum-project.com",
                      "token8": "k3y9x2ab",
                      "status": "live",
                      "deployState": "idle"
                    },
                    "lastDeployError": null,
                    "currentRun": null,
                    "state": "active",
                    "pausedAt": null,
                    "resumable": false,
                    "contextClearPending": false,
                    "operations": []
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "`API_ACCESS_DISABLED` — API access is switched off for this project in your account settings\n`PROJECT_NOT_ALLOWED` — Your API key is restricted to other projects",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "`PROJECT_NOT_FOUND` — No project with this id in your account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateProject",
        "summary": "Update Project",
        "description": "Change the label, the description, the group or the live address's domain. The project id never changes. A field you leave out is untouched; null clears it.\n\nFull reference: https://www.totalum.app/docs/api/projects#update-project",
        "tags": [
          "Projects"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "label": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Display name, up to 80 characters; null clears it"
                  },
                  "description": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Up to 500 characters; null clears it"
                  },
                  "groupId": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "An existing group; null takes the project out of its group"
                  },
                  "liveHostSuffix": {
                    "type": "string",
                    "description": "\"totalum-project.com\" (default) or \"webapp-project.com\" — the main domain of the published site and its preview, e.g. <projectId>.webapp-project.com. webapp-project.com needs the Professional or Enterprise plan. On those plans both domains serve the site and its preview; this setting only picks the main one (productionProjectUrl, canonical and sitemap links). Links inside your app follow at your next publish. If the account moves to a lower plan, the project goes back to totalum-project.com and its webapp-project.com address redirects for 90 days."
                  }
                },
                "additionalProperties": true
              },
              "example": {
                "label": "Barber shop",
                "groupId": null
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Update Project — Totalum docs",
          "url": "https://www.totalum.app/docs/api/projects#update-project"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "projectId": {
                          "type": "string",
                          "description": "Project id"
                        },
                        "label": {
                          "type": "string",
                          "description": "The label after the change"
                        },
                        "description": {
                          "type": "string",
                          "description": "The description after the change"
                        },
                        "groupId": {
                          "type": "string",
                          "description": "The group after the change"
                        },
                        "liveHostSuffix": {
                          "type": "string",
                          "description": "The domain chosen, when liveHostSuffix was sent"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "projectId": "barber-bookings",
                    "label": "Barber shop",
                    "description": ""
                  }
                }
              }
            }
          },
          "400": {
            "description": "`NOTHING_TO_UPDATE` — None of label, description, groupId, liveHostSuffix was sent\n`INVALID_LIVE_HOST_SUFFIX` — liveHostSuffix is not totalum-project.com or webapp-project.com\n`INVALID_PROJECT_GROUP` — The group does not exist or is not yours",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "`PLAN_REQUIRED` — webapp-project.com needs the Professional or Enterprise plan (errorDetails.upgradePlan)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "`PROJECT_NOT_FOUND` — No such project in your account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "`AGENT_RUNNING / OPERATION_IN_PROGRESS` — A prompt, an operation or a preview deploy is in progress; try again when it ends",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteProject",
        "summary": "Delete Project",
        "description": "Permanently delete a project: its published site, preview, custom domain, databases, files and versions. It cannot be undone, and its id can never be used again. Deleting is free and always allowed, whatever your balance.\n\nFull reference: https://www.totalum.app/docs/api/projects#delete-project",
        "tags": [
          "Projects"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Delete Project — Totalum docs",
          "url": "https://www.totalum.app/docs/api/projects#delete-project"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "success": {
                          "type": "boolean",
                          "description": "true"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "success": true
                  }
                }
              }
            }
          },
          "400": {
            "description": "`PLAN_NOT_API` — The project was not created through the API or the Totalum app's API plan and cannot be deleted here",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "404": {
            "description": "`PROJECT_NOT_FOUND` — No such project in your account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/state": {
      "get": {
        "operationId": "getProjectState",
        "summary": "Get Project State",
        "description": "The project's live state in one read: what is running, the preview, the lifecycle and any long operation with its progress (for example the copy of a database move to Turso).\n\nFull reference: https://www.totalum.app/docs/api/projects#get-project-state",
        "tags": [
          "Projects"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Project State — Totalum docs",
          "url": "https://www.totalum.app/docs/api/projects#get-project-state"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "projectId": {
                          "type": "string",
                          "description": "Project id"
                        },
                        "engineVersion": {
                          "type": "string",
                          "description": "\"v2\""
                        },
                        "state": {
                          "type": "string",
                          "description": "\"queued\", \"provisioning\", \"ready\", \"error\", \"suspended\" or \"deleting\""
                        },
                        "lifecycle": {
                          "type": "object",
                          "description": "{ state, nextStep: { kind, at } | null, lastActivityAt, pausedAt, resumable }",
                          "additionalProperties": true
                        },
                        "sandbox": {
                          "type": "object",
                          "description": "{ state, lastPromptAt }",
                          "additionalProperties": true
                        },
                        "preview": {
                          "type": "object",
                          "description": "{ temporalLinkUrl, token8, versionId?, status, deploy: { state, fixAttempt?, error? } }",
                          "additionalProperties": true
                        },
                        "lastDeployError": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "The last failed preview or publish build",
                          "additionalProperties": true
                        },
                        "run": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "The running prompt: { id, state, startedAt, batchId?, promptPreview }",
                          "additionalProperties": true
                        },
                        "batch": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "The newest multi-prompt batch",
                          "additionalProperties": true
                        },
                        "contextClearPending": {
                          "type": "boolean",
                          "description": "The next prompt starts fresh"
                        },
                        "operations": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "{ kind, id, status, startedAt, errorMessage?, versionId?, progress? }"
                        },
                        "liveHostSuffix": {
                          "type": "string",
                          "description": "Domain of the published host"
                        },
                        "liveUrl": {
                          "type": "string",
                          "description": "Published URL"
                        },
                        "dataResidency": {
                          "type": "string",
                          "description": "\"global\" or \"eu\""
                        },
                        "updatedAt": {
                          "type": "string",
                          "description": "When this state last changed"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "projectId": "barber-bookings",
                    "engineVersion": "v2",
                    "state": "ready",
                    "lifecycle": {
                      "state": "active",
                      "nextStep": null,
                      "lastActivityAt": "2026-10-08T11:02:00.000Z",
                      "pausedAt": null,
                      "resumable": false
                    },
                    "sandbox": {
                      "state": "active",
                      "lastPromptAt": "2026-10-08T10:30:05.000Z"
                    },
                    "preview": {
                      "temporalLinkUrl": "https://barber-bookings-dev-temporal-link-preview-k3y9x2ab.totalum-project.com",
                      "token8": "k3y9x2ab",
                      "status": "live",
                      "deploy": {
                        "state": "idle"
                      }
                    },
                    "lastDeployError": null,
                    "run": null,
                    "batch": null,
                    "contextClearPending": false,
                    "operations": [],
                    "liveHostSuffix": "totalum-project.com",
                    "liveUrl": "https://barber-bookings.totalum-project.com",
                    "dataResidency": "global",
                    "updatedAt": "2026-10-08T11:02:00.000Z"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/pause": {
      "post": {
        "operationId": "pauseProject",
        "summary": "Pause Project",
        "description": "Take the whole project offline so it consumes nothing: the published site and the preview show a paused page and the databases are saved first. Answers 202 while the pause runs; follow it on Get Project State (lifecycle.state becomes paused-by-user).\n\nFull reference: https://www.totalum.app/docs/api/projects#pause-project",
        "tags": [
          "Projects"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "x-totalum-cost": "2 credits",
        "externalDocs": {
          "description": "Pause Project — Totalum docs",
          "url": "https://www.totalum.app/docs/api/projects#pause-project"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "accepted": {
                          "type": "boolean",
                          "description": "true"
                        },
                        "state": {
                          "type": "string",
                          "description": "The lifecycle state now"
                        },
                        "operation": {
                          "type": "object",
                          "description": "The operation started: { kind, id, startedAt, estimateSec }. Absent (and 200) when the project was already paused",
                          "additionalProperties": true
                        },
                        "creditsCharged": {
                          "type": "number",
                          "description": "Credits charged (0 when nothing started)"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "accepted": true,
                    "state": "active",
                    "operation": {
                      "kind": "pause",
                      "id": "op_01k6xa",
                      "startedAt": "2026-10-08T12:00:00.000Z",
                      "estimateSec": 60
                    },
                    "creditsCharged": 2
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "`INSUFFICIENT_CREDITS` — Not enough credits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "409": {
            "description": "`AGENT_RUNNING` — A prompt is running; wait for it\n`DEPLOYMENT_RUNNING` — A publish is running\n`OPERATION_IN_PROGRESS` — Another long operation is running\n`LIFECYCLE_NOT_APPLICABLE` — The project is asleep after a long inactivity: prompt it (or restart its server) to wake it first",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/resume": {
      "post": {
        "operationId": "resumeProject",
        "summary": "Resume Project",
        "description": "Bring a paused project back: databases restored, preview and published site online again. Answers 202 while it runs.\n\nFull reference: https://www.totalum.app/docs/api/projects#resume-project",
        "tags": [
          "Projects"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "x-totalum-cost": "2 credits",
        "externalDocs": {
          "description": "Resume Project — Totalum docs",
          "url": "https://www.totalum.app/docs/api/projects#resume-project"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "accepted": {
                          "type": "boolean",
                          "description": "true"
                        },
                        "state": {
                          "type": "string",
                          "description": "The lifecycle state now"
                        },
                        "operation": {
                          "type": "object",
                          "description": "{ kind, id, startedAt, estimateSec }",
                          "additionalProperties": true
                        },
                        "creditsCharged": {
                          "type": "number",
                          "description": "Credits charged"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "accepted": true,
                    "state": "paused-by-user",
                    "operation": {
                      "kind": "resume",
                      "id": "op_01k6xb",
                      "startedAt": "2026-10-09T08:00:00.000Z",
                      "estimateSec": 90
                    },
                    "creditsCharged": 2
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "`INSUFFICIENT_CREDITS` — Not enough credits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "409": {
            "description": "`PROJECT_NOT_PAUSED` — The project is not paused\n`OPERATION_IN_PROGRESS` — Another long operation is running",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "410": {
            "description": "`PAUSE_DUMP_EXPIRED` — The saved databases of this pause are gone; the project cannot be resumed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/runaway/release": {
      "post": {
        "operationId": "releaseRunawayPause",
        "summary": "Release Runaway Pause",
        "description": "Bring a site back online after the emergency stop paused it. The emergency stop pauses a project when its app uses far more than normal (for example a loop that sends thousands of requests or spends credits on built-in features every minute): the site shows a paused page, the app's calls to Totalum answer 429 PROJECT_PAUSED_RUNAWAY, and you get an e-mail and the project.kill_switch.fired webhook. The pause lifts by itself after 24 hours (runawayPause.resumesAt on Get Project); this call lifts it now. Fix the cause first, or the same usage pauses it again. Free at any balance; the site answers again within about a minute. A project that is not paused by the emergency stop answers 200 with released: false and nothing changes. This is not Resume Project, which brings back a project you paused yourself.\n\nFull reference: https://www.totalum.app/docs/api/projects#release-runaway-pause",
        "tags": [
          "Projects"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Release Runaway Pause — Totalum docs",
          "url": "https://www.totalum.app/docs/api/projects#release-runaway-pause"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "released": {
                          "type": "boolean",
                          "description": "true when the pause was lifted, false when the project was not paused by the emergency stop"
                        },
                        "message": {
                          "type": "string",
                          "description": "What happened, in plain words"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "released": true,
                    "message": "The site is back online; it can take up to a minute to show everywhere."
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/preview/rotate-url": {
      "post": {
        "operationId": "rotatePreviewUrl",
        "summary": "Rotate Preview URL",
        "description": "Give the development preview a new address; the old one stops working at once. The preview address also changes by itself every month, so never store it: read temporalDevelopmentProjectUrl from Get Project. The published site and custom domains never change. Owner (or a member allowed to manage API keys) only; at most once a minute.\n\nFull reference: https://www.totalum.app/docs/api/projects#rotate-preview-url",
        "tags": [
          "Projects"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Rotate Preview URL — Totalum docs",
          "url": "https://www.totalum.app/docs/api/projects#rotate-preview-url"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "temporalLinkUrl": {
                          "type": "string",
                          "description": "The new preview address"
                        },
                        "rotatedAt": {
                          "type": "string",
                          "description": "ISO 8601 time of the change"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "temporalLinkUrl": "https://barber-bookings-dev-temporal-link-preview-p7m2q9rt.totalum-project.com",
                    "rotatedAt": "2026-10-08T12:00:00.000Z"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "`OWNER_ONLY` — Only the owner or a member allowed to manage API keys",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "`AGENT_RUNNING` — A prompt is running\n`OPERATION_IN_PROGRESS` — A publish or other operation is running",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "`RATE_LIMIT_EXCEEDED` — Rotated less than a minute ago",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/owner-email": {
      "put": {
        "operationId": "setAppOwner",
        "summary": "Set App Owner",
        "description": "Set who owns the generated app. The owner's e-mail is the app's admin: after signing up in the app with that address, that person enters the 8-digit code e-mailed to them (the app asks for it right after sign-up) and then has the admin and staff pages. The default is none: in a project without an owner e-mail, the first person who signs up in the app becomes its admin after entering the 8-digit code e-mailed to them (the preview and the published app each have their own first sign-up). If your users build apps through your product, set each project's owner to your user's e-mail, best at Launch Project with ownerEmail. The running preview and published app use the new address at once, with no rebuild. GET on the same path reads it; it answers ownerEmail: null when none is set. Projects created earlier keep the owner they had. The project's owner can also set, change or remove it by asking the project's coding agent in a prompt (\"set the owner e-mail to ana@example.com\", \"remove the owner e-mail\"): the agent changes only its own project, with the same effect. Current engine only.\n\nFull reference: https://www.totalum.app/docs/api/projects#set-app-owner",
        "tags": [
          "Projects"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "ownerEmail": {
                    "type": "string",
                    "description": "The owner's e-mail (email is accepted too). Stored in lower case"
                  }
                },
                "required": [
                  "ownerEmail"
                ],
                "additionalProperties": true
              },
              "example": {
                "ownerEmail": "ana@example.com"
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Set App Owner — Totalum docs",
          "url": "https://www.totalum.app/docs/api/projects#set-app-owner"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "ownerEmail": {
                          "type": "string",
                          "description": "The owner's e-mail now in effect"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "ownerEmail": "ana@example.com"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`INVALID_OWNER_EMAIL` — ownerEmail is not a valid e-mail address (also answered by Launch and Create Project)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "404": {
            "description": "`PROJECT_NOT_FOUND` — No project with this id in your account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/agent/start": {
      "post": {
        "operationId": "runAiAgent",
        "summary": "Run AI Agent",
        "description": "Send one prompt to the agent (or a multi-prompt batch). One run at a time per project. Once the running prompt's change is in the preview and the run is only finishing, the next prompt is accepted and waits: it starts as soon as that run ends. One prompt can wait; Stop Agent cancels the waiting one first.\n\nFull reference: https://www.totalum.app/docs/api/agent#run-ai-agent",
        "tags": [
          "AI Agent"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "prompt": {
                    "type": "string",
                    "description": "The instruction, up to 40,000 characters"
                  },
                  "tier": {
                    "type": "string",
                    "description": "\"auto\" (default), \"cheap\", \"normal\" or \"expensive\" — see Agent tiers. model and modelTier are accepted as aliases"
                  },
                  "inputFiles": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "name": {
                          "type": "string",
                          "description": "File name"
                        },
                        "imageDescription": {
                          "type": "string",
                          "description": "What the file shows"
                        },
                        "url": {
                          "type": "string",
                          "description": "Public URL, or the url returned by Upload File"
                        }
                      },
                      "required": [
                        "name",
                        "url"
                      ],
                      "additionalProperties": true
                    },
                    "description": "Up to 10 files for this prompt. Say in the prompt what each one is for (\"use this as the logo\")"
                  },
                  "multiPrompt": {
                    "type": "object",
                    "description": "Run a batch of prompts one after another, unattended. Omit for normal use",
                    "properties": {
                      "prompts": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "description": "1–50 prompts, run in order"
                      },
                      "letTotalumDecide": {
                        "type": "boolean",
                        "description": "true = Totalum plans the prompts from prompt (the goal)"
                      }
                    },
                    "additionalProperties": true
                  }
                },
                "required": [
                  "prompt"
                ],
                "additionalProperties": true
              },
              "example": {
                "prompt": "Add a contact form that emails me every message"
              }
            }
          }
        },
        "x-totalum-cost": "Metered, at least 3 credits",
        "externalDocs": {
          "description": "Run AI Agent — Totalum docs",
          "url": "https://www.totalum.app/docs/api/agent#run-ai-agent"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "projectId": {
                          "type": "string",
                          "description": "Project id"
                        },
                        "status": {
                          "type": "string",
                          "description": "Always \"init\""
                        },
                        "message": {
                          "type": "string",
                          "description": "How to follow the run"
                        },
                        "expectedMinutes": {
                          "type": "number",
                          "description": "Estimated minutes — an estimate, never a deadline"
                        },
                        "expectedFinishAt": {
                          "type": "string",
                          "description": "Start + expectedMinutes (ISO 8601)"
                        },
                        "warnings": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Options that were ignored"
                        },
                        "runId": {
                          "type": "string",
                          "description": "The run's id (single prompt)"
                        },
                        "multiPrompt": {
                          "type": "object",
                          "properties": {
                            "totalPrompts": {
                              "type": "number",
                              "description": "Batches only: number of prompts (absent while Totalum plans them)"
                            }
                          },
                          "additionalProperties": true
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "projectId": "barber-bookings",
                    "status": "init",
                    "message": "Process started. Estimated time: about 6 minutes. This is only an approximation… Fetch GET /api/v1/vcaas/projects/barber-bookings/agent/status every 10-15 seconds to track progress; the status there is the only reliable signal that the run has finished.",
                    "expectedMinutes": 6,
                    "expectedFinishAt": "2026-10-08T11:16:00.000Z",
                    "runId": "run_01k6xc4n7d"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`MISSING_PROMPT` — prompt is missing\n`INVALID_MULTI_PROMPT` — multiPrompt needs exactly one of prompts or letTotalumDecide: true\n`TOO_MANY_PROMPTS` — More than 50 prompts\n`INVALID_PROMPT_ITEM` — A prompt in prompts is empty\n`VALIDATION_ERROR` — The prompt is over 40,000 characters, or a field has the wrong type",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "`INSUFFICIENT_CREDITS` — Your balance is below 1 credit",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "`PROJECT_CREDIT_LIMIT_REACHED` — The project's monthly development cap is reached — raise it with Update Credit Limits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "`PROJECT_NOT_FOUND` — No such project in your account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "`AGENT_RUNNING` — A prompt is already running and its change is not in the preview yet, or a prompt is already waiting (a batch answers 400 AGENT_ALREADY_RUNNING)\n`PROJECT_PAUSED_BY_USER` — The project is paused — resume it first\n`OPERATION_IN_PROGRESS` — A restore, import or other long operation holds the project",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "`RATE_LIMITED` — Your account sent more prompts this minute than its plan allows, or has the most prompts running at once (all projects together, see Limits) — retry after Retry-After seconds",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/agent/status": {
      "get": {
        "operationId": "getAgentStatus",
        "summary": "Get Agent Status",
        "description": "Whether a prompt is running, and the messages of the current (or last) run. Poll every 10–15 seconds. When status becomes \"done\", read the preview URL again from Get Project.\n\nFull reference: https://www.totalum.app/docs/api/agent#get-agent-status",
        "tags": [
          "AI Agent"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Agent Status — Totalum docs",
          "url": "https://www.totalum.app/docs/api/agent#get-agent-status"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "projectId": {
                          "type": "string",
                          "description": "Project id"
                        },
                        "status": {
                          "type": "string",
                          "description": "\"init\" (running), \"done\" (the last run finished) or \"idle\" (never prompted)"
                        },
                        "startedAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Start of the current or last run"
                        },
                        "runId": {
                          "type": "string",
                          "description": "The current or last run"
                        },
                        "realtimeConversation": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "author": {
                                "type": "string",
                                "description": "\"user\" or \"agent\""
                              },
                              "message": {
                                "type": "string",
                                "description": "Text"
                              },
                              "messageType": {
                                "type": "string",
                                "description": "\"regular\", \"starting\", \"building\" (a status note), \"finished\" (the run's summary), \"error\", \"limit-reached\" or \"individual\" (a one-off notice)"
                              },
                              "createdAt": {
                                "type": "string",
                                "description": "ISO 8601"
                              },
                              "versionId": {
                                "type": "string",
                                "description": "The version this message created"
                              },
                              "secretKeysNeeded": {
                                "type": "object",
                                "description": "Secrets the app needs: { NAME: { isProvided, description } }. Add them with Create Secret",
                                "additionalProperties": true
                              },
                              "files": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "additionalProperties": true
                                },
                                "description": "Files attached to the message"
                              },
                              "autoMode": {
                                "type": "boolean",
                                "description": "true on the final message of an auto run"
                              },
                              "modelUsed": {
                                "type": "string",
                                "description": "The tier an auto run used"
                              }
                            },
                            "additionalProperties": true
                          },
                          "description": "The run's messages, oldest first (the user's prompt is in Get Full Conversation)"
                        },
                        "creditsSpent": {
                          "type": "number",
                          "description": "What the last run cost, once \"done\""
                        },
                        "expectedMinutes": {
                          "type": [
                            "number",
                            "null"
                          ],
                          "description": "Estimate of the running prompt"
                        },
                        "expectedFinishAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Start + estimate"
                        },
                        "multiPrompt": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "The batch, when one exists: { status, totalPrompts, currentPromptIndex, prompts[{ order, prompt, status }], startedAt, updatedAt }. status: \"executing\", \"paused\", \"done\", \"cancelled\"",
                          "additionalProperties": true
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "projectId": "barber-bookings",
                    "status": "done",
                    "startedAt": "2026-10-08T11:10:00.000Z",
                    "realtimeConversation": [
                      {
                        "author": "agent",
                        "message": "Added a contact form on /contact. Every message is saved and e-mailed to you. I sent a test message: saved, 200.",
                        "messageType": "finished",
                        "versionId": "ver_01k6xd2m8q",
                        "createdAt": "2026-10-08T11:15:40.000Z",
                        "autoMode": true,
                        "modelUsed": "normal"
                      }
                    ],
                    "creditsSpent": 7.4,
                    "expectedMinutes": null,
                    "expectedFinishAt": null,
                    "multiPrompt": null,
                    "runId": "run_01k6xc4n7d"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/agent/progress": {
      "get": {
        "operationId": "getAgentProgress",
        "summary": "Get Agent Progress",
        "description": "A step-by-step view of the current run (or the last one): its stage, the files it changed, the builds and checks it ran. Use it to show a live \"building\" timeline. data is null before the first run.\n\nFull reference: https://www.totalum.app/docs/api/agent#get-agent-progress",
        "tags": [
          "AI Agent"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Agent Progress — Totalum docs",
          "url": "https://www.totalum.app/docs/api/agent#get-agent-progress"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "runId": {
                          "type": "string",
                          "description": "The run"
                        },
                        "state": {
                          "type": "string",
                          "description": "\"queued\", \"provisioning\", \"running\", \"finishing\", \"done\", \"failed\", \"cancelled\" or \"incomplete\""
                        },
                        "stage": {
                          "type": "string",
                          "description": "Where the run is: \"queued\", \"sandbox\", \"starting\", \"thinking\", \"working\", \"build\", \"deploy\", \"fixing\", \"wrapping-up\", \"entry-page\", \"done\", \"failed\", \"cancelled\", \"incomplete\""
                        },
                        "startedAt": {
                          "type": "string",
                          "description": "Start time"
                        },
                        "finishedAt": {
                          "type": "string",
                          "description": "End time"
                        },
                        "turns": {
                          "type": "number",
                          "description": "Agent turns so far"
                        },
                        "steps": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "Up to the 40 latest steps: { at, kind, file?, task?, ok?, added?, removed? }. kind: read, search, create, edit, delete, command, web, browser, integration, helper, plan, waiting; task (commands): build, test, install, database, check, save, other"
                        },
                        "totalSteps": {
                          "type": "number",
                          "description": "All steps of the run"
                        },
                        "files": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "Files changed: { path, change: \"create\" | \"edit\" | \"delete\", added, removed }"
                        },
                        "counts": {
                          "type": "object",
                          "description": "{ reads, searches, edits, commands, failedCommands }",
                          "additionalProperties": true
                        },
                        "build": {
                          "type": "object",
                          "description": "{ ok } of the last build",
                          "additionalProperties": true
                        },
                        "tests": {
                          "type": "object",
                          "description": "{ runs, failed, failedFlows? }: the checks the agent ran on the pages it changed",
                          "additionalProperties": true
                        },
                        "versionId": {
                          "type": "string",
                          "description": "The version the run saved"
                        },
                        "failure": {
                          "type": "string",
                          "description": "Why it failed: INSUFFICIENT_CREDITS, PROJECT_CREDIT_LIMIT_REACHED, DEPLOY_FAILED, RUN_TIMED_OUT, RUN_INTERRUPTED, CONTENT_BLOCKED, … or OTHER"
                        },
                        "creditsSpent": {
                          "type": "number",
                          "description": "What the run cost, once it ended"
                        },
                        "previewAt": {
                          "type": "string",
                          "description": "When the preview last started serving this run's new build (reload your preview frame when it changes)"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "runId": "run_01k6xc4n7d",
                    "state": "running",
                    "stage": "working",
                    "startedAt": "2026-10-08T11:10:00.000Z",
                    "turns": 12,
                    "steps": [
                      {
                        "at": "2026-10-08T11:12:01.000Z",
                        "kind": "edit",
                        "file": "src/app/contact/page.tsx",
                        "added": 64,
                        "removed": 0
                      },
                      {
                        "at": "2026-10-08T11:12:30.000Z",
                        "kind": "command",
                        "task": "database",
                        "ok": true
                      }
                    ],
                    "totalSteps": 18,
                    "files": [
                      {
                        "path": "src/app/contact/page.tsx",
                        "change": "create",
                        "added": 64,
                        "removed": 0
                      }
                    ],
                    "counts": {
                      "reads": 6,
                      "searches": 2,
                      "edits": 4,
                      "commands": 3,
                      "failedCommands": 0
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/agent/full-conversation": {
      "get": {
        "operationId": "getFullConversation",
        "summary": "Get Full Conversation",
        "description": "The project's whole chat: every prompt and every agent message, oldest first (the latest 1,000).\n\nFull reference: https://www.totalum.app/docs/api/agent#get-full-conversation",
        "tags": [
          "AI Agent"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Full Conversation — Totalum docs",
          "url": "https://www.totalum.app/docs/api/agent#get-full-conversation"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "projectId": {
                          "type": "string",
                          "description": "Project id"
                        },
                        "conversation": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "Messages with the fields of realtimeConversation[] in Get Agent Status"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "projectId": "barber-bookings",
                    "conversation": [
                      {
                        "author": "user",
                        "message": "Add a contact form that emails me every message",
                        "messageType": "regular",
                        "createdAt": "2026-10-08T11:10:00.000Z"
                      },
                      {
                        "author": "agent",
                        "message": "Added a contact form on /contact…",
                        "messageType": "finished",
                        "versionId": "ver_01k6xd2m8q",
                        "createdAt": "2026-10-08T11:15:40.000Z"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/agent/stop": {
      "post": {
        "operationId": "stopAgent",
        "summary": "Stop Agent",
        "description": "Stop the running prompt (and the rest of a multi-prompt batch). What the run built so far is kept; you pay only for what it used.\n\nFull reference: https://www.totalum.app/docs/api/agent#stop-agent",
        "tags": [
          "AI Agent"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Stop Agent — Totalum docs",
          "url": "https://www.totalum.app/docs/api/agent#stop-agent"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "\"Agent process cancelled successfully\""
                        },
                        "paused": {
                          "type": "boolean",
                          "description": "false"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "message": "Agent process cancelled successfully",
                    "paused": false
                  }
                }
              }
            }
          },
          "400": {
            "description": "`NO_PROCESS_RUNNING` — No prompt is running",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/agent/multi-prompt/resume": {
      "post": {
        "operationId": "resumeMultiPromptBatch",
        "summary": "Resume Multi-Prompt Batch",
        "description": "When a prompt of a batch fails, the batch pauses there (multiPrompt.status: \"paused\") because the next prompts build on it. This runs the failed prompt again, then the rest. Stop Agent cancels the batch instead.\n\nFull reference: https://www.totalum.app/docs/api/agent#resume-multi-prompt-batch",
        "tags": [
          "AI Agent"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "x-totalum-cost": "The prompts it runs",
        "externalDocs": {
          "description": "Resume Multi-Prompt Batch — Totalum docs",
          "url": "https://www.totalum.app/docs/api/agent#resume-multi-prompt-batch"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "projectId": {
                          "type": "string",
                          "description": "Project id"
                        },
                        "status": {
                          "type": "string",
                          "description": "\"init\""
                        },
                        "message": {
                          "type": "string",
                          "description": "Which prompt the batch continues from"
                        },
                        "multiPrompt": {
                          "type": "object",
                          "properties": {
                            "totalPrompts": {
                              "type": "number",
                              "description": "Prompts in the batch"
                            }
                          },
                          "additionalProperties": true
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "projectId": "barber-bookings",
                    "status": "init",
                    "message": "Multi-prompt run continued from prompt 2.",
                    "multiPrompt": {
                      "totalPrompts": 3
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`INVALID_AUTO_STATUS` — No batch is paused\n`AGENT_RUNNING` — A prompt is running",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/agent/clear-context": {
      "post": {
        "operationId": "clearAgentContext",
        "summary": "Clear Agent Context",
        "description": "The next prompt starts with a fresh agent memory: it works from the project's current code and its change history, plus the messages sent after the clear. Restate anything from before that still matters.\n\nFull reference: https://www.totalum.app/docs/api/agent#clear-agent-context",
        "tags": [
          "AI Agent"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Clear Agent Context — Totalum docs",
          "url": "https://www.totalum.app/docs/api/agent#clear-agent-context"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "\"Agent context cleared\""
                        },
                        "contextClearPending": {
                          "type": "boolean",
                          "description": "true until the next prompt starts"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "message": "Agent context cleared",
                    "contextClearPending": true
                  }
                }
              }
            }
          },
          "400": {
            "description": "`AGENT_RUNNING` — A prompt is running",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/agent/system-prompt": {
      "get": {
        "operationId": "getSystemPrompt",
        "summary": "Get System Prompt",
        "description": "The project's own instructions for the agent, added to every prompt (house style, rules, context).\n\nFull reference: https://www.totalum.app/docs/api/agent#get-system-prompt",
        "tags": [
          "AI Agent"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get System Prompt — Totalum docs",
          "url": "https://www.totalum.app/docs/api/agent#get-system-prompt"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "systemPrompt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "The instructions, or null"
                        },
                        "updatedAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "When they were last set"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "systemPrompt": "Write every page in Spanish. Use our brand blue #1d4ed8.",
                    "updatedAt": "2026-10-08T09:00:00.000Z"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      },
      "put": {
        "operationId": "setSystemPrompt",
        "summary": "Set System Prompt",
        "description": "Set or clear the project's instructions for the agent.\n\nFull reference: https://www.totalum.app/docs/api/agent#set-system-prompt",
        "tags": [
          "AI Agent"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "systemPrompt": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Up to 20,000 characters; null or \"\" clears it"
                  },
                  "systemPromptBase64": {
                    "type": "string",
                    "description": "The same text as base64 (UTF-8), instead of systemPrompt"
                  }
                },
                "required": [
                  "systemPrompt"
                ],
                "additionalProperties": true
              },
              "example": {
                "systemPrompt": "Write every page in Spanish. Use our brand blue #1d4ed8."
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Set System Prompt — Totalum docs",
          "url": "https://www.totalum.app/docs/api/agent#set-system-prompt"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "systemPrompt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "The saved instructions"
                        },
                        "updatedAt": {
                          "type": "string",
                          "description": "When they were saved"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "systemPrompt": "Write every page in Spanish. Use our brand blue #1d4ed8.",
                    "updatedAt": "2026-10-08T09:00:00.000Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`VALIDATION_ERROR` — Not text, or over 20,000 characters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/agent/mcp-servers": {
      "get": {
        "operationId": "listMcpServers",
        "summary": "List MCP Servers",
        "description": "The MCP servers you added for the agent to use while it builds (header values are never returned).\n\nFull reference: https://www.totalum.app/docs/api/agent#list-mcp-servers",
        "tags": [
          "AI Agent"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "List MCP Servers — Totalum docs",
          "url": "https://www.totalum.app/docs/api/agent#list-mcp-servers"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "servers": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "description": "Server id"
                              },
                              "name": {
                                "type": "string",
                                "description": "Name"
                              },
                              "transport": {
                                "type": "string",
                                "description": "\"http\" or \"sse\""
                              },
                              "url": {
                                "type": "string",
                                "description": "Server URL"
                              },
                              "headerNames": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                },
                                "description": "Names of the headers sent (values are write-only)"
                              },
                              "enabled": {
                                "type": "boolean",
                                "description": "Whether the agent uses it"
                              },
                              "verifiedAt": {
                                "type": "string",
                                "description": "When it last answered the handshake"
                              },
                              "tools": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                },
                                "description": "Its tools"
                              },
                              "createdAt": {
                                "type": "string",
                                "description": "When it was added"
                              }
                            },
                            "additionalProperties": true
                          },
                          "description": "The servers"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "servers": [
                      {
                        "id": "mcp_01k6xe",
                        "name": "crm",
                        "transport": "http",
                        "url": "https://mcp.example.com/mcp",
                        "headerNames": [
                          "Authorization"
                        ],
                        "enabled": true,
                        "verifiedAt": "2026-10-08T09:00:00.000Z",
                        "tools": [
                          "find_customer"
                        ],
                        "createdAt": "2026-10-08T09:00:00.000Z"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      },
      "post": {
        "operationId": "addMcpServer",
        "summary": "Add MCP Server",
        "description": "Verify and add an MCP server for the agent (at most 10 per project). Same body as Verify MCP Server.\n\nFull reference: https://www.totalum.app/docs/api/agent#add-mcp-server",
        "tags": [
          "AI Agent"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "mcp": {
                    "type": "object",
                    "description": "{ name, transport, url, headers? } as in Verify MCP Server",
                    "additionalProperties": true
                  }
                },
                "required": [
                  "mcp"
                ],
                "additionalProperties": true
              },
              "example": {
                "mcp": {
                  "name": "crm",
                  "transport": "http",
                  "url": "https://mcp.example.com/mcp"
                }
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Add MCP Server — Totalum docs",
          "url": "https://www.totalum.app/docs/api/agent#add-mcp-server"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "server": {
                          "type": "object",
                          "description": "The stored server, with the fields of servers[] in List MCP Servers",
                          "additionalProperties": true
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "server": {
                      "id": "mcp_01k6xe",
                      "name": "crm",
                      "transport": "http",
                      "url": "https://mcp.example.com/mcp",
                      "headerNames": [],
                      "enabled": true,
                      "verifiedAt": "2026-10-08T09:00:00.000Z",
                      "tools": [
                        "find_customer"
                      ],
                      "createdAt": "2026-10-08T09:00:00.000Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`MCP_LIMIT_REACHED` — The project already has 10 servers\n`MCP_VERIFY_FAILED` — The server did not pass the handshake\n`VALIDATION_ERROR` — A field is invalid or the name is taken or reserved",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/agent/mcp-servers/verify": {
      "post": {
        "operationId": "verifyMcpServer",
        "summary": "Verify MCP Server",
        "description": "Check that a server answers the MCP handshake and lists at least one tool, without saving it.\n\nFull reference: https://www.totalum.app/docs/api/agent#verify-mcp-server",
        "tags": [
          "AI Agent"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "mcp": {
                    "type": "object",
                    "description": "The server",
                    "properties": {
                      "name": {
                        "type": "string",
                        "description": "2–41 characters: lowercase letters, digits, _, -. Not totalum, playwright, figma, github or context7"
                      },
                      "transport": {
                        "type": "string",
                        "description": "\"http\" (streamable HTTP) or \"sse\""
                      },
                      "url": {
                        "type": "string",
                        "description": "A public https URL"
                      },
                      "headers": {
                        "type": "object",
                        "description": "Up to 20 headers, e.g. { \"Authorization\": \"Bearer …\" }",
                        "additionalProperties": true
                      }
                    },
                    "required": [
                      "name",
                      "transport",
                      "url"
                    ],
                    "additionalProperties": true
                  }
                },
                "required": [
                  "mcp"
                ],
                "additionalProperties": true
              },
              "example": {
                "mcp": {
                  "name": "crm",
                  "transport": "http",
                  "url": "https://mcp.example.com/mcp",
                  "headers": {
                    "Authorization": "Bearer abc"
                  }
                }
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Verify MCP Server — Totalum docs",
          "url": "https://www.totalum.app/docs/api/agent#verify-mcp-server"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "ok": {
                          "type": "boolean",
                          "description": "true"
                        },
                        "serverInfo": {
                          "type": "object",
                          "description": "{ name, version }",
                          "additionalProperties": true
                        },
                        "protocolVersion": {
                          "type": "string",
                          "description": "MCP protocol version"
                        },
                        "tools": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "{ name, description? }"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "ok": true,
                    "serverInfo": {
                      "name": "crm",
                      "version": "1.0.0"
                    },
                    "protocolVersion": "2025-06-18",
                    "tools": [
                      {
                        "name": "find_customer"
                      }
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "`MCP_VERIFY_FAILED` — The handshake failed. errorDetails: { stage: \"connect\" | \"initialize\" | \"tools_list\" | \"auth\", message, authHint? }\n`VALIDATION_ERROR` — A field is invalid or the name is reserved",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/agent/mcp-servers/{mcpId}": {
      "patch": {
        "operationId": "updateMcpServer",
        "summary": "Update MCP Server",
        "description": "Turn a server on or off, or change it (a changed configuration is verified again).\n\nFull reference: https://www.totalum.app/docs/api/agent#update-mcp-server",
        "tags": [
          "AI Agent"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          },
          {
            "name": "mcpId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The server id"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean",
                    "description": "Use it or not"
                  },
                  "mcp": {
                    "type": "object",
                    "description": "A new { name, transport, url, headers? }",
                    "additionalProperties": true
                  }
                },
                "additionalProperties": true
              },
              "example": {
                "enabled": false
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Update MCP Server — Totalum docs",
          "url": "https://www.totalum.app/docs/api/agent#update-mcp-server"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "server": {
                          "type": "object",
                          "description": "The server after the change",
                          "additionalProperties": true
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "server": {
                      "id": "mcp_01k6xe",
                      "name": "crm",
                      "transport": "http",
                      "url": "https://mcp.example.com/mcp",
                      "headerNames": [],
                      "enabled": false,
                      "verifiedAt": "2026-10-08T09:00:00.000Z",
                      "tools": [
                        "find_customer"
                      ],
                      "createdAt": "2026-10-08T09:00:00.000Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`MCP_VERIFY_FAILED` — The new configuration did not pass the handshake",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "404": {
            "description": "`MCP_SERVER_NOT_FOUND` — No such server",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteMcpServer",
        "summary": "Delete MCP Server",
        "description": "Remove an MCP server.\n\nFull reference: https://www.totalum.app/docs/api/agent#delete-mcp-server",
        "tags": [
          "AI Agent"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          },
          {
            "name": "mcpId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The server id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Delete MCP Server — Totalum docs",
          "url": "https://www.totalum.app/docs/api/agent#delete-mcp-server"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "deleted": {
                          "type": "boolean",
                          "description": "true"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "deleted": true
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "404": {
            "description": "`MCP_SERVER_NOT_FOUND` — No such server",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/deployments/deploy": {
      "post": {
        "operationId": "deployToProduction",
        "summary": "Deploy to Production",
        "description": "Publish the project's current version. It takes about 2 to 5 minutes. If the build or a migration fails, Totalum's agent tries to repair it once or twice before the publish ends in error; the live site keeps serving the previous version until a publish succeeds.\n\nFull reference: https://www.totalum.app/docs/api/deployments#deploy-to-production",
        "tags": [
          "Publishing"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "confirmDestructive": {
                    "type": "boolean",
                    "description": "true = run the pending migrations that drop columns or tables or delete/overwrite live rows"
                  }
                },
                "additionalProperties": true
              }
            }
          }
        },
        "x-totalum-cost": "0.5 credits",
        "externalDocs": {
          "description": "Deploy to Production — Totalum docs",
          "url": "https://www.totalum.app/docs/api/deployments#deploy-to-production"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "projectId": {
                          "type": "string",
                          "description": "Project id"
                        },
                        "status": {
                          "type": "string",
                          "description": "\"deploying\""
                        },
                        "deploymentId": {
                          "type": "string",
                          "description": "This publish"
                        },
                        "message": {
                          "type": "string",
                          "description": "How to follow it"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "projectId": "barber-bookings",
                    "status": "deploying",
                    "message": "Deployment started. It will take from 2 to 5 minutes depending on project size. Fetch GET /api/v1/vcaas/projects/barber-bookings/deployments/status every 10-15 seconds to track progress.",
                    "deploymentId": "dep_01k6xf3a9b"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "`INSUFFICIENT_CREDITS` — Not enough credits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "`PROJECT_CREDIT_LIMIT_REACHED` — The project's monthly development cap is reached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "`AGENT_RUNNING` — A prompt is running; publish when it is done\n`DEPLOYMENT_RUNNING` — A publish is already running\n`OPERATION_IN_PROGRESS` — A restore, import or other long operation holds the project, or it is still being set up",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/deployments/status": {
      "get": {
        "operationId": "getDeploymentStatus",
        "summary": "Get Deployment Status",
        "description": "The newest publish and where it is. Poll every 10–15 seconds until status is \"success\" or \"error\".\n\nFull reference: https://www.totalum.app/docs/api/deployments#get-deployment-status",
        "tags": [
          "Publishing"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Deployment Status — Totalum docs",
          "url": "https://www.totalum.app/docs/api/deployments#get-deployment-status"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "\"deploying\", \"success\", \"error\", or null if never published"
                        },
                        "createdAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "When the publish started"
                        },
                        "deploymentId": {
                          "type": "string",
                          "description": "The publish"
                        },
                        "step": {
                          "type": "string",
                          "description": "\"build\", \"migration\", \"upload\", \"probe\", \"fixing\" (the agent is repairing a failed step) or \"done\""
                        },
                        "progress": {
                          "type": "object",
                          "description": "While step is \"fixing\": { stage: \"fixing\", failedStage, fixAttempt, fixAttempts }",
                          "additionalProperties": true
                        },
                        "errorDetails": {
                          "type": "object",
                          "description": "On \"error\": { stage, title, message, logExcerpt, versionId, deploymentId?, migrationName?, fixSummary?, at } — fixSummary says what the repair tried and what you need to do",
                          "additionalProperties": true
                        },
                        "liveUrl": {
                          "type": "string",
                          "description": "The live address"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "status": "success",
                    "createdAt": "2026-10-08T11:20:00.000Z",
                    "deploymentId": "dep_01k6xf3a9b",
                    "step": "done",
                    "liveUrl": "https://barber-bookings.totalum-project.com"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/deployments/unpublish": {
      "post": {
        "operationId": "unpublish",
        "summary": "Unpublish",
        "description": "Take the published site offline and remove the project's custom domain. The preview, the code, the databases and the versions stay. Publish again with Deploy to Production; a custom domain has to be added again. Free, at any balance.\n\nFull reference: https://www.totalum.app/docs/api/deployments#unpublish",
        "tags": [
          "Publishing"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Unpublish — Totalum docs",
          "url": "https://www.totalum.app/docs/api/deployments#unpublish"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "projectId": {
                          "type": "string",
                          "description": "Project id"
                        },
                        "status": {
                          "type": "string",
                          "description": "\"unpublished\""
                        },
                        "customDomainsRemoved": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Domains removed"
                        },
                        "customDomainsFailed": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Domains that could not be removed (they serve nothing; call again to retry)"
                        },
                        "warnings": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Non-fatal problems"
                        },
                        "message": {
                          "type": "string",
                          "description": "What happened"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "projectId": "barber-bookings",
                    "status": "unpublished",
                    "customDomainsRemoved": [],
                    "customDomainsFailed": [],
                    "warnings": [],
                    "message": "The project is offline: its published site, preview snapshot and custom domains were removed. Deploy again to publish it; custom domains have to be added again."
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "409": {
            "description": "`DEPLOYMENT_RUNNING` — A publish is running and would put the site back; wait until it ends, then retry",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/versions": {
      "get": {
        "operationId": "listVersions",
        "summary": "List Versions",
        "description": "The project's versions, newest first.\n\nFull reference: https://www.totalum.app/docs/api/versions#list-versions",
        "tags": [
          "Versions"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number"
            },
            "description": "1–100 (default 20)"
          },
          {
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number"
            },
            "description": "Versions to skip (default 0)"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "List Versions — Totalum docs",
          "url": "https://www.totalum.app/docs/api/versions#list-versions"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "versions": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "_id": {
                                "type": "string",
                                "description": "Version id — for Recover Version"
                              },
                              "name": {
                                "type": "string",
                                "description": "Display name"
                              },
                              "commitSha": {
                                "type": "string",
                                "description": "Commit of the version — for Get Version Diff"
                              },
                              "commitMessage": {
                                "type": "string",
                                "description": "Commit message"
                              },
                              "prompt": {
                                "type": "string",
                                "description": "The prompt that produced it (first 300 characters)"
                              },
                              "gcsUploaded": {
                                "type": "boolean",
                                "description": "true once the version's archive is stored"
                              },
                              "recoveredVersionId": {
                                "type": "string",
                                "description": "When this version is a restore: the version it restored"
                              },
                              "createdAt": {
                                "type": "string",
                                "description": "ISO 8601"
                              },
                              "updatedAt": {
                                "type": "string",
                                "description": "ISO 8601 (same as createdAt)"
                              }
                            },
                            "additionalProperties": true
                          },
                          "description": "The versions"
                        },
                        "totalCount": {
                          "type": "number",
                          "description": "Total versions"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "versions": [
                      {
                        "_id": "ver_01k6xd2m8q",
                        "commitSha": "9f2c1ab4d3e5f60718293a4b5c6d7e8f90a1b2c3",
                        "commitMessage": "Add a contact form",
                        "prompt": "Add a contact form that emails me every message",
                        "gcsUploaded": true,
                        "createdAt": "2026-10-08T11:15:40.000Z",
                        "updatedAt": "2026-10-08T11:15:40.000Z",
                        "name": "Version 4"
                      }
                    ],
                    "totalCount": 4
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/version-diff": {
      "get": {
        "operationId": "getVersionDiff",
        "summary": "Get Version Diff",
        "description": "The unified diff (git diff format) a version introduced.\n\nFull reference: https://www.totalum.app/docs/api/versions#get-version-diff",
        "tags": [
          "Versions"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          },
          {
            "name": "commitSha",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The version's commitSha, 7–40 hexadecimal characters"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Version Diff — Totalum docs",
          "url": "https://www.totalum.app/docs/api/versions#get-version-diff"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "commitSha": {
                          "type": "string",
                          "description": "The commit"
                        },
                        "diff": {
                          "type": "string",
                          "description": "The diff; \"\" when nothing tracked changed"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "commitSha": "9f2c1ab",
                    "diff": "diff --git a/src/app/contact/page.tsx b/src/app/contact/page.tsx\nnew file mode 100644\n+export default function Contact() {\n"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`MISSING_COMMIT_SHA` — commitSha is missing\n`INVALID_COMMIT_SHA` — Not 7–40 hexadecimal characters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "404": {
            "description": "`VERSION_NOT_FOUND` — No version with this commit",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/versions/{id}/recover": {
      "post": {
        "operationId": "recoverVersion",
        "summary": "Recover Version",
        "description": "Restore an earlier version's code as a new version, deployed to the preview. It runs in the background (1–4 minutes): poll Get Project until versionRecovery is null (on failure it shows status: \"error\" with errorMessage).\n\nFull reference: https://www.totalum.app/docs/api/versions#recover-version",
        "tags": [
          "Versions"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The version's _id"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "restoreDevDatabase": {
                    "type": "boolean",
                    "description": "Also restore the development database to the version's time (a restore point is taken first)"
                  }
                },
                "additionalProperties": true
              }
            }
          }
        },
        "x-totalum-cost": "2 credits",
        "externalDocs": {
          "description": "Recover Version — Totalum docs",
          "url": "https://www.totalum.app/docs/api/versions#recover-version"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "\"Version recovered successfully\" — the restore has started"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "message": "Version recovered successfully"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "`INSUFFICIENT_CREDITS` — Not enough credits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "404": {
            "description": "`VERSION_NOT_FOUND` — No such version",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "`AGENT_RUNNING` — A prompt is running\n`DEPLOYMENT_RUNNING` — A publish is running\n`OPERATION_IN_PROGRESS` — Another restore or long operation is running",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/versions/recovery": {
      "delete": {
        "operationId": "clearRecoveryMarker",
        "summary": "Clear Recovery Marker",
        "description": "Clear versionRecovery on the project after a failed restore, so it no longer shows. A restore that is really running ends by itself; never more than 25 minutes.\n\nFull reference: https://www.totalum.app/docs/api/versions#clear-recovery-marker",
        "tags": [
          "Versions"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Clear Recovery Marker — Totalum docs",
          "url": "https://www.totalum.app/docs/api/versions#clear-recovery-marker"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "cleared": {
                          "type": "boolean",
                          "description": "false when there was nothing to clear"
                        },
                        "wasRunning": {
                          "type": "boolean",
                          "description": "The cleared restore had started less than 10 minutes ago"
                        },
                        "previousStatus": {
                          "type": "string",
                          "description": "Its status before clearing"
                        },
                        "message": {
                          "type": "string",
                          "description": "What to do next"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "cleared": true,
                    "wasRunning": false,
                    "previousStatus": "error",
                    "message": "Cleared. Restart, deploy, prompts and a new recovery are allowed again."
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/database/schema": {
      "get": {
        "operationId": "getSchema",
        "summary": "Get Schema",
        "description": "The tables, columns, foreign keys and relations of one environment's database, read from the database itself, plus the display settings shown in the Totalum database explorer.\n\nFull reference: https://www.totalum.app/docs/api/database#get-schema",
        "tags": [
          "Database"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project ID"
          },
          {
            "name": "env",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "\"live\" or \"dev\""
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Schema — Totalum docs",
          "url": "https://www.totalum.app/docs/api/database#get-schema"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "env": {
                          "type": "string",
                          "description": "The environment read"
                        },
                        "tables": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "name": {
                                "type": "string",
                                "description": "Table name"
                              },
                              "label": {
                                "type": "string",
                                "description": "Display label"
                              },
                              "kind": {
                                "type": "string",
                                "description": "\"table\", \"junction\" (a many-to-many link table) or \"system\" (auth and migrations: read-only here)"
                              },
                              "primaryKey": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                },
                                "description": "The primary key's columns in key order; [] when the table has none (its rows are addressed by rowid)"
                              },
                              "columns": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "name": {
                                      "type": "string",
                                      "description": "Column name"
                                    },
                                    "sqlType": {
                                      "type": "string",
                                      "description": "SQLite type, e.g. TEXT, INTEGER"
                                    },
                                    "kind": {
                                      "type": "string",
                                      "description": "Value kind, e.g. text, number, datetime, options, relation"
                                    },
                                    "label": {
                                      "type": "string",
                                      "description": "Display label"
                                    },
                                    "notNull": {
                                      "type": "boolean",
                                      "description": "NOT NULL"
                                    },
                                    "unique": {
                                      "type": "boolean",
                                      "description": "Unique on its own: a one-column primary key or a one-column UNIQUE index. A column of a composite primary key is not unique on its own"
                                    },
                                    "default": {
                                      "type": [
                                        "string",
                                        "null"
                                      ],
                                      "description": "Default value expression"
                                    },
                                    "options": {
                                      "type": "array",
                                      "items": {
                                        "type": "string"
                                      },
                                      "description": "Allowed values (a CHECK … IN (…) list)"
                                    },
                                    "relation": {
                                      "type": "object",
                                      "description": "{ table, fkColumn, onDelete } the column references",
                                      "additionalProperties": true
                                    }
                                  },
                                  "additionalProperties": true
                                }
                              },
                              "indexes": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "description": "{ name, columns, unique }",
                                  "additionalProperties": true
                                }
                              },
                              "foreignKeys": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "description": "{ column, table, toColumn, onDelete }",
                                  "additionalProperties": true
                                }
                              },
                              "rowCountEstimate": {
                                "type": "number",
                                "description": "Rows in the table (0 unless counted)"
                              }
                            },
                            "additionalProperties": true
                          }
                        },
                        "ledger": {
                          "type": "object",
                          "description": "{ count, lastCreatedAt, lastHash } of the applied migrations",
                          "additionalProperties": true
                        },
                        "ddlHash": {
                          "type": "string",
                          "description": "Hash of the whole schema: changes whenever a migration changes it"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "env": "live",
                    "tables": [
                      {
                        "name": "bookings",
                        "label": "Bookings",
                        "kind": "table",
                        "primaryKey": [
                          "id"
                        ],
                        "columns": [
                          {
                            "name": "id",
                            "sqlType": "TEXT",
                            "kind": "text",
                            "label": "Id",
                            "notNull": true,
                            "unique": true,
                            "default": null
                          },
                          {
                            "name": "status",
                            "sqlType": "TEXT",
                            "kind": "options",
                            "label": "Status",
                            "notNull": true,
                            "unique": false,
                            "default": "'pending'",
                            "options": [
                              "pending",
                              "paid",
                              "cancelled"
                            ]
                          },
                          {
                            "name": "user_id",
                            "sqlType": "TEXT",
                            "kind": "relation",
                            "label": "User",
                            "notNull": true,
                            "unique": false,
                            "default": null,
                            "relation": {
                              "table": "users",
                              "fkColumn": "id",
                              "onDelete": "cascade"
                            }
                          }
                        ],
                        "indexes": [
                          {
                            "name": "bookings_user_id",
                            "columns": [
                              "user_id"
                            ],
                            "unique": false
                          }
                        ],
                        "foreignKeys": [
                          {
                            "column": "user_id",
                            "table": "users",
                            "toColumn": "id",
                            "onDelete": "cascade"
                          }
                        ],
                        "rowCountEstimate": 0
                      }
                    ],
                    "ledger": {
                      "count": 4,
                      "lastCreatedAt": "2026-10-08T11:15:00.000Z",
                      "lastHash": "a41f9c"
                    },
                    "ddlHash": "9c0e2b"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "404": {
            "description": "`DEV_DATABASE_NOT_FOUND` — env is \"dev\" and the project has no development database\n`PROJECT_NOT_FOUND` — Project does not exist or you don't own it",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/database/rows": {
      "post": {
        "operationId": "queryRows",
        "summary": "Query Rows",
        "description": "Rows of one table, filtered, searched, sorted and paginated. Filters compile to parameterised SQL on the server; values are never interpolated.\n\nFull reference: https://www.totalum.app/docs/api/database#query-rows",
        "tags": [
          "Database"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project ID"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "env": {
                    "type": "string",
                    "description": "\"live\" or \"dev\""
                  },
                  "table": {
                    "type": "string",
                    "description": "Table name"
                  },
                  "filter": {
                    "type": "object",
                    "description": "{ and: [...] } or { or: [...] } of conditions { column, op, value } and nested groups. op: eq, ne, lt, lte, gt, gte, contains, startsWith, in, isNull, notNull. At most 4 levels, 50 conditions and 1,000 in values",
                    "additionalProperties": true
                  },
                  "search": {
                    "type": "string",
                    "description": "Text search, at most 200 characters"
                  },
                  "sort": {
                    "type": "array",
                    "description": "Up to 3 { column, dir: \"asc\" | \"desc\" }"
                  },
                  "page": {
                    "type": "object",
                    "description": "{ limit, after? , offset? } — limit 1–200; after is the previous page's nextAfter (keyset, the default way to page); offset (≤ 10,000) is the alternative. Send after or offset, not both",
                    "additionalProperties": true
                  },
                  "expand": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Up to 5 foreign-key columns of table; each row gets the referenced row as <column>__expanded (null when missing)"
                  },
                  "count": {
                    "type": "boolean",
                    "description": "Also return total, the number of matching rows"
                  }
                },
                "required": [
                  "env",
                  "table",
                  "page"
                ],
                "additionalProperties": true
              },
              "example": {
                "env": "live",
                "table": "orders",
                "filter": {
                  "and": [
                    {
                      "column": "status",
                      "op": "eq",
                      "value": "paid"
                    },
                    {
                      "column": "total",
                      "op": "gte",
                      "value": 100
                    }
                  ]
                },
                "sort": [
                  {
                    "column": "created_at",
                    "dir": "desc"
                  }
                ],
                "page": {
                  "limit": 20
                }
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Query Rows — Totalum docs",
          "url": "https://www.totalum.app/docs/api/database#query-rows"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "columns": {
                          "type": "array",
                          "description": "{ name, sqlType?, kind? } of each column"
                        },
                        "rows": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "The rows, one object per row"
                        },
                        "nextAfter": {
                          "type": "string",
                          "description": "Cursor of the next page; absent on the last page"
                        },
                        "total": {
                          "type": "number",
                          "description": "Matching rows, when count was true"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "columns": [
                      {
                        "name": "id",
                        "sqlType": "TEXT"
                      },
                      {
                        "name": "status",
                        "sqlType": "TEXT"
                      },
                      {
                        "name": "total",
                        "sqlType": "REAL"
                      },
                      {
                        "name": "created_at",
                        "sqlType": "TEXT"
                      }
                    ],
                    "rows": [
                      {
                        "id": "01J8ZK3W6Q2Y4N7B9C1D3F5G7H",
                        "status": "paid",
                        "total": 120,
                        "created_at": "2026-09-20T10:04:11.000Z"
                      }
                    ],
                    "nextAfter": "WyIyMDI2LTA5LTIwVDEwOjA0OjExLjAwMFoiXQ"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`COLUMN_NOT_FOUND` — A filter, sort or expand column does not exist (or is not a foreign key, for expand)\n`FILTER_TOO_COMPLEX` — Filter deeper than 4 levels, more than 50 conditions or more than 1,000 in values\n`VALIDATION_ERROR` — Invalid body, or page.after is not a cursor of this table and sort",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "404": {
            "description": "`TABLE_NOT_FOUND` — No such table; errorDetails.suggestions lists close names\n`DEV_DATABASE_NOT_FOUND` — env is \"dev\" and the project has no development database",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/database/records": {
      "post": {
        "operationId": "insertRecord",
        "summary": "Insert Record",
        "description": "Insert one row and return it as stored.\n\nFull reference: https://www.totalum.app/docs/api/database#insert-record",
        "tags": [
          "Database"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project ID"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "env": {
                    "type": "string",
                    "description": "\"live\" or \"dev\""
                  },
                  "table": {
                    "type": "string",
                    "description": "Table name"
                  },
                  "data": {
                    "type": "object",
                    "description": "Column → value. Columns with a default may be omitted",
                    "additionalProperties": true
                  }
                },
                "required": [
                  "env",
                  "table",
                  "data"
                ],
                "additionalProperties": true
              },
              "example": {
                "env": "live",
                "table": "bookings",
                "data": {
                  "id": "bk_1001",
                  "status": "paid",
                  "user_id": "usr_42"
                }
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Insert Record — Totalum docs",
          "url": "https://www.totalum.app/docs/api/database#insert-record"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "row": {
                          "type": "object",
                          "description": "The inserted row, every column",
                          "additionalProperties": true
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "row": {
                      "id": "bk_1001",
                      "status": "paid",
                      "user_id": "usr_42",
                      "created_at": "2026-10-08T12:00:00.000Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`COLUMN_NOT_FOUND` — data names a column the table does not have\n`COLUMN_REQUIRED` — A NOT NULL column without a default is missing\n`VALUE_NOT_ALLOWED` — The value is not one of the column's allowed values",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "`SYSTEM_TABLE_READ_ONLY` — The table is written by Totalum only (e.g. _migrations)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "`TABLE_NOT_FOUND` — No such table",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/database/records/{recordId}": {
      "patch": {
        "operationId": "updateRecord",
        "summary": "Update Record",
        "description": "Update the given columns of one row, found by its record id, and return the full row.\n\nFull reference: https://www.totalum.app/docs/api/database#update-record",
        "tags": [
          "Database"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project ID"
          },
          {
            "name": "recordId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The row's record id: its key value, or for a composite primary key the URL-encoded JSON object of every key column"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "env": {
                    "type": "string",
                    "description": "\"live\" or \"dev\""
                  },
                  "table": {
                    "type": "string",
                    "description": "Table name"
                  },
                  "data": {
                    "type": "object",
                    "description": "Column → new value; at least one column",
                    "additionalProperties": true
                  }
                },
                "required": [
                  "env",
                  "table",
                  "data"
                ],
                "additionalProperties": true
              },
              "example": {
                "env": "live",
                "table": "bookings",
                "data": {
                  "status": "cancelled"
                }
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Update Record — Totalum docs",
          "url": "https://www.totalum.app/docs/api/database#update-record"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "row": {
                          "type": "object",
                          "description": "The updated row, every column",
                          "additionalProperties": true
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "row": {
                      "id": "bk_1001",
                      "status": "cancelled",
                      "user_id": "usr_42",
                      "created_at": "2026-10-08T12:00:00.000Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`RECORD_KEY_REQUIRED` — The id does not name every column of the table's key; errorDetails.keyColumns lists them\n`AMBIGUOUS_RECORD_ID` — The id matches more than one row; nothing was changed\n`COLUMN_NOT_FOUND` — data names a column the table does not have\n`VALUE_NOT_ALLOWED` — The value is not one of the column's allowed values",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "`SYSTEM_TABLE_READ_ONLY` — The table is written by Totalum only",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "`RECORD_NOT_FOUND` — No row has that id\n`TABLE_NOT_FOUND` — No such table",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteRecord",
        "summary": "Delete Record",
        "description": "Delete one row by its record id. There is no trash: a deleted row comes back only from a backup.\n\nFull reference: https://www.totalum.app/docs/api/database#delete-record",
        "tags": [
          "Database"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project ID"
          },
          {
            "name": "recordId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The row's record id: its key value, or for a composite primary key the URL-encoded JSON object of every key column"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "env": {
                    "type": "string",
                    "description": "\"live\" or \"dev\""
                  },
                  "table": {
                    "type": "string",
                    "description": "Table name"
                  }
                },
                "required": [
                  "env",
                  "table"
                ],
                "additionalProperties": true
              },
              "example": {
                "env": "live",
                "table": "bookings"
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Delete Record — Totalum docs",
          "url": "https://www.totalum.app/docs/api/database#delete-record"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "deleted": {
                          "type": "boolean",
                          "description": "Always true"
                        },
                        "id": {
                          "type": [
                            "string",
                            "number",
                            "object"
                          ],
                          "description": "The deleted row's id, as sent",
                          "additionalProperties": true
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "deleted": true,
                    "id": "bk_1001"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`RECORD_KEY_REQUIRED` — The id does not name every column of the table's key; errorDetails.keyColumns lists them\n`AMBIGUOUS_RECORD_ID` — The id matches more than one row; nothing was changed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "`SYSTEM_TABLE_READ_ONLY` — The table is written by Totalum only",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "`RECORD_NOT_FOUND` — No row has that id\n`TABLE_NOT_FOUND` — No such table",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/database/records/bulk": {
      "post": {
        "operationId": "bulkWrite",
        "summary": "Bulk Write",
        "description": "Insert, update or delete up to 500 rows of one table in one atomic batch: if one item fails, none is applied.\n\nFull reference: https://www.totalum.app/docs/api/database#bulk-write",
        "tags": [
          "Database"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project ID"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "env": {
                    "type": "string",
                    "description": "\"live\" or \"dev\""
                  },
                  "table": {
                    "type": "string",
                    "description": "Table name"
                  },
                  "op": {
                    "type": "string",
                    "description": "\"insert\", \"update\" or \"delete\""
                  },
                  "items": {
                    "type": "array",
                    "description": "1–500 items: row objects for insert, { id, data } for update, { id } for delete — each id a record id"
                  }
                },
                "required": [
                  "env",
                  "table",
                  "op",
                  "items"
                ],
                "additionalProperties": true
              },
              "example": {
                "env": "dev",
                "table": "services",
                "op": "insert",
                "items": [
                  {
                    "id": "cut",
                    "name": "Haircut",
                    "price": 20
                  },
                  {
                    "id": "beard",
                    "name": "Beard trim",
                    "price": 12
                  }
                ]
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Bulk Write — Totalum docs",
          "url": "https://www.totalum.app/docs/api/database#bulk-write"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "op": {
                          "type": "string",
                          "description": "The operation"
                        },
                        "count": {
                          "type": "number",
                          "description": "Rows inserted, updated or deleted"
                        },
                        "rows": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "The inserted or updated rows (insert, update)"
                        },
                        "ids": {
                          "type": "array",
                          "description": "The ids actually deleted (delete)"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "op": "insert",
                    "count": 2,
                    "rows": [
                      {
                        "id": "cut",
                        "name": "Haircut",
                        "price": 20
                      },
                      {
                        "id": "beard",
                        "name": "Beard trim",
                        "price": 12
                      }
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "`BULK_TOO_LARGE` — More than 500 items\n`RECORD_KEY_REQUIRED` — An item's id does not name every column of the table's key; errorDetails.keyColumns lists them\n`AMBIGUOUS_RECORD_ID` — An item's id matches more than one row; nothing was changed\n`SQL_ERROR` — An item failed; nothing was applied\n`COLUMN_NOT_FOUND` — An item names a column the table does not have",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "`SYSTEM_TABLE_READ_ONLY` — The table is written by Totalum only",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "`TABLE_NOT_FOUND` — No such table",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/database/relations": {
      "post": {
        "operationId": "linkOrUnlinkRecords",
        "summary": "Link or Unlink Records",
        "description": "Add or remove the junction-table row that links two rows in a many-to-many relation.\n\nFull reference: https://www.totalum.app/docs/api/database#link-or-unlink-records",
        "tags": [
          "Database"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project ID"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "env": {
                    "type": "string",
                    "description": "\"live\" or \"dev\""
                  },
                  "a": {
                    "type": "object",
                    "description": "{ table, id } — one side",
                    "additionalProperties": true
                  },
                  "b": {
                    "type": "object",
                    "description": "{ table, id } — the other side",
                    "additionalProperties": true
                  },
                  "op": {
                    "type": "string",
                    "description": "\"link\" or \"unlink\""
                  },
                  "junctionTable": {
                    "type": "string",
                    "description": "The junction table to use; required when more than one connects the two tables"
                  }
                },
                "required": [
                  "env",
                  "a",
                  "b",
                  "op"
                ],
                "additionalProperties": true
              },
              "example": {
                "env": "live",
                "op": "link",
                "a": {
                  "table": "bookings",
                  "id": "bk_1001"
                },
                "b": {
                  "table": "services",
                  "id": "cut"
                }
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Link or Unlink Records — Totalum docs",
          "url": "https://www.totalum.app/docs/api/database#link-or-unlink-records"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "op": {
                          "type": "string",
                          "description": "The operation"
                        },
                        "junctionTable": {
                          "type": "string",
                          "description": "The junction table used"
                        },
                        "changed": {
                          "type": "number",
                          "description": "1 when a row was added or removed, 0 when it already was (or was not) linked"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "op": "link",
                    "junctionTable": "booking_services",
                    "changed": 1
                  }
                }
              }
            }
          },
          "400": {
            "description": "`AMBIGUOUS_RELATION` — Zero or several junction tables connect the two tables; errorDetails.candidates lists them — send one as junctionTable\n`NOT_A_JUNCTION_TABLE` — junctionTable does not reference both tables",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "404": {
            "description": "`RECORD_NOT_FOUND` — a or b does not exist\n`TABLE_NOT_FOUND` — No such table",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/database/sql": {
      "post": {
        "operationId": "runSql",
        "summary": "Run SQL",
        "description": "Run one SQL statement with bound parameters. Reads return at most 1,000 rows. Writes run only when asked for. Schema changes (DDL) are refused: they are migrations in the project's code.\n\nFull reference: https://www.totalum.app/docs/api/database#run-sql",
        "tags": [
          "Database"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project ID"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "env": {
                    "type": "string",
                    "description": "\"live\" or \"dev\""
                  },
                  "sql": {
                    "type": "string",
                    "description": "One statement, at most 100 KB, with ? placeholders"
                  },
                  "params": {
                    "type": "array",
                    "description": "Up to 100 values bound to the placeholders"
                  },
                  "allowWrites": {
                    "type": "boolean",
                    "description": "Required for INSERT, UPDATE and DELETE"
                  },
                  "confirmLive": {
                    "type": "boolean",
                    "description": "Required for a write on live (the published site's data)"
                  }
                },
                "required": [
                  "env",
                  "sql"
                ],
                "additionalProperties": true
              },
              "example": {
                "env": "live",
                "sql": "SELECT status, SUM(total) AS total FROM orders GROUP BY status"
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Run SQL — Totalum docs",
          "url": "https://www.totalum.app/docs/api/database#run-sql"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "columns": {
                          "type": "array",
                          "description": "{ name } of each result column"
                        },
                        "rows": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "Result rows (at most 1,000)"
                        },
                        "truncated": {
                          "type": "boolean",
                          "description": "true when the result had more than 1,000 rows"
                        },
                        "meta": {
                          "type": "object",
                          "description": "The database's statement metadata (rows_read, rows_written, changes, duration, …)",
                          "additionalProperties": true
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "columns": [
                      {
                        "name": "status"
                      },
                      {
                        "name": "total"
                      }
                    ],
                    "rows": [
                      {
                        "status": "paid",
                        "total": 4810
                      },
                      {
                        "status": "refunded",
                        "total": 120
                      }
                    ],
                    "truncated": false,
                    "meta": {
                      "rows_read": 312,
                      "rows_written": 0,
                      "changes": 0,
                      "duration": 0.4
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`DDL_NOT_ALLOWED` — The statement changes the schema — change src/db/schema.ts, then npm run db:generate and npm run db:migrate\n`SQL_MULTI_STATEMENT` — More than one statement\n`SQL_ERROR` — The database rejected the statement",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "`SQL_READ_ONLY` — The statement writes and allowWrites is not true\n`SYSTEM_TABLE_READ_ONLY` — The statement writes _migrations",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "`LIVE_WRITE_CONFIRMATION_REQUIRED` — A write on live without confirmLive: true",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/database/ask": {
      "post": {
        "operationId": "askDatabase",
        "summary": "Ask Database",
        "description": "Turn a plain-language question into one SQL statement for this database. The statement is shown, never run: run it with Run SQL.\n\nFull reference: https://www.totalum.app/docs/api/database#ask-database",
        "tags": [
          "Database"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "question": {
                    "type": "string",
                    "description": "What you want from the data"
                  },
                  "questionBase64": {
                    "type": "string",
                    "description": "The question as base64 (UTF-8), instead of question"
                  },
                  "env": {
                    "type": "string",
                    "description": "\"live\" or \"dev\". Default: live once the project has been published, else dev"
                  }
                },
                "required": [
                  "question"
                ],
                "additionalProperties": true
              },
              "example": {
                "question": "How many bookings were paid last week?",
                "env": "live"
              }
            }
          }
        },
        "x-totalum-cost": "Metered (one AI call)",
        "externalDocs": {
          "description": "Ask Database — Totalum docs",
          "url": "https://www.totalum.app/docs/api/database#ask-database"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "sql": {
                          "type": "string",
                          "description": "The statement"
                        },
                        "explanation": {
                          "type": "string",
                          "description": "What it does"
                        },
                        "isReadOnly": {
                          "type": "boolean",
                          "description": "true when the statement only reads"
                        },
                        "creditsCharged": {
                          "type": "number",
                          "description": "What the question cost"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "sql": "SELECT COUNT(*) AS paid FROM bookings WHERE status = 'paid' AND created_at >= datetime('now', '-7 days')",
                    "explanation": "Counts the bookings paid in the last 7 days.",
                    "isReadOnly": true,
                    "creditsCharged": 0.02
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "404": {
            "description": "`DEV_DATABASE_NOT_FOUND` — env is \"dev\" and the project has no development database",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "422": {
            "description": "`NL_QUERY_UNANSWERABLE` — The database's tables cannot answer the question (errorMessage says why)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/database/usage": {
      "get": {
        "operationId": "getDatabaseUsage",
        "summary": "Get Database Usage",
        "description": "The database's usage and health: rows read and written and storage, in credits (today, 7 and 30 days), size, tables and row counts, the slowest queries, tips (missing indexes, large tables, backups) and whether moving to Turso is worth it.\n\nFull reference: https://www.totalum.app/docs/api/database#get-database-usage",
        "tags": [
          "Database"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          },
          {
            "name": "env",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "\"all\" (default), \"live\" or \"dev\""
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Database Usage — Totalum docs",
          "url": "https://www.totalum.app/docs/api/database#get-database-usage"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "generatedAt": {
                          "type": "string",
                          "description": "When this was computed"
                        },
                        "envs": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "env": {
                                "type": "string",
                                "description": "\"live\" or \"dev\""
                              },
                              "provider": {
                                "type": "string",
                                "description": "\"d1\" or \"turso\""
                              },
                              "region": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Where the primary copy runs"
                              },
                              "readReplicas": {
                                "type": "boolean",
                                "description": "Whether reads are served from copies near visitors"
                              },
                              "sizeBytes": {
                                "type": [
                                  "number",
                                  "null"
                                ],
                                "description": "Size of the database"
                              },
                              "lastBackupAt": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Last manual backup"
                              },
                              "usage": {
                                "type": "object",
                                "description": "{ today, last7Days, last30Days }, each { rowsRead, rowsWritten, credits: { rowsRead, rowsWritten, storage, total } }",
                                "additionalProperties": true
                              },
                              "daily": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "additionalProperties": true
                                },
                                "description": "One row per day: { date, rowsRead, rowsWritten, requests, credits, sizeBytes }"
                              },
                              "tables": {
                                "type": [
                                  "object",
                                  "null"
                                ],
                                "description": "{ count, rows, list: [{ name, rows, estimated? }] }",
                                "additionalProperties": true
                              },
                              "queries": {
                                "type": [
                                  "array",
                                  "null"
                                ],
                                "items": {
                                  "type": "object",
                                  "additionalProperties": true
                                },
                                "description": "The heaviest query shapes of the last 7 days: { sql, count, totalMs, rowsRead, rowsReturned, rowsWritten }"
                              }
                            },
                            "additionalProperties": true
                          }
                        },
                        "turso": {
                          "type": "object",
                          "description": "{ verdict, reasons[], caveats[], location, envs, estimateSec, databaseBytes, credits, paidPlanRequired }; verdict: \"recommended\", \"consider\", \"not_needed\" or \"on_turso\"",
                          "additionalProperties": true
                        },
                        "tips": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "{ env, severity: \"warn\" | \"info\", code, message, params? }"
                        },
                        "notes": {
                          "type": "object",
                          "description": "{ liveTrafficSettledNightly, queriesSince }",
                          "additionalProperties": true
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "generatedAt": "2026-10-08T12:00:00.000Z",
                    "envs": [
                      {
                        "env": "live",
                        "provider": "d1",
                        "region": "WEUR",
                        "readReplicas": true,
                        "sizeBytes": 2457600,
                        "lastBackupAt": null,
                        "usage": {
                          "today": {
                            "rowsRead": 4120,
                            "rowsWritten": 36,
                            "credits": {
                              "rowsRead": 0.0002,
                              "rowsWritten": 0.0021,
                              "storage": 0.0001,
                              "total": 0.0024
                            }
                          },
                          "last7Days": {
                            "rowsRead": 30211,
                            "rowsWritten": 240,
                            "credits": {
                              "rowsRead": 0.0017,
                              "rowsWritten": 0.0137,
                              "storage": 0.0007,
                              "total": 0.0161
                            }
                          },
                          "last30Days": {
                            "rowsRead": 30211,
                            "rowsWritten": 240,
                            "credits": {
                              "rowsRead": 0.0017,
                              "rowsWritten": 0.0137,
                              "storage": 0.0007,
                              "total": 0.0161
                            }
                          }
                        },
                        "tables": {
                          "count": 7,
                          "rows": 412,
                          "list": [
                            {
                              "name": "bookings",
                              "rows": 240
                            }
                          ]
                        },
                        "queries": []
                      }
                    ],
                    "turso": {
                      "verdict": "not_needed",
                      "reasons": [
                        {
                          "code": "fits_d1",
                          "message": "The database is small (2.5 MB of 10 GB) and its traffic fits D1 well. There is no need to move."
                        }
                      ],
                      "caveats": []
                    },
                    "tips": [],
                    "notes": {
                      "liveTrafficSettledNightly": true,
                      "queriesSince": "2026-10-01T12:00:00.000Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`VALIDATION_ERROR` — env is not all, live or dev",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/database/undo-run": {
      "post": {
        "operationId": "undoAgentRunDatabaseChange",
        "summary": "Undo Agent Run Database Change",
        "description": "Undo the latest agent run's database change: the database goes back to the restore point taken at the start of that run (a backup is taken first), then the code goes back to before the run. Only the latest run can be undone. Follow it on Get Project State.\n\nFull reference: https://www.totalum.app/docs/api/database#undo-agent-run-database-change",
        "tags": [
          "Database"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "runId": {
                    "type": "string",
                    "description": "The run to undo"
                  },
                  "confirm": {
                    "type": "string",
                    "description": "The project id, typed to confirm"
                  }
                },
                "required": [
                  "runId"
                ],
                "additionalProperties": true
              },
              "example": {
                "runId": "run_01k6xc4n7d",
                "confirm": "barber-bookings"
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Undo Agent Run Database Change — Totalum docs",
          "url": "https://www.totalum.app/docs/api/database#undo-agent-run-database-change"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string",
                          "description": "\"restoring\""
                        },
                        "env": {
                          "type": "string",
                          "description": "The database restored"
                        },
                        "runId": {
                          "type": "string",
                          "description": "The run undone"
                        },
                        "restoredTo": {
                          "type": "string",
                          "description": "The restore point used"
                        },
                        "previousBookmark": {
                          "type": "string",
                          "description": "The point taken just before (restoring to it undoes the undo)"
                        },
                        "preRestoreBackupId": {
                          "type": "string",
                          "description": "The backup taken first"
                        },
                        "codeVersionId": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "The version the code goes back to; null when the run changed no code"
                        },
                        "operation": {
                          "type": "object",
                          "description": "{ kind, id }",
                          "additionalProperties": true
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "env": "dev",
                    "status": "restoring",
                    "restoredTo": "00000085-00000001-…",
                    "previousBookmark": "00000091-00000002-…",
                    "preRestoreBackupId": "bkp_01k6xg",
                    "operation": {
                      "kind": "backupRestore",
                      "id": "op_01k6xh"
                    },
                    "runId": "run_01k6xc4n7d",
                    "codeVersionId": "ver_01k6xh9q"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "409": {
            "description": "`AGENT_RUNNING` — A prompt is running\n`OPERATION_IN_PROGRESS` — Another restore or long operation is running",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/database/backups": {
      "get": {
        "operationId": "listBackups",
        "summary": "List Backups",
        "description": "The project's backups, newest first, the schedule of the live database's backups and the Time-Travel window.\n\nFull reference: https://www.totalum.app/docs/api/database-backups#list-backups",
        "tags": [
          "Database Backups & Restore"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project ID"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "List Backups — Totalum docs",
          "url": "https://www.totalum.app/docs/api/database-backups#list-backups"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "backups": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "description": "Backup ID"
                              },
                              "env": {
                                "type": "string",
                                "description": "\"live\" or \"dev\""
                              },
                              "kind": {
                                "type": "string",
                                "description": "\"daily\", \"weekly\" or \"monthly\" (scheduled), \"manual\", or \"pre_restore\" (taken before a restore)"
                              },
                              "status": {
                                "type": "string",
                                "description": "\"running\", \"complete\" or \"failed\" (error says why)"
                              },
                              "sizeBytes": {
                                "type": [
                                  "number",
                                  "null"
                                ],
                                "description": "Size of the stored file"
                              },
                              "bookmark": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "The restore point taken with it"
                              },
                              "createdAt": {
                                "type": "string",
                                "description": "ISO time"
                              },
                              "expiresAt": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "When a scheduled backup is deleted; null for the others"
                              }
                            },
                            "additionalProperties": true
                          }
                        },
                        "schedule": {
                          "type": "object",
                          "properties": {
                            "enabled": {
                              "type": "boolean",
                              "description": "true on a paid plan"
                            },
                            "frequency": {
                              "type": "string",
                              "description": "\"daily\", or \"weekly\" for a database of several gigabytes"
                            },
                            "nextRunAt": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "The next run"
                            },
                            "lastRunAt": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "The last run"
                            },
                            "lastStatus": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "\"complete\", \"skipped_unchanged\" (no write since lastBackupAt) or \"failed\" (lastError says why; the next night tries again)"
                            },
                            "lastBackupAt": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "The newest scheduled backup"
                            },
                            "retention": {
                              "type": [
                                "object",
                                "null"
                              ],
                              "description": "{ daily, weekly, monthly }: days, weeks and months each kind is kept; null on the free plan",
                              "additionalProperties": true
                            }
                          },
                          "additionalProperties": true
                        },
                        "timeTravel": {
                          "type": "object",
                          "description": "{ availableFrom, availableTo } — the window of Restore to a Point in Time",
                          "additionalProperties": true
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "backups": [
                      {
                        "id": "bkp_01k6xg",
                        "env": "live",
                        "kind": "daily",
                        "status": "complete",
                        "sizeBytes": 18233,
                        "bookmark": "00000085-00000001-4f1c",
                        "createdAt": "2026-10-08T02:10:00.000Z",
                        "expiresAt": "2026-10-15T02:10:00.000Z"
                      }
                    ],
                    "schedule": {
                      "enabled": true,
                      "frequency": "daily",
                      "nextRunAt": "2026-10-09T02:10:00.000Z",
                      "lastRunAt": "2026-10-08T02:10:00.000Z",
                      "lastStatus": "complete",
                      "lastBackupAt": "2026-10-08T02:10:00.000Z",
                      "retention": {
                        "daily": 7,
                        "weekly": 4,
                        "monthly": 3
                      }
                    },
                    "timeTravel": {
                      "availableFrom": "2026-09-08T12:00:00.000Z",
                      "availableTo": "2026-10-08T12:00:00.000Z"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      },
      "post": {
        "operationId": "createBackup",
        "summary": "Create Backup",
        "description": "Dump one database now. One manual backup per 10 minutes per project. Poll List Backups until status is \"complete\".\n\nFull reference: https://www.totalum.app/docs/api/database-backups#create-backup",
        "tags": [
          "Database Backups & Restore"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project ID"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "env": {
                    "type": "string",
                    "description": "\"live\" (default) or \"dev\""
                  }
                },
                "additionalProperties": true
              },
              "example": {
                "env": "live"
              }
            }
          }
        },
        "x-totalum-cost": "2 credits",
        "externalDocs": {
          "description": "Create Backup — Totalum docs",
          "url": "https://www.totalum.app/docs/api/database-backups#create-backup"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "backupId": {
                          "type": "string",
                          "description": "The backup being written"
                        },
                        "status": {
                          "type": "string",
                          "description": "\"running\""
                        },
                        "creditsCharged": {
                          "type": "number",
                          "description": "2 (BACKUP_CREATE_MANUAL in Get Credit Costs)"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "backupId": "bkp_01k6xj",
                    "status": "running",
                    "creditsCharged": 2
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "404": {
            "description": "`DEV_DATABASE_NOT_FOUND` — env is \"dev\" and the project has no development database",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "`BACKUP_RATE_LIMITED` — A manual backup was made less than 10 minutes ago",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/database/backups/{backupId}/download": {
      "get": {
        "operationId": "downloadBackup",
        "summary": "Download Backup",
        "description": "A 15-minute link to a complete backup as standard SQLite SQL (every row, including password hashes and sessions; uploaded files are not included). A scheduled backup is gzip-compressed (.sql.gz).\n\nFull reference: https://www.totalum.app/docs/api/database-backups#download-backup",
        "tags": [
          "Database Backups & Restore"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project ID"
          },
          {
            "name": "backupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "From List Backups"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Download Backup — Totalum docs",
          "url": "https://www.totalum.app/docs/api/database-backups#download-backup"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "url": {
                          "type": "string",
                          "description": "Signed download URL (15 minutes)"
                        },
                        "fileName": {
                          "type": "string",
                          "description": "Suggested file name"
                        },
                        "sizeBytes": {
                          "type": "number",
                          "description": "Size of the file"
                        },
                        "sha256": {
                          "type": "string",
                          "description": "SHA-256 of the file"
                        },
                        "importRecipe": {
                          "type": "string",
                          "description": "sqlite3 my-project.sqlite < <fileName>, or gunzip -c <fileName> | sqlite3 my-project.sqlite for a .sql.gz"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "url": "https://files.totalum.app/backups/…",
                    "fileName": "barber-bookings-live-2026-10-08.sql",
                    "sizeBytes": 18233,
                    "sha256": "3b1f…",
                    "importRecipe": "sqlite3 my-project.sqlite < barber-bookings-live-2026-10-08.sql"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "404": {
            "description": "`BACKUP_NOT_FOUND` — No such backup, or it has no complete dump",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/database/backups/{backupId}/restore": {
      "post": {
        "operationId": "restoreBackup",
        "summary": "Restore Backup",
        "description": "Put a database back to one of its backups (scheduled, manual or pre-restore). A backup of the current state is taken first; then the database is emptied, the backup is loaded and its tables, row counts and migration history are checked against the backup. If the load fails, the database goes back to the state before the restore. Every write made since the backup is lost. Poll GET /projects/:projectId/state until the operation ends.\n\nFull reference: https://www.totalum.app/docs/api/database-backups#restore-backup",
        "tags": [
          "Database Backups & Restore"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project ID"
          },
          {
            "name": "backupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "From List Backups, with status \"complete\""
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "confirm": {
                    "type": "string",
                    "description": "The project ID, typed to confirm"
                  }
                },
                "required": [
                  "confirm"
                ],
                "additionalProperties": true
              },
              "example": {
                "confirm": "barber-bookings"
              }
            }
          }
        },
        "x-totalum-cost": "4 credits",
        "externalDocs": {
          "description": "Restore Backup — Totalum docs",
          "url": "https://www.totalum.app/docs/api/database-backups#restore-backup"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string",
                          "description": "\"restoring\""
                        },
                        "env": {
                          "type": "string",
                          "description": "The database restored (the backup's own)"
                        },
                        "restoredTo": {
                          "type": "string",
                          "description": "backup:<backupId> (on a database moved to Turso: turso:<ISO time of the backup>)"
                        },
                        "previousBookmark": {
                          "type": "string",
                          "description": "The point taken just before — restoring to it undoes this restore"
                        },
                        "preRestoreBackupId": {
                          "type": "string",
                          "description": "The backup taken first; the restore runs only once it is complete"
                        },
                        "operation": {
                          "type": "object",
                          "description": "{ kind: \"backupRestore\", id } — progress in GET /projects/:projectId/state",
                          "additionalProperties": true
                        },
                        "creditsCharged": {
                          "type": "number",
                          "description": "4 (BACKUP_RESTORE in Get Credit Costs)"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "env": "live",
                    "status": "restoring",
                    "restoredTo": "backup:bkp_01k6xj",
                    "previousBookmark": "00000091-00000002-77aa",
                    "preRestoreBackupId": "bkp_01k6xk",
                    "operation": {
                      "kind": "backupRestore",
                      "id": "op_01k6xm"
                    },
                    "creditsCharged": 4
                  }
                }
              }
            }
          },
          "400": {
            "description": "`CONFIRMATION_REQUIRED` — confirm is not the project ID\n`VALIDATION_ERROR` — On a database moved to Turso, the backup is from before the move (errorDetails.availableFrom): download it, or restore a point in time from availableFrom on. Nothing is charged",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "404": {
            "description": "`BACKUP_NOT_FOUND` — No such backup, or it has no complete dump",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "`RESTORE_BEFORE_LIVE_MIGRATION` — The live backup is older than the database changes the published site needs; unpublish first\n`BACKUP_TOO_LARGE_FOR_IMPORT` — The backup is too large to load in place: download it, or use Restore to a Point in Time\n`AGENT_RUNNING` — The agent is running\n`OPERATION_IN_PROGRESS` — Another operation is in progress",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/database/backups/{backupId}": {
      "delete": {
        "operationId": "deleteBackup",
        "summary": "Delete Backup",
        "description": "Delete a manual or pre-restore backup. Scheduled backups are deleted by their retention.\n\nFull reference: https://www.totalum.app/docs/api/database-backups#delete-backup",
        "tags": [
          "Database Backups & Restore"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project ID"
          },
          {
            "name": "backupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "From List Backups"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Delete Backup — Totalum docs",
          "url": "https://www.totalum.app/docs/api/database-backups#delete-backup"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "deleted": {
                          "type": "boolean",
                          "description": "true"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "deleted": true
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "404": {
            "description": "`BACKUP_NOT_FOUND` — No such backup",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "`BACKUP_NOT_DELETABLE` — Only manual and pre-restore backups can be deleted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/database/bookmarks": {
      "get": {
        "operationId": "listRestorePoints",
        "summary": "List Restore Points",
        "description": "Every restore point, newest first. Query runId to see one agent run's.\n\nFull reference: https://www.totalum.app/docs/api/database-backups#list-restore-points",
        "tags": [
          "Database Backups & Restore"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project ID"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "List Restore Points — Totalum docs",
          "url": "https://www.totalum.app/docs/api/database-backups#list-restore-points"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "databaseCase": {
                          "type": "string",
                          "description": "\"dev+live\": the agent works on the development database"
                        },
                        "items": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "env": {
                                "type": "string",
                                "description": "The database"
                              },
                              "bookmark": {
                                "type": "string",
                                "description": "Send it to Restore to a Restore Point"
                              },
                              "at": {
                                "type": "string",
                                "description": "ISO time it was taken"
                              },
                              "kind": {
                                "type": "string",
                                "description": "\"run\" or \"pre_restore\""
                              },
                              "runId": {
                                "type": "string",
                                "description": "The agent run that took it"
                              }
                            },
                            "additionalProperties": true
                          }
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "databaseCase": "dev+live",
                    "items": [
                      {
                        "env": "dev",
                        "bookmark": "00000085-00000001-4f1c",
                        "at": "2026-10-08T11:10:02.000Z",
                        "kind": "run",
                        "runId": "run_01k6xc4n7d"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/database/restore": {
      "post": {
        "operationId": "restoreToARestorePoint",
        "summary": "Restore to a Restore Point",
        "description": "Put one database back to a restore point from List Restore Points — for example the moment before the agent changed it. Free: it undoes an agent step.\n\nFull reference: https://www.totalum.app/docs/api/database-backups#restore-to-a-restore-point",
        "tags": [
          "Database Backups & Restore"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project ID"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "bookmark": {
                    "type": "string",
                    "description": "From List Restore Points"
                  },
                  "env": {
                    "type": "string",
                    "description": "\"live\" (default) or \"dev\""
                  },
                  "confirm": {
                    "type": "string",
                    "description": "The project ID, typed to confirm"
                  }
                },
                "required": [
                  "bookmark",
                  "confirm"
                ],
                "additionalProperties": true
              },
              "example": {
                "bookmark": "00000085-00000001-4f1c",
                "env": "dev",
                "confirm": "barber-bookings"
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Restore to a Restore Point — Totalum docs",
          "url": "https://www.totalum.app/docs/api/database-backups#restore-to-a-restore-point"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string",
                          "description": "\"restoring\""
                        },
                        "env": {
                          "type": "string",
                          "description": "The environment restored"
                        },
                        "restoredTo": {
                          "type": "string",
                          "description": "The Time-Travel bookmark restored to"
                        },
                        "previousBookmark": {
                          "type": "string",
                          "description": "The point taken just before — restoring to it undoes this restore"
                        },
                        "preRestoreBackupId": {
                          "type": "string",
                          "description": "The backup taken first; the restore runs only once it is complete"
                        },
                        "operation": {
                          "type": "object",
                          "description": "{ kind: \"backupRestore\", id } — progress in GET /projects/:projectId/state",
                          "additionalProperties": true
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "env": "dev",
                    "status": "restoring",
                    "restoredTo": "00000085-00000001-4f1c",
                    "previousBookmark": "00000091-00000002-77aa",
                    "preRestoreBackupId": "bkp_01k6xn",
                    "operation": {
                      "kind": "backupRestore",
                      "id": "op_01k6xp"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`CONFIRMATION_REQUIRED` — confirm is not the project ID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "404": {
            "description": "`BOOKMARK_NOT_FOUND` — The bookmark is not a restore point of this database\n`DEV_DATABASE_NOT_FOUND` — env is \"dev\" and the project has no development database",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "`RESTORE_BEFORE_LIVE_MIGRATION` — The live point lies before database changes the published site needs (errorDetails: deploymentId, migrations, earliestPoint); choose earliestPoint or later, or unpublish first\n`AGENT_RUNNING` — An agent run is in progress\n`OPERATION_IN_PROGRESS` — Another operation (a restore, a publish…) is running",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/database/time-travel/restore": {
      "post": {
        "operationId": "restoreToAPointInTime",
        "summary": "Restore to a Point in Time",
        "description": "Put one database back to any minute of the last 30 days (on a database moved to Turso: from the move on, timeTravel.availableFrom in List Backups).\n\nFull reference: https://www.totalum.app/docs/api/database-backups#restore-to-a-point-in-time",
        "tags": [
          "Database Backups & Restore"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project ID"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "env": {
                    "type": "string",
                    "description": "\"live\" (default) or \"dev\""
                  },
                  "timestamp": {
                    "type": "string",
                    "description": "ISO time within the last 30 days"
                  },
                  "confirm": {
                    "type": "string",
                    "description": "The project ID, typed to confirm"
                  }
                },
                "required": [
                  "timestamp",
                  "confirm"
                ],
                "additionalProperties": true
              },
              "example": {
                "env": "live",
                "timestamp": "2026-10-08T09:00:00.000Z",
                "confirm": "barber-bookings"
              }
            }
          }
        },
        "x-totalum-cost": "4 credits",
        "externalDocs": {
          "description": "Restore to a Point in Time — Totalum docs",
          "url": "https://www.totalum.app/docs/api/database-backups#restore-to-a-point-in-time"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string",
                          "description": "\"restoring\""
                        },
                        "env": {
                          "type": "string",
                          "description": "The environment restored"
                        },
                        "restoredTo": {
                          "type": "string",
                          "description": "The Time-Travel bookmark restored to"
                        },
                        "previousBookmark": {
                          "type": "string",
                          "description": "The point taken just before — restoring to it undoes this restore"
                        },
                        "preRestoreBackupId": {
                          "type": "string",
                          "description": "The backup taken first; the restore runs only once it is complete"
                        },
                        "operation": {
                          "type": "object",
                          "description": "{ kind: \"backupRestore\", id } — progress in GET /projects/:projectId/state",
                          "additionalProperties": true
                        },
                        "creditsCharged": {
                          "type": "number",
                          "description": "4 (BACKUP_RESTORE in Get Credit Costs)"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "env": "live",
                    "status": "restoring",
                    "restoredTo": "00000080-00000003-1a2b",
                    "previousBookmark": "00000091-00000002-77aa",
                    "preRestoreBackupId": "bkp_01k6xq",
                    "operation": {
                      "kind": "backupRestore",
                      "id": "op_01k6xr"
                    },
                    "creditsCharged": 4
                  }
                }
              }
            }
          },
          "400": {
            "description": "`VALIDATION_ERROR` — timestamp is outside the last 30 days or, on a database moved to Turso, before the move (its point-in-time history starts there; errorDetails.availableFrom, also in GET …/database/backups?env= as timeTravel.availableFrom)\n`CONFIRMATION_REQUIRED` — confirm is not the project ID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "404": {
            "description": "`DEV_DATABASE_NOT_FOUND` — env is \"dev\" and the project has no development database",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "`RESTORE_BEFORE_LIVE_MIGRATION` — The live point lies before database changes the published site needs (errorDetails: deploymentId, migrations, earliestPoint); choose earliestPoint or later, or unpublish first\n`RESTORE_VERIFY_FAILED` — Time Travel resolved timestamp to a state older or newer than a restore point recorded around that time; nothing was restored (errorDetails: timestamp, resolvedBookmark, restorePoint). Restore to that recorded point instead: its bookmark with Restore to a Restore Point\n`AGENT_RUNNING` — An agent run is in progress\n`OPERATION_IN_PROGRESS` — Another operation (a restore, a publish…) is running",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/database/migrate-provider": {
      "post": {
        "operationId": "moveToTurso",
        "summary": "Move to Turso",
        "description": "Move the project's database to Turso, (a managed Turso database, run by Totalum). One way: it cannot be moved back. The 50 credits are refunded in full when the move fails before the switch. Both databases, live and dev, move. Available on the Builder plan and above.\n\nFull reference: https://www.totalum.app/docs/api/database-backups#move-to-turso",
        "tags": [
          "Database Backups & Restore"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project ID"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "to": {
                    "type": "string",
                    "description": "\"turso\""
                  },
                  "confirm": {
                    "type": "string",
                    "description": "The project ID, typed to confirm"
                  }
                },
                "required": [
                  "to",
                  "confirm"
                ],
                "additionalProperties": true
              },
              "example": {
                "to": "turso",
                "confirm": "barber-bookings"
              }
            }
          }
        },
        "x-totalum-cost": "50 credits",
        "externalDocs": {
          "description": "Move to Turso — Totalum docs",
          "url": "https://www.totalum.app/docs/api/database-backups#move-to-turso"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "operation": {
                          "type": "object",
                          "description": "{ kind: \"dbProviderMigration\", id, status, startedAt, to, envs, estimateSec, databaseBytes } — follow it in GET /projects/:projectId/state (below)",
                          "additionalProperties": true
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "operation": {
                      "kind": "dbProviderMigration",
                      "id": "op_01k6xs",
                      "status": "running",
                      "startedAt": "2026-10-08T12:00:00.000Z",
                      "to": "turso",
                      "envs": [
                        "live",
                        "dev"
                      ],
                      "estimateSec": 240,
                      "databaseBytes": 2457600
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`CONFIRMATION_REQUIRED` — confirm is not the project ID\n`MIGRATION_NOT_REVERSIBLE` — to is not \"turso\"",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "`INSUFFICIENT_CREDITS` — Fewer than 50 credits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "`PLAN_REQUIRED` — The account's plan is below Builder",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "`ALREADY_ON_PROVIDER` — The project is already on Turso\n`AGENT_RUNNING` — An agent run is in progress",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/files/tree": {
      "get": {
        "operationId": "getProjectTree",
        "summary": "Get Project Tree",
        "description": "The project's files and folders, as a flat, sorted list. node_modules, .next, .git, dist and other build output are never included.\n\nFull reference: https://www.totalum.app/docs/api/project-files#get-project-tree",
        "tags": [
          "Project Files"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project ID"
          },
          {
            "name": "path",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Limit the tree to one subfolder, e.g. src/app. Default: the whole project"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number"
            },
            "description": "Page size. Default 2000, max 5000"
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number"
            },
            "description": "Entries to skip. Default 0"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Project Tree — Totalum docs",
          "url": "https://www.totalum.app/docs/api/project-files#get-project-tree"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "entries": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "path": {
                                "type": "string",
                                "description": "Path relative to the project root, e.g. src/app/page.tsx"
                              },
                              "name": {
                                "type": "string",
                                "description": "File or folder name"
                              },
                              "type": {
                                "type": "string",
                                "description": "\"file\" or \"folder\""
                              },
                              "size": {
                                "type": "number",
                                "description": "Size in bytes. Files only"
                              },
                              "depth": {
                                "type": "number",
                                "description": "0 at the project root"
                              }
                            },
                            "additionalProperties": true
                          }
                        },
                        "totalEntries": {
                          "type": "number",
                          "description": "Entries matching the request before paging"
                        },
                        "offset": {
                          "type": "number",
                          "description": "The offset used"
                        },
                        "limit": {
                          "type": "number",
                          "description": "The limit used"
                        },
                        "hasMore": {
                          "type": "boolean",
                          "description": "true when more entries follow"
                        },
                        "commitSha": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Git commit the tree was read from"
                        },
                        "filesCount": {
                          "type": "number",
                          "description": "Files tracked in the project, before exclusions"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "entries": [
                      {
                        "path": "src/app",
                        "name": "app",
                        "type": "folder",
                        "depth": 1
                      },
                      {
                        "path": "src/app/layout.tsx",
                        "name": "layout.tsx",
                        "type": "file",
                        "size": 1284,
                        "depth": 2
                      },
                      {
                        "path": "src/app/page.tsx",
                        "name": "page.tsx",
                        "type": "file",
                        "size": 3902,
                        "depth": 2
                      }
                    ],
                    "totalEntries": 3,
                    "offset": 0,
                    "limit": 100,
                    "hasMore": false,
                    "commitSha": "a1b2c3d",
                    "filesCount": 47
                  }
                }
              }
            }
          },
          "400": {
            "description": "`INVALID_PATH` — The path is absolute, contains .., or points inside an excluded folder",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "404": {
            "description": "`PROJECT_NOT_FOUND` — Project does not exist or you don't own it",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "`PROJECT_TOO_LARGE` — The project archive is too large to browse through the API — download it instead",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/files/content": {
      "get": {
        "operationId": "getFileContent",
        "summary": "Get File Content",
        "description": "The complete content of one file. Files up to 1 MB.\n\nFull reference: https://www.totalum.app/docs/api/project-files#get-file-content",
        "tags": [
          "Project Files"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project ID"
          },
          {
            "name": "path",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Path relative to the project root, e.g. src/app/page.tsx"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get File Content — Totalum docs",
          "url": "https://www.totalum.app/docs/api/project-files#get-file-content"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "path": {
                          "type": "string",
                          "description": "The normalised path"
                        },
                        "name": {
                          "type": "string",
                          "description": "File name"
                        },
                        "size": {
                          "type": "number",
                          "description": "Size of the stored file in bytes"
                        },
                        "encoding": {
                          "type": "string",
                          "description": "\"utf8\" for text, \"base64\" for binary"
                        },
                        "content": {
                          "type": "string",
                          "description": "The file content, in encoding"
                        },
                        "commitSha": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Git commit the file was read from"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "path": "src/app/page.tsx",
                    "name": "page.tsx",
                    "size": 62,
                    "encoding": "utf8",
                    "content": "export default function Page() {\n  return <h1>Hello</h1>;\n}\n",
                    "commitSha": "a1b2c3d"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`INVALID_PATH` — The path is absolute, contains .., or points inside an excluded folder",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "404": {
            "description": "`PROJECT_NOT_FOUND` — Project does not exist or you don't own it\n`FILE_NOT_FOUND` — No file at that path",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "errors": {
                    "errorCode": "FILE_NOT_FOUND",
                    "errorMessage": "No file at \"src/app/missing.tsx\" in this project."
                  },
                  "data": null
                }
              }
            }
          },
          "413": {
            "description": "`FILE_TOO_LARGE` — The file is larger than 1 MB — download the source archive instead",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "put": {
        "operationId": "writeFileContent",
        "summary": "Write File Content",
        "description": "Create or replace one file (up to 512 KB). Missing folders are created. The write is saved as a version and the preview is rebuilt with it (a new file under public/ can make the preview answer 503 updating for a minute or two).\n\nFull reference: https://www.totalum.app/docs/api/project-files#write-file-content",
        "tags": [
          "Project Files"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "path": {
                    "type": "string",
                    "description": "Path from the project root, e.g. src/app/page.tsx"
                  },
                  "content": {
                    "type": "string",
                    "description": "The complete new content (\"\" empties the file)"
                  },
                  "encoding": {
                    "type": "string",
                    "description": "\"utf8\" (default) or \"base64\" for binary files"
                  },
                  "baseSha256": {
                    "type": "string",
                    "description": "SHA-256 (hex) of the file as you read it: if it changed since (the agent, a restore), the write is refused with 409 FILE_CHANGED"
                  }
                },
                "required": [
                  "path",
                  "content"
                ],
                "additionalProperties": true
              },
              "example": {
                "path": "src/app/hello/page.tsx",
                "content": "export default function Hello() {\n  return <h1>Hello</h1>;\n}\n"
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Write File Content — Totalum docs",
          "url": "https://www.totalum.app/docs/api/project-files#write-file-content"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "path": {
                          "type": "string",
                          "description": "Normalised path"
                        },
                        "created": {
                          "type": "boolean",
                          "description": "true when the file is new"
                        },
                        "bytesWritten": {
                          "type": "number",
                          "description": "Bytes written (saved writes only)"
                        },
                        "commitSha": {
                          "type": "string",
                          "description": "The commit of the new version"
                        },
                        "filesCount": {
                          "type": "number",
                          "description": "Files in the project after the write"
                        },
                        "rebuildRequired": {
                          "type": "boolean",
                          "description": "Always false: the write deploys itself"
                        },
                        "saved": {
                          "type": "boolean",
                          "description": "false on a 202 (still saving)"
                        },
                        "versionId": {
                          "type": "string",
                          "description": "On a 202: the version being saved"
                        },
                        "message": {
                          "type": "string",
                          "description": "On a 202: what to do"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "path": "src/app/hello/page.tsx",
                    "bytesWritten": 58,
                    "created": true,
                    "commitSha": "d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3",
                    "filesCount": 97,
                    "rebuildRequired": false
                  }
                }
              }
            }
          },
          "400": {
            "description": "`INVALID_PATH` — Absolute, contains .., or inside an excluded folder\n`MISSING_CONTENT` — content is missing or not a string\n`INVALID_ENCODING` — Not utf8 or base64",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "409": {
            "description": "`FILE_CHANGED` — The file changed since your baseSha256\n`AGENT_RUNNING` — A prompt is running\n`OPERATION_IN_PROGRESS` — A publish, restore or import is running",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "`FILE_TOO_LARGE` — Over 512 KB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "`RATE_LIMITED` — More than 300 writes a minute",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/rebuild": {
      "post": {
        "operationId": "rebuildProject",
        "summary": "Rebuild Project",
        "description": "Build the current version again and redeploy the preview — for example after the preview failed to build. Takes 1–4 minutes; poll Get Rebuild Status.\n\nFull reference: https://www.totalum.app/docs/api/project-files#rebuild-project",
        "tags": [
          "Project Files"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "x-totalum-cost": "2 credits",
        "externalDocs": {
          "description": "Rebuild Project — Totalum docs",
          "url": "https://www.totalum.app/docs/api/project-files#rebuild-project"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "projectId": {
                          "type": "string",
                          "description": "Project id"
                        },
                        "status": {
                          "type": "string",
                          "description": "\"rebuilding\""
                        },
                        "startedAt": {
                          "type": "string",
                          "description": "ISO 8601"
                        },
                        "message": {
                          "type": "string",
                          "description": "Next step"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "projectId": "barber-bookings",
                    "status": "rebuilding",
                    "startedAt": "2026-10-08T12:20:00.000Z",
                    "message": "Rebuild started. It usually takes 1-4 minutes. Poll GET /projects/barber-bookings/rebuild/status until status is \"success\" or \"error\"."
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "`INSUFFICIENT_CREDITS` — Not enough credits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "409": {
            "description": "`REBUILD_RUNNING` — A rebuild is already running\n`AGENT_RUNNING` — A prompt is running\n`DEPLOYMENT_RUNNING` — A publish is running",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/rebuild/status": {
      "get": {
        "operationId": "getRebuildStatus",
        "summary": "Get Rebuild Status",
        "description": "The newest rebuild. A failed rebuild is status: \"error\" in a 200 answer.\n\nFull reference: https://www.totalum.app/docs/api/project-files#get-rebuild-status",
        "tags": [
          "Project Files"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Rebuild Status — Totalum docs",
          "url": "https://www.totalum.app/docs/api/project-files#get-rebuild-status"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "projectId": {
                          "type": "string",
                          "description": "Project id"
                        },
                        "status": {
                          "type": "string",
                          "description": "\"idle\" (never rebuilt), \"rebuilding\", \"success\" or \"error\""
                        },
                        "startedAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "ISO 8601"
                        },
                        "finishedAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "ISO 8601"
                        },
                        "elapsedSeconds": {
                          "type": [
                            "number",
                            "null"
                          ],
                          "description": "Duration so far, or total"
                        },
                        "livePreviewUrl": {
                          "type": "string",
                          "description": "The preview, after a success"
                        },
                        "errorCode": {
                          "type": "string",
                          "description": "On \"error\""
                        },
                        "errorMessage": {
                          "type": "string",
                          "description": "On \"error\""
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "projectId": "barber-bookings",
                    "status": "success",
                    "startedAt": "2026-10-08T12:20:00.000Z",
                    "finishedAt": "2026-10-08T12:22:10.000Z",
                    "elapsedSeconds": 130,
                    "livePreviewUrl": "https://barber-bookings-dev-temporal-link-preview-k3y9x2ab.totalum-project.com"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/source-code": {
      "get": {
        "operationId": "downloadSourceCode",
        "summary": "Download Source Code",
        "description": "A short-lived link to the project's current code as an archive. With the project's .env (Get Project Env) it runs locally with npm ci && npm run dev. Downloading source code is included on paid plans.\n\nFull reference: https://www.totalum.app/docs/api/source-files#download-source-code",
        "tags": [
          "Source Code & Uploads"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          },
          {
            "name": "intent",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "view when you only show the code (for example in a code viewer), which works on every plan"
          }
        ],
        "x-totalum-cost": "2 credits",
        "externalDocs": {
          "description": "Download Source Code — Totalum docs",
          "url": "https://www.totalum.app/docs/api/source-files#download-source-code"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "filesCount": {
                          "type": "number",
                          "description": "Files in the archive"
                        },
                        "lastCommitSha": {
                          "type": "string",
                          "description": "Commit of the current version"
                        },
                        "downloadUrl": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Signed download URL (valid a few minutes)"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "filesCount": 96,
                    "lastCommitSha": "9f2c1ab4d3e5f60718293a4b5c6d7e8f90a1b2c3",
                    "downloadUrl": "https://files.totalum.app/source/barber-bookings.tar.gz?sig=…"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "`INSUFFICIENT_CREDITS` — Not enough credits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "`PLATFORM_CAPABILITY_QUOTA_REACHED` — Source download is not included on your plan (upgradePlan says which is needed)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/files/upload": {
      "post": {
        "operationId": "uploadFile",
        "summary": "Upload File",
        "description": "Upload one file (up to 20 MB) as multipart/form-data with the field file. Use the returned url in inputFiles of Run AI Agent. For a bigger file, pass its own public URL in inputFiles instead; no upload is needed.\n\nFull reference: https://www.totalum.app/docs/api/source-files#upload-file",
        "tags": [
          "Source Code & Uploads"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "The file, up to 20 MB"
                  },
                  "private": {
                    "type": "string",
                    "description": "\"true\" = stored privately (served only through signed links)"
                  }
                },
                "required": [
                  "file"
                ],
                "additionalProperties": true
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Upload File — Totalum docs",
          "url": "https://www.totalum.app/docs/api/source-files#upload-file"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "fileNameId": {
                          "type": "string",
                          "description": "The stored file's key"
                        },
                        "url": {
                          "type": "string",
                          "description": "Its URL (for inputFiles)"
                        },
                        "private": {
                          "type": "boolean",
                          "description": "true for a private file"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "fileNameId": "uploads/01k6y1-logo.png",
                    "url": "https://files.totalum.app/barber-bookings/uploads/01k6y1-logo.png"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`MISSING_FILE` — No multipart field file",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "413": {
            "description": "`FILE_TOO_LARGE` — Over 20 MB — pass the file's own URL in inputFiles instead",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "`RATE_LIMITED` — More than 300 uploads a minute",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/secrets": {
      "post": {
        "operationId": "createSecret",
        "summary": "Create Secret",
        "description": "Add an environment variable. It reaches the preview and the agent at once and the published site at the next publish. The agent never asks for a key in its reply text: when the app needs one, its message carries secretKeysNeeded (Get Agent Status). Let your user choose the environment, add each name here, then prompt again (\"the keys are saved, carry on\").\n\nFull reference: https://www.totalum.app/docs/api/secrets#create-secret",
        "tags": [
          "Secrets, Keys & .env"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "secretName": {
                    "type": "string",
                    "description": "Uppercase letters, digits and _, starting with a letter. Names starting with TOTALUM_ (except TOTALUM_VCAAS_API_KEY) and NODE_ENV, NEXT_PUBLIC_APP_URL, BETTER_AUTH_SECRET, NEXT_SERVER_ACTIONS_ENCRYPTION_KEY, TURSO_AUTH_TOKEN, TURSO_DATABASE_URL are reserved"
                  },
                  "secretValue": {
                    "type": "string",
                    "description": "1–10,000 characters"
                  },
                  "environment": {
                    "type": "string",
                    "description": "\"development\" (preview), \"production\" (published site) or \"both\" (default)"
                  }
                },
                "required": [
                  "secretName",
                  "secretValue"
                ],
                "additionalProperties": true
              },
              "example": {
                "secretName": "OPENWEATHER_KEY",
                "secretValue": "abc123",
                "environment": "both"
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Create Secret — Totalum docs",
          "url": "https://www.totalum.app/docs/api/secrets#create-secret"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "_id": {
                          "type": "string",
                          "description": "Secret id (to delete it)"
                        },
                        "secretName": {
                          "type": "string",
                          "description": "Name"
                        },
                        "environment": {
                          "type": "string",
                          "description": "Environment"
                        },
                        "createdAt": {
                          "type": "string",
                          "description": "ISO 8601"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "_id": "sec_01k6xy",
                    "secretName": "OPENWEATHER_KEY",
                    "environment": "both",
                    "createdAt": "2026-10-08T12:00:00.000Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`MISSING_SECRET_FIELDS` — secretName or secretValue is missing\n`VALIDATION_ERROR` — The name, value or environment is invalid; errorDetails.errors lists each field\n`SECRET_CREATE_FAILED` — A secret with this name already exists in that environment\n`RESERVED_SECRET_NAME` — The name is reserved\n`SECRET_LIMIT_EXCEEDED` — The project already has 500 secrets",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "errors": {
                    "errorCode": "VALIDATION_ERROR",
                    "errorMessage": "secretName: Secret name must be uppercase, separated by underscores, cannot start with a number, and can only contain letters, numbers, and underscores",
                    "errorDetails": {
                      "errors": [
                        {
                          "value": "openweather",
                          "msg": "Secret name must be uppercase, separated by underscores, cannot start with a number, and can only contain letters, numbers, and underscores",
                          "param": "secretName",
                          "location": "body"
                        }
                      ]
                    }
                  },
                  "data": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/secrets/{secretId}": {
      "delete": {
        "operationId": "deleteSecret",
        "summary": "Delete Secret",
        "description": "Remove an environment variable. The names and ids of a project's secrets are in Get Project (secrets[]).\n\nFull reference: https://www.totalum.app/docs/api/secrets#delete-secret",
        "tags": [
          "Secrets, Keys & .env"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          },
          {
            "name": "secretId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The secret's _id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Delete Secret — Totalum docs",
          "url": "https://www.totalum.app/docs/api/secrets#delete-secret"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "success": {
                          "type": "boolean",
                          "description": "true"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "success": true
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/api-keys": {
      "get": {
        "operationId": "listProjectKeys",
        "summary": "List Project Keys",
        "description": "The project's own API keys, revoked ones included (secrets are never listed). Two are managed by Totalum: managed: \"app\" runs the app itself, managed: \"env\" is the key in the downloaded .env; rotate them, never revoke them.\n\nFull reference: https://www.totalum.app/docs/api/secrets#list-project-keys",
        "tags": [
          "Secrets, Keys & .env"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "List Project Keys — Totalum docs",
          "url": "https://www.totalum.app/docs/api/secrets#list-project-keys"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "keys": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "description": "Key id"
                              },
                              "name": {
                                "type": "string",
                                "description": "Name"
                              },
                              "prefix": {
                                "type": "string",
                                "description": "The visible start of the key"
                              },
                              "scopes": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                },
                                "description": "Scopes"
                              },
                              "env": {
                                "type": "string",
                                "description": "\"dev\", \"live\" or \"both\""
                              },
                              "createdAt": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "ISO 8601"
                              },
                              "expiresAt": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Expiry"
                              },
                              "revokedAt": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "When it was revoked"
                              },
                              "managed": {
                                "type": "string",
                                "description": "\"app\" or \"env\" for Totalum's own keys"
                              }
                            },
                            "additionalProperties": true
                          }
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "keys": [
                      {
                        "id": "key_01k6xz",
                        "name": "backend",
                        "prefix": "tlm_pk_a1b2",
                        "scopes": [
                          "db:read",
                          "db:write"
                        ],
                        "env": "both",
                        "createdAt": "2026-10-08T12:00:00.000Z",
                        "expiresAt": null,
                        "revokedAt": null
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      },
      "post": {
        "operationId": "createProjectApiKey",
        "summary": "Create Project API Key",
        "description": "Create a tlm_pk_ key for calling this project's database, files and built-in features from your servers (with totalum-sdk or HTTP). It works only on this project and only for its scopes. The secret is returned once. Owner (or a member allowed to manage API keys) only.\n\nFull reference: https://www.totalum.app/docs/api/secrets#create-project-api-key",
        "tags": [
          "Secrets, Keys & .env"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "A name"
                  },
                  "scopes": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "One or more scopes from the table"
                  },
                  "env": {
                    "type": "string",
                    "description": "\"dev\", \"live\" or both (default): the database environment the key may use"
                  }
                },
                "required": [
                  "name",
                  "scopes"
                ],
                "additionalProperties": true
              },
              "example": {
                "name": "backend",
                "scopes": [
                  "db:read",
                  "db:write",
                  "integrations:*"
                ]
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Create Project API Key — Totalum docs",
          "url": "https://www.totalum.app/docs/api/secrets#create-project-api-key"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "key": {
                          "type": "object",
                          "description": "The key, with the fields of List Project Keys",
                          "properties": {
                            "plaintext": {
                              "type": "string",
                              "description": "The secret — shown only now"
                            }
                          },
                          "additionalProperties": true
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "key": {
                      "id": "key_01k6xz",
                      "name": "backend",
                      "prefix": "tlm_pk_a1b2",
                      "scopes": [
                        "db:read",
                        "db:write",
                        "integrations:*"
                      ],
                      "env": "both",
                      "createdAt": "2026-10-08T12:00:00.000Z",
                      "expiresAt": null,
                      "revokedAt": null,
                      "plaintext": "tlm_pk_a1b2…"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`INVALID_SCOPES` — Empty or unknown scopes; the message lists the valid ones",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "`OWNER_ONLY` — Only the owner or a member allowed to manage API keys",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "`PROJECT_NOT_READY` — The project is still being set up; retry after Retry-After seconds",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/api-keys/{keyId}/rotate": {
      "post": {
        "operationId": "rotateProjectKey",
        "summary": "Rotate Project Key",
        "description": "Replace a key with a new secret (same name, scopes and environment); the old one stops at once. For the app's own key, the new key reaches the app before the old one stops.\n\nFull reference: https://www.totalum.app/docs/api/secrets#rotate-project-key",
        "tags": [
          "Secrets, Keys & .env"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          },
          {
            "name": "keyId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The key id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Rotate Project Key — Totalum docs",
          "url": "https://www.totalum.app/docs/api/secrets#rotate-project-key"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "key": {
                          "type": "object",
                          "description": "The new key, with plaintext (shown once)",
                          "additionalProperties": true
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "key": {
                      "id": "key_01k6y0",
                      "name": "backend",
                      "prefix": "tlm_pk_c3d4",
                      "scopes": [
                        "db:read",
                        "db:write",
                        "integrations:*"
                      ],
                      "env": "both",
                      "createdAt": "2026-10-08T12:10:00.000Z",
                      "expiresAt": null,
                      "revokedAt": null,
                      "plaintext": "tlm_pk_c3d4…"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "`OWNER_ONLY` — Only the owner or a member allowed to manage API keys",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "`KEY_NOT_FOUND` — Unknown or already revoked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/api-keys/{keyId}": {
      "delete": {
        "operationId": "revokeProjectKey",
        "summary": "Revoke Project Key",
        "description": "Revoke a key at once.\n\nFull reference: https://www.totalum.app/docs/api/secrets#revoke-project-key",
        "tags": [
          "Secrets, Keys & .env"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          },
          {
            "name": "keyId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The key id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Revoke Project Key — Totalum docs",
          "url": "https://www.totalum.app/docs/api/secrets#revoke-project-key"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "revoked": {
                          "type": "boolean",
                          "description": "true"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "revoked": true
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "`OWNER_ONLY` — Only the owner or a member allowed to manage API keys",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "`KEY_NOT_FOUND` — Unknown or already revoked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "`KEY_MANAGED` — The app's own key or the .env key: rotate it instead",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/env": {
      "get": {
        "operationId": "getProjectEnv",
        "summary": "Get Project Env",
        "description": "The project's .env file for one environment, as plain text (not JSON): the project key, the auth secret, the URLs and that environment's secrets. Save it as .env (dev) or .env.prod (live) next to the downloaded source to run the app locally; never commit it. Owner (or a member allowed to manage API keys) only.\n\nFull reference: https://www.totalum.app/docs/api/secrets#get-project-env",
        "tags": [
          "Secrets, Keys & .env"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          },
          {
            "name": "env",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "\"dev\" or \"live\""
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Project Env — Totalum docs",
          "url": "https://www.totalum.app/docs/api/secrets#get-project-env"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "(body)": {
                      "description": "The .env file (Content-Disposition: attachment)"
                    }
                  },
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "description": "`INVALID_ENV` — env is not dev or live",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "`OWNER_ONLY` — Only the owner or a member allowed to manage API keys",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/logs": {
      "get": {
        "operationId": "getProjectLogs",
        "summary": "Get Project Logs",
        "description": "Log lines of the preview or the published site, newest first, with filters.\n\nFull reference: https://www.totalum.app/docs/api/server#get-project-logs",
        "tags": [
          "Logs & Preview Server"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          },
          {
            "name": "env",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "\"dev\" (preview) or \"live\" (published site)"
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Start, ISO 8601"
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "End, ISO 8601"
          },
          {
            "name": "level",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "\"error\", \"warn\", \"info\", \"log\" or \"debug\""
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Text to find in the message (up to 200 characters)"
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "HTTP status of the request: 500, or a class like 5xx"
          },
          {
            "name": "path",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Request path"
          },
          {
            "name": "requestId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "One request's lines"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number"
            },
            "description": "1–500"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Project Logs — Totalum docs",
          "url": "https://www.totalum.app/docs/api/server#get-project-logs"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "items": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "ts": {
                                "type": "string",
                                "description": "ISO 8601 time"
                              },
                              "level": {
                                "type": "string",
                                "description": "error, warn, info, log or debug"
                              },
                              "message": {
                                "type": "string",
                                "description": "The text (secrets redacted)"
                              },
                              "requestId": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "The request it belongs to"
                              },
                              "method": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "HTTP method"
                              },
                              "path": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Request path"
                              },
                              "status": {
                                "type": [
                                  "number",
                                  "null"
                                ],
                                "description": "Response status"
                              },
                              "cpuMs": {
                                "type": [
                                  "number",
                                  "null"
                                ],
                                "description": "CPU time of the request"
                              },
                              "wallMs": {
                                "type": [
                                  "number",
                                  "null"
                                ],
                                "description": "Duration of the request"
                              },
                              "outcome": {
                                "type": "string",
                                "description": "How the request ended (ok, exception, canceled, …)"
                              },
                              "exception": {
                                "type": "object",
                                "description": "{ name, message, stack? } of an uncaught error",
                                "additionalProperties": true
                              }
                            },
                            "additionalProperties": true
                          },
                          "description": "Log lines"
                        },
                        "window": {
                          "type": "object",
                          "description": "{ from, to, source }: the range searched",
                          "additionalProperties": true
                        },
                        "nextCursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Cursor for older lines"
                        },
                        "sampled": {
                          "type": "boolean",
                          "description": "true when a very busy window was sampled"
                        },
                        "hint": {
                          "type": "string",
                          "description": "A suggestion when nothing matched"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "items": [
                      {
                        "ts": "2026-10-08T12:03:11.000Z",
                        "level": "error",
                        "message": "TotalumError [INSUFFICIENT_CREDITS]: The account has no credits",
                        "requestId": "9a1f2c",
                        "method": "POST",
                        "path": "/api/summary",
                        "status": 502,
                        "cpuMs": 4,
                        "wallMs": 210,
                        "outcome": "ok"
                      }
                    ],
                    "window": {
                      "from": "2026-10-08T06:03:00.000Z",
                      "to": "2026-10-08T12:03:30.000Z",
                      "source": "buffer"
                    },
                    "nextCursor": null,
                    "sampled": false
                  }
                }
              }
            }
          },
          "400": {
            "description": "`VALIDATION_ERROR` — A filter has an invalid value",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/backend/prod/logs": {
      "get": {
        "operationId": "getProductionLogs",
        "summary": "Get Production Logs",
        "description": "The published site's requests, one record per request with the console output and exceptions of that request nested in it. Without from/to it covers the last 6 hours (the last 3 days when to or regexSearch is given). At most 500 log lines are read.\n\nFull reference: https://www.totalum.app/docs/api/server#get-production-logs",
        "tags": [
          "Logs & Preview Server"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Start, ISO 8601"
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "End, ISO 8601"
          },
          {
            "name": "regexSearch",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Text to find — the fastest way to a specific request"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Production Logs — Totalum docs",
          "url": "https://www.totalum.app/docs/api/server#get-production-logs"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "ok": {
                          "type": "boolean",
                          "description": "true"
                        },
                        "organizationId": {
                          "type": "string",
                          "description": "The project id"
                        },
                        "fromMs": {
                          "type": "number",
                          "description": "Start of the range (epoch ms)"
                        },
                        "toMs": {
                          "type": "number",
                          "description": "End of the range (epoch ms)"
                        },
                        "regexSearch": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "The search"
                        },
                        "count": {
                          "type": "number",
                          "description": "Records returned"
                        },
                        "records": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "EventTimestampMs": {
                                "type": "number",
                                "description": "When it was served"
                              },
                              "Outcome": {
                                "type": "string",
                                "description": "How it ended"
                              },
                              "WallTimeMs": {
                                "type": "number",
                                "description": "Duration"
                              },
                              "CPUTimeMs": {
                                "type": "number",
                                "description": "CPU time"
                              },
                              "Event": {
                                "type": "object",
                                "properties": {
                                  "Request": {
                                    "type": "object",
                                    "description": "{ URL, Method }",
                                    "additionalProperties": true
                                  },
                                  "Response": {
                                    "type": "object",
                                    "description": "{ Status }",
                                    "additionalProperties": true
                                  }
                                },
                                "additionalProperties": true
                              },
                              "Logs": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "additionalProperties": true
                                },
                                "description": "{ Level, Message: [text], TimestampMs }"
                              },
                              "Exceptions": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "additionalProperties": true
                                },
                                "description": "{ Name, Message, TimestampMs }"
                              }
                            },
                            "additionalProperties": true
                          },
                          "description": "One per request"
                        },
                        "totalChars": {
                          "type": "number",
                          "description": "Size of the records"
                        },
                        "truncated": {
                          "type": "boolean",
                          "description": "true when the 500-line read limit was hit — narrow the range"
                        },
                        "window": {
                          "type": "object",
                          "description": "{ from, to, source } actually searched",
                          "additionalProperties": true
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "ok": true,
                    "organizationId": "barber-bookings",
                    "fromMs": 1791547200000,
                    "toMs": 1791806400000,
                    "regexSearch": "checkout",
                    "count": 1,
                    "records": [
                      {
                        "EventTimestampMs": 1791806380000,
                        "Outcome": "ok",
                        "WallTimeMs": 128,
                        "CPUTimeMs": 14,
                        "Event": {
                          "Request": {
                            "URL": "/api/checkout",
                            "Method": "POST"
                          },
                          "Response": {
                            "Status": 500
                          }
                        },
                        "Logs": [
                          {
                            "Level": "error",
                            "Message": [
                              "checkout failed: missing price"
                            ],
                            "TimestampMs": 1791806380000
                          }
                        ],
                        "Exceptions": []
                      }
                    ],
                    "totalChars": 312,
                    "truncated": false
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/backend/dev/logs": {
      "get": {
        "operationId": "getDevServerLogs",
        "summary": "Get Dev Server Logs",
        "description": "The development preview's log of the last hour, as plain text ([time] message per line, oldest first).\n\nFull reference: https://www.totalum.app/docs/api/server#get-dev-server-logs",
        "tags": [
          "Logs & Preview Server"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Dev Server Logs — Totalum docs",
          "url": "https://www.totalum.app/docs/api/server#get-dev-server-logs"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "logs": {
                          "type": "string",
                          "description": "The lines, or a note when there are none yet"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "logs": "[2026-10-08T11:58:02.000Z] booking saved bk_1001\n[2026-10-08T11:58:03.000Z] e-mail sent to owner"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/agent/server/start-or-restart": {
      "post": {
        "operationId": "startOrRestartServer",
        "summary": "Start or Restart Server",
        "description": "Restart the project's development environment from its saved code, for example when the preview is stuck. On a project asleep after a long inactivity it wakes it instead (free): the preview answers again within seconds. You rarely need this — a prompt wakes a project by itself.\n\nFull reference: https://www.totalum.app/docs/api/server#start-or-restart-server",
        "tags": [
          "Logs & Preview Server"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "x-totalum-cost": "2 credits (free to wake a sleeping project)",
        "externalDocs": {
          "description": "Start or Restart Server — Totalum docs",
          "url": "https://www.totalum.app/docs/api/server#start-or-restart-server"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "\"Server is restarting\" or \"Project is reactivating\""
                        },
                        "status": {
                          "type": "string",
                          "description": "\"restarting\" or \"reactivating\""
                        },
                        "operationId": {
                          "type": "string",
                          "description": "The operation, visible in Get Project State"
                        },
                        "creditsCharged": {
                          "type": "number",
                          "description": "2 for a restart, 0 to wake"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "message": "Server is restarting",
                    "status": "restarting",
                    "operationId": "op_01k6xt",
                    "creditsCharged": 2
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "409": {
            "description": "`AGENT_RUNNING` — A prompt is running\n`OPERATION_IN_PROGRESS` — Another operation (publish, restore…) is running",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/usage": {
      "get": {
        "operationId": "getProjectUsage",
        "summary": "Get Project Usage",
        "description": "What one project's app used, per feature, in a date range.\n\nFull reference: https://www.totalum.app/docs/api/analytics#get-project-usage",
        "tags": [
          "Usage & Analytics"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          },
          {
            "name": "from",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "ISO 8601 start (2026-10-01T00:00:00Z)"
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "ISO 8601 end"
          },
          {
            "name": "groupBy",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "\"day\" (default) or \"month\""
          },
          {
            "name": "env",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "\"dev\", \"live\" or \"all\" (default)"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Project Usage — Totalum docs",
          "url": "https://www.totalum.app/docs/api/analytics#get-project-usage"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "range": {
                          "type": "object",
                          "description": "{ from, to } as asked",
                          "additionalProperties": true
                        },
                        "groupBy": {
                          "type": "string",
                          "description": "The bucket used"
                        },
                        "env": {
                          "type": "string",
                          "description": "dev, live or all"
                        },
                        "dimensions": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "One row per feature: { dimension, units, unit, credits, period } (a feature with no use has units: 0)"
                        },
                        "series": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "{ ts, integration, units, unit, credits } per bucket and feature"
                        },
                        "totals": {
                          "type": "object",
                          "description": "{ credits, byDimension } for the range",
                          "additionalProperties": true
                        },
                        "period": {
                          "type": "object",
                          "description": "{ from, to } the figures cover",
                          "additionalProperties": true
                        },
                        "refusals": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "Calls a feature limit refused: { feature, kind: \"limit\" | \"disabled\", cap, period, consumed, at, count }"
                        },
                        "infrastructure": {
                          "type": "object",
                          "description": "{ d1: { rowsRead, rowsWritten, storageBytes }, worker: { requests, cpuMs }, storage: { bytes } }",
                          "additionalProperties": true
                        },
                        "accrualPending": {
                          "type": "number",
                          "description": "Credits used but not settled yet"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "range": {
                      "from": "2026-10-01T00:00:00Z",
                      "to": "2026-10-08T00:00:00Z"
                    },
                    "groupBy": "day",
                    "env": "all",
                    "dimensions": [
                      {
                        "dimension": "email",
                        "units": 42,
                        "unit": "recipients",
                        "credits": 0.42,
                        "period": {
                          "from": "2026-10-01T00:00:00Z",
                          "to": "2026-10-08T00:00:00Z"
                        }
                      }
                    ],
                    "series": [
                      {
                        "ts": "2026-10-07T00:00:00Z",
                        "integration": "email",
                        "units": 12,
                        "unit": "recipients",
                        "credits": 0.12
                      }
                    ],
                    "totals": {
                      "credits": 0.61,
                      "byDimension": {
                        "email": {
                          "units": 42,
                          "unit": "recipients",
                          "credits": 0.42
                        }
                      }
                    },
                    "period": {
                      "from": "2026-10-01T00:00:00Z",
                      "to": "2026-10-08T00:00:00Z"
                    },
                    "refusals": [],
                    "infrastructure": {
                      "d1": {
                        "rowsRead": 30211,
                        "rowsWritten": 240,
                        "storageBytes": 2457600
                      },
                      "worker": {
                        "requests": 8120,
                        "cpuMs": 40210
                      },
                      "storage": {
                        "bytes": 1048576
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/usage": {
      "get": {
        "operationId": "getAccountUsage",
        "summary": "Get Account Usage",
        "description": "The same report for the whole account, with a per-project breakdown (100 projects a page).\n\nFull reference: https://www.totalum.app/docs/api/analytics#get-account-usage",
        "tags": [
          "Usage & Analytics"
        ],
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "ISO 8601 start"
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "ISO 8601 end"
          },
          {
            "name": "groupBy",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "\"day\" (default) or \"month\""
          },
          {
            "name": "env",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "\"dev\", \"live\" or \"all\" (default)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "nextCursor of the previous page"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Account Usage — Totalum docs",
          "url": "https://www.totalum.app/docs/api/analytics#get-account-usage"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "byProject": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "{ projectId, label, engineVersion, totals, period } for the projects of this page"
                        },
                        "account": {
                          "type": "object",
                          "description": "{ plan, balance, accountCaps: { hour, day }, consumedThisPeriod }: accountCaps are the account's spending caps in credits per hour and per 24 hours (0 when they are agreed per account)",
                          "additionalProperties": true
                        },
                        "nextCursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Next page of projects; null on the last"
                        },
                        "dimensions, data": {
                          "type": "object",
                          "properties": {
                            "series, data": {
                              "type": "object",
                              "properties": {
                                "totals, data": {
                                  "type": "object",
                                  "properties": {
                                    "period": {
                                      "description": "As in Get Project Usage, for this page's projects"
                                    }
                                  },
                                  "additionalProperties": true
                                }
                              },
                              "additionalProperties": true
                            }
                          },
                          "additionalProperties": true
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "byProject": [
                      {
                        "projectId": "barber-bookings",
                        "label": "Barber bookings",
                        "engineVersion": "v2",
                        "totals": {
                          "credits": 0.61
                        },
                        "period": {
                          "from": "2026-10-01T00:00:00Z",
                          "to": "2026-10-08T00:00:00Z"
                        }
                      }
                    ],
                    "account": {
                      "plan": "starter",
                      "balance": 412.5,
                      "accountCaps": {
                        "hour": 360,
                        "day": 900
                      },
                      "consumedThisPeriod": 31.2
                    },
                    "nextCursor": null,
                    "dimensions": [],
                    "series": [],
                    "totals": {
                      "credits": 0.61,
                      "byDimension": {}
                    },
                    "period": {
                      "from": "2026-10-01T00:00:00Z",
                      "to": "2026-10-08T00:00:00Z"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/analytics/site": {
      "get": {
        "operationId": "getSiteAnalytics",
        "summary": "Get Site Analytics",
        "description": "Visits of the published site (or the preview): a time series, or the top values of one dimension. Counts are sampled at high traffic; unique visitors are approximate.\n\nFull reference: https://www.totalum.app/docs/api/analytics#get-site-analytics",
        "tags": [
          "Usage & Analytics"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "ISO 8601 start"
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "ISO 8601 end"
          },
          {
            "name": "granularity",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "\"minute\", \"hour\" or \"day\""
          },
          {
            "name": "metric",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Up to 4, comma-separated: page_views, hits, uniques, errors, bytes, ttfb_p50, ttfb_p95"
          },
          {
            "name": "dimension",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Top values of: path, referrer, country, device, browser, os, status, hostname"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number"
            },
            "description": "1–100 top values"
          },
          {
            "name": "bots",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "\"exclude\" (default), \"include\" or \"only\""
          },
          {
            "name": "env",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "\"live\" (published and custom hosts) or \"dev\" (preview); both when omitted"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Site Analytics — Totalum docs",
          "url": "https://www.totalum.app/docs/api/analytics#get-site-analytics"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "series": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "Time series: { t, <metric>: number, … }"
                        },
                        "top": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "With dimension: { key, share, <metric>: number, … }"
                        },
                        "window": {
                          "type": "object",
                          "description": "{ from, to, granularity }",
                          "additionalProperties": true
                        },
                        "source": {
                          "type": "string",
                          "description": "\"wae\""
                        },
                        "approximate": {
                          "type": "object",
                          "description": "{ uniques: boolean }",
                          "additionalProperties": true
                        },
                        "cachedAt": {
                          "type": "string",
                          "description": "When the figures were computed"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "top": [
                      {
                        "key": "/",
                        "share": 0.62,
                        "page_views": 310
                      },
                      {
                        "key": "/book",
                        "share": 0.21,
                        "page_views": 105
                      }
                    ],
                    "window": {
                      "from": "2026-10-01T00:00:00.000Z",
                      "to": "2026-10-08T00:00:00.000Z",
                      "granularity": "day"
                    },
                    "source": "wae",
                    "approximate": {
                      "uniques": true
                    },
                    "cachedAt": "2026-10-08T12:00:00.000Z"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/credits/spending-analytics": {
      "get": {
        "operationId": "spendingAnalytics",
        "summary": "Spending Analytics",
        "description": "Credits spent per day, by category and usage type, for charts and reports (90 days at most). Note the path: it is not under /vcaas.\n\nFull reference: https://www.totalum.app/docs/api/analytics#spending-analytics",
        "tags": [
          "Usage & Analytics"
        ],
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Start date YYYY-MM-DD"
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "End date YYYY-MM-DD, at most 90 days after from"
          },
          {
            "name": "projectId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Only one project"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Spending Analytics — Totalum docs",
          "url": "https://www.totalum.app/docs/api/analytics#spending-analytics"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "daily": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "{ date, development, infrastructure, byType, recurrent, oneTime } per day"
                        },
                        "totals": {
                          "type": "object",
                          "description": "{ development, infrastructure, total, byType, recurrent, oneTime, unsplit, uncategorized }",
                          "additionalProperties": true
                        },
                        "projects": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Projects with spending in the range"
                        },
                        "byProject": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "{ projectId, total, development, infrastructure, recurrent, oneTime }"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "daily": [
                      {
                        "date": "2026-10-07",
                        "development": 7.9,
                        "infrastructure": 0.3,
                        "byType": {
                          "prompt": 7.4,
                          "deploy": 0.5,
                          "email": 0.1
                        },
                        "recurrent": 8.2,
                        "oneTime": 0
                      }
                    ],
                    "totals": {
                      "development": 7.9,
                      "infrastructure": 0.3,
                      "total": 8.2,
                      "byType": {
                        "prompt": 7.4,
                        "deploy": 0.5,
                        "email": 0.1
                      },
                      "recurrent": 8.2,
                      "oneTime": 0,
                      "unsplit": 0,
                      "uncategorized": 0
                    },
                    "projects": [
                      "barber-bookings"
                    ],
                    "byProject": [
                      {
                        "projectId": "barber-bookings",
                        "total": 8.2,
                        "development": 7.9,
                        "infrastructure": 0.3,
                        "recurrent": 8.2,
                        "oneTime": 0
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/credit-limits": {
      "get": {
        "operationId": "getCreditLimits",
        "summary": "Get Credit Limits",
        "description": "The project's monthly caps and what it spent this month (UTC), per category.\n\nFull reference: https://www.totalum.app/docs/api/limits#get-credit-limits",
        "tags": [
          "Spending & Rate Limits"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Credit Limits — Totalum docs",
          "url": "https://www.totalum.app/docs/api/limits#get-credit-limits"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "creditLimits": {
                          "type": "object",
                          "properties": {
                            "maxDevelopmentCreditsPerMonth": {
                              "type": [
                                "number",
                                "null"
                              ],
                              "description": "The development cap; null = no cap"
                            },
                            "maxInfrastructureCreditsPerMonth": {
                              "type": [
                                "number",
                                "null"
                              ],
                              "description": "The infrastructure cap; null = no cap"
                            }
                          },
                          "additionalProperties": true
                        },
                        "usedThisMonth": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "{ development, infrastructure } credits spent this month; null when it cannot be read right now",
                          "additionalProperties": true
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "creditLimits": {
                      "maxDevelopmentCreditsPerMonth": 5000,
                      "maxInfrastructureCreditsPerMonth": 300
                    },
                    "usedThisMonth": {
                      "development": 42.5,
                      "infrastructure": 3.1
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      },
      "patch": {
        "operationId": "updateCreditLimits",
        "summary": "Update Credit Limits",
        "description": "Set the project's monthly caps. null removes a cap. Defaults for a project created through the API: a development cap of 5,000 credits a month and an infrastructure cap of 300 credits a month. Both can also be set when the project is created (Launch Project, Create Project).\n\nFull reference: https://www.totalum.app/docs/api/limits#update-credit-limits",
        "tags": [
          "Spending & Rate Limits"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "maxDevelopmentCreditsPerMonth": {
                    "type": [
                      "number",
                      "null"
                    ],
                    "description": "Positive number, or null for no cap"
                  },
                  "maxInfrastructureCreditsPerMonth": {
                    "type": [
                      "number",
                      "null"
                    ],
                    "description": "Positive number, or null for no cap"
                  }
                },
                "additionalProperties": true
              },
              "example": {
                "maxDevelopmentCreditsPerMonth": 500,
                "maxInfrastructureCreditsPerMonth": null
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Update Credit Limits — Totalum docs",
          "url": "https://www.totalum.app/docs/api/limits#update-credit-limits"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "creditLimits": {
                          "type": "object",
                          "properties": {
                            "maxDevelopmentCreditsPerMonth": {
                              "type": [
                                "number",
                                "null"
                              ],
                              "description": "When sent: the new development cap"
                            },
                            "maxInfrastructureCreditsPerMonth": {
                              "type": [
                                "number",
                                "null"
                              ],
                              "description": "When sent: the new infrastructure cap"
                            }
                          },
                          "additionalProperties": true
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "creditLimits": {
                      "maxDevelopmentCreditsPerMonth": 500,
                      "maxInfrastructureCreditsPerMonth": null
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`MISSING_LIMIT_FIELDS` — Neither cap was sent\n`INVALID_CREDIT_LIMITS` — The body is not an object\n`INVALID_LIMIT` — A cap is not a positive number or null",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "`OWNER_ONLY` — Only the account owner can change the caps",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/credit-limits/at-limit": {
      "get": {
        "operationId": "listProjectsAtTheirLimit",
        "summary": "List Projects at Their Limit",
        "description": "The account's projects that reached a monthly credit limit this month (UTC), with their caps and spend — the list behind the platform's \"projects at their monthly limit\" notice. Raise one with Update Credit Limits.\n\nFull reference: https://www.totalum.app/docs/api/limits#list-projects-at-their-limit",
        "tags": [
          "Spending & Rate Limits"
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "List Projects at Their Limit — Totalum docs",
          "url": "https://www.totalum.app/docs/api/limits#list-projects-at-their-limit"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "projects": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "projectId": {
                                "type": "string",
                                "description": "The project id"
                              },
                              "label": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Its display name"
                              },
                              "createdVia": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "\"ui\" (the platform) or \"api\""
                              },
                              "creditLimits": {
                                "type": "object",
                                "description": "{ maxDevelopmentCreditsPerMonth, maxInfrastructureCreditsPerMonth }",
                                "additionalProperties": true
                              },
                              "usedThisMonth": {
                                "type": "object",
                                "description": "{ development, infrastructure } credits spent this month",
                                "additionalProperties": true
                              },
                              "atLimit": {
                                "type": "object",
                                "description": "{ development, infrastructure }: true for each limit reached",
                                "additionalProperties": true
                              }
                            },
                            "additionalProperties": true
                          },
                          "description": "The projects at a limit (empty when none)"
                        },
                        "resetsAt": {
                          "type": "string",
                          "description": "When the limits reset (the start of next month, UTC)"
                        },
                        "canEdit": {
                          "type": "boolean",
                          "description": "Whether this caller may raise them (the account owner)"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "projects": [
                      {
                        "projectId": "barber-bookings",
                        "label": "Barber bookings",
                        "createdVia": "api",
                        "creditLimits": {
                          "maxDevelopmentCreditsPerMonth": 5000,
                          "maxInfrastructureCreditsPerMonth": 300
                        },
                        "usedThisMonth": {
                          "development": 812.4,
                          "infrastructure": 300.2
                        },
                        "atLimit": {
                          "development": false,
                          "infrastructure": true
                        }
                      }
                    ],
                    "resetsAt": "2026-11-01T00:00:00.000Z",
                    "canEdit": true
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/limits": {
      "get": {
        "operationId": "getFeatureLimits",
        "summary": "Get Feature Limits",
        "description": "Every built-in feature of the app: whether it is on, its monthly budgets and what it used this month. Every feature is on by default, with no budget of its own.\n\nFull reference: https://www.totalum.app/docs/api/limits#get-feature-limits",
        "tags": [
          "Spending & Rate Limits"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Feature Limits — Totalum docs",
          "url": "https://www.totalum.app/docs/api/limits#get-feature-limits"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "plan": {
                          "type": "string",
                          "description": "The account's plan"
                        },
                        "features": {
                          "type": "object",
                          "description": "Feature → its entry",
                          "properties": {
                            "<feature>": {
                              "type": "object",
                              "properties": {
                                "enabled": {
                                  "type": "boolean",
                                  "description": "false = switched off"
                                },
                                "parent": {
                                  "type": "string",
                                  "description": "\"ai\" for ai_text, ai_image, ai_video (the parent's switch and budget also apply)"
                                },
                                "monthlyCreditCap": {
                                  "type": "number",
                                  "description": "Budget in credits, when set"
                                },
                                "monthlyUnitCap": {
                                  "type": "number",
                                  "description": "Budget in the feature's unit, when set"
                                },
                                "unit": {
                                  "type": "string",
                                  "description": "calls, recipients, pages, bytes, session_minutes, room_minutes, executions, builds, rows, requests or credits"
                                },
                                "consumed": {
                                  "type": "object",
                                  "description": "{ credits, units } this month",
                                  "additionalProperties": true
                                },
                                "period": {
                                  "type": "object",
                                  "description": "{ from, to }: the month",
                                  "additionalProperties": true
                                },
                                "planCeiling": {
                                  "type": "object",
                                  "description": "Highest budget your plan allows: { monthlyCreditCap, monthlyUnitCap } (null = none)",
                                  "additionalProperties": true
                                },
                                "source": {
                                  "type": "string",
                                  "description": "plan (default), user (you set it) or ceo (set by Totalum support)"
                                }
                              },
                              "additionalProperties": true
                            }
                          },
                          "additionalProperties": true
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "plan": "starter",
                    "features": {
                      "ai_video": {
                        "enabled": false,
                        "parent": "ai",
                        "unit": "calls",
                        "consumed": {
                          "credits": 0,
                          "units": 0
                        },
                        "period": {
                          "from": "2026-10-01T00:00:00.000Z",
                          "to": "2026-11-01T00:00:00.000Z"
                        },
                        "planCeiling": {
                          "monthlyCreditCap": null,
                          "monthlyUnitCap": 20
                        },
                        "source": "user"
                      },
                      "all": {
                        "enabled": true,
                        "monthlyCreditCap": 300,
                        "unit": "credits",
                        "consumed": {
                          "credits": 12.4,
                          "units": 0
                        },
                        "period": {
                          "from": "2026-10-01T00:00:00.000Z",
                          "to": "2026-11-01T00:00:00.000Z"
                        },
                        "planCeiling": {
                          "monthlyCreditCap": null,
                          "monthlyUnitCap": null
                        },
                        "source": "user"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      },
      "put": {
        "operationId": "setFeatureLimits",
        "summary": "Set Feature Limits",
        "description": "Switch features on or off and set monthly budgets. Send only the features you change; null removes a budget. Account owner only. Setting the budget of all also sets the project's infrastructure credit limit.\n\nFull reference: https://www.totalum.app/docs/api/limits#set-feature-limits",
        "tags": [
          "Spending & Rate Limits"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "features": {
                    "type": "object",
                    "description": "Feature → { enabled?, monthlyCreditCap?, monthlyUnitCap? }",
                    "additionalProperties": true
                  }
                },
                "required": [
                  "features"
                ],
                "additionalProperties": true
              },
              "example": {
                "features": {
                  "ai_video": {
                    "enabled": false
                  },
                  "ai": {
                    "monthlyCreditCap": 200
                  },
                  "all": {
                    "monthlyCreditCap": 500
                  }
                }
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Set Feature Limits — Totalum docs",
          "url": "https://www.totalum.app/docs/api/limits#set-feature-limits"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "plan": {
                          "type": "string",
                          "description": "The account's plan"
                        },
                        "features": {
                          "type": "object",
                          "description": "Every feature after the change, as in Get Feature Limits",
                          "additionalProperties": true
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "plan": "starter",
                    "features": {
                      "ai_video": {
                        "enabled": false,
                        "parent": "ai",
                        "unit": "calls",
                        "consumed": {
                          "credits": 0,
                          "units": 0
                        },
                        "period": {
                          "from": "2026-10-01T00:00:00.000Z",
                          "to": "2026-11-01T00:00:00.000Z"
                        },
                        "planCeiling": {
                          "monthlyCreditCap": null,
                          "monthlyUnitCap": 20
                        },
                        "source": "user"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`UNKNOWN_FEATURE` — Not a feature of the table above\n`INVALID_LIMIT` — A negative or non-integer budget, or a monthlyUnitCap on all\n`FEATURE_NOT_DISABLABLE` — database and worker cannot be switched off\n`LIMIT_ABOVE_PLAN_CEILING` — A budget above your plan's ceiling",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "`OWNER_ONLY` — Only the account owner can change budgets",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/rate-limit": {
      "get": {
        "operationId": "getRateLimit",
        "summary": "Get Rate Limit",
        "description": "How many requests per minute each visitor (IP) may send to the published site.\n\nFull reference: https://www.totalum.app/docs/api/limits#get-rate-limit",
        "tags": [
          "Spending & Rate Limits"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Rate Limit — Totalum docs",
          "url": "https://www.totalum.app/docs/api/limits#get-rate-limit"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "perIpPerMinute": {
                          "type": [
                            "number",
                            "null"
                          ],
                          "description": "Requests per minute per IP; null = off"
                        },
                        "allowlistCidrs": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "IP ranges that are never limited (up to 50)"
                        },
                        "verifiedBotsExempt": {
                          "type": "boolean",
                          "description": "Search engines and other verified bots are not limited"
                        },
                        "planDefault": {
                          "type": "number",
                          "description": "Your plan's default"
                        },
                        "planMax": {
                          "type": [
                            "number",
                            "null"
                          ],
                          "description": "The highest value your plan allows"
                        },
                        "canDisable": {
                          "type": "boolean",
                          "description": "Whether your plan may switch it off"
                        },
                        "source": {
                          "type": "string",
                          "description": "\"plan\" or \"user\""
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "perIpPerMinute": 5000,
                    "allowlistCidrs": [],
                    "verifiedBotsExempt": true,
                    "planDefault": 5000,
                    "planMax": 60000,
                    "canDisable": true,
                    "source": "plan"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      },
      "patch": {
        "operationId": "updateRateLimit",
        "summary": "Update Rate Limit",
        "description": "Change the per-visitor limit, the allowlist or the bot exemption. Send only what changes.\n\nFull reference: https://www.totalum.app/docs/api/limits#update-rate-limit",
        "tags": [
          "Spending & Rate Limits"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "perIpPerMinute": {
                    "type": [
                      "number",
                      "null"
                    ],
                    "description": "From 10 to 60,000 on paid plans (5,000 on the free plan, the default everywhere); null = off (paid plans only)"
                  },
                  "allowlistCidrs": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Up to 50 IP ranges (203.0.113.0/24)"
                  },
                  "verifiedBotsExempt": {
                    "type": "boolean",
                    "description": "Exempt verified bots"
                  }
                },
                "additionalProperties": true
              },
              "example": {
                "perIpPerMinute": 300
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Update Rate Limit — Totalum docs",
          "url": "https://www.totalum.app/docs/api/limits#update-rate-limit"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "description": "The setting after the change, as in Get Rate Limit",
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "perIpPerMinute": 300,
                    "allowlistCidrs": [],
                    "verifiedBotsExempt": true,
                    "planDefault": 5000,
                    "planMax": 60000,
                    "canDisable": true,
                    "source": "user"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`VALIDATION_ERROR` — A value is out of range\n`RATE_LIMIT_ABOVE_PLAN` — Above your plan's maximum (errorDetails.planMax)\n`INVALID_CIDR` — An allowlist entry is not an IPv4 or IPv6 range",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "`RATE_LIMIT_DISABLE_NOT_ALLOWED` — The free plan cannot switch the limit off",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/cron-jobs": {
      "get": {
        "operationId": "listCronJobs",
        "summary": "List Cron Jobs",
        "description": "The project's jobs, both environments.\n\nFull reference: https://www.totalum.app/docs/api/cron-jobs#list-cron-jobs",
        "tags": [
          "Scheduled Jobs"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "List Cron Jobs — Totalum docs",
          "url": "https://www.totalum.app/docs/api/cron-jobs#list-cron-jobs"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "items": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "description": "Job id"
                              },
                              "name": {
                                "type": "string",
                                "description": "Name"
                              },
                              "schedule": {
                                "type": [
                                  "string",
                                  "object"
                                ],
                                "description": "A 5-field cron expression, or { everyMinutes }",
                                "additionalProperties": true
                              },
                              "timezone": {
                                "type": "string",
                                "description": "IANA time zone of the schedule (absent = UTC)"
                              },
                              "request": {
                                "type": "object",
                                "description": "{ method, url, headers?, body?, timeoutMs? }",
                                "additionalProperties": true
                              },
                              "env": {
                                "type": "string",
                                "description": "\"dev\" or \"live\""
                              },
                              "enabled": {
                                "type": "boolean",
                                "description": "Switched on"
                              },
                              "status": {
                                "type": "string",
                                "description": "\"active\", \"paused\" or \"paused_failures\" (paused after too many failures)"
                              },
                              "nextRunAt": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Next run"
                              },
                              "lastRun": {
                                "type": "object",
                                "description": "{ at, status, latencyMs }; status is the HTTP status, or \"timeout\", \"error\", \"skipped\"",
                                "additionalProperties": true
                              },
                              "pauseAfterFailures": {
                                "type": [
                                  "number",
                                  "null"
                                ],
                                "description": "Failures in a row that pause it; null = never"
                              },
                              "description": {
                                "type": "string",
                                "description": "Description"
                              },
                              "createdAt": {
                                "type": "string",
                                "description": "ISO 8601"
                              }
                            },
                            "additionalProperties": true
                          },
                          "description": "The jobs"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "items": [
                      {
                        "id": "cj_01k6xv",
                        "name": "daily-report",
                        "schedule": "0 9 * * *",
                        "timezone": "Europe/Madrid",
                        "request": {
                          "method": "POST",
                          "url": "https://barber-bookings.totalum-project.com/api/cron/daily-report"
                        },
                        "env": "live",
                        "enabled": true,
                        "status": "active",
                        "nextRunAt": "2026-10-09T07:00:00.000Z",
                        "pauseAfterFailures": 3,
                        "createdAt": "2026-10-08T12:00:00.000Z"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      },
      "post": {
        "operationId": "createCronJob",
        "summary": "Create Cron Job",
        "description": "Create a job. The URL must be on the environment's own host: the preview address for dev, the published <projectId>.totalum-project.com for live (which needs a published project). Without env the job belongs to the environment of its URL: the preview address makes a dev job (so an unpublished project needs no env), any other address a live one.\n\nFull reference: https://www.totalum.app/docs/api/cron-jobs#create-cron-job",
        "tags": [
          "Scheduled Jobs"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "1–64 characters"
                  },
                  "schedule": {
                    "type": [
                      "string",
                      "object"
                    ],
                    "description": "A 5-field cron expression (\"*/15 * * * *\"), or { \"everyMinutes\": 30 }",
                    "additionalProperties": true
                  },
                  "request": {
                    "type": "object",
                    "description": "What to call",
                    "properties": {
                      "method": {
                        "type": "string",
                        "description": "\"GET\" or \"POST\""
                      },
                      "url": {
                        "type": "string",
                        "description": "https:// URL on the environment's host"
                      },
                      "headers": {
                        "type": "object",
                        "description": "Up to 10 headers; a value may be {{secret:NAME}} to send a project secret",
                        "additionalProperties": true
                      },
                      "body": {
                        "type": "string",
                        "description": "Up to 64 KB"
                      },
                      "timeoutMs": {
                        "type": "number",
                        "description": "Up to 30,000"
                      }
                    },
                    "required": [
                      "method",
                      "url"
                    ],
                    "additionalProperties": true
                  },
                  "env": {
                    "type": "string",
                    "description": "\"dev\" or \"live\" (default: the environment of request.url — \"dev\" for the preview address, else \"live\")"
                  },
                  "timezone": {
                    "type": "string",
                    "description": "IANA zone, e.g. \"Europe/Madrid\": \"0 9 * * *\" runs at 09:00 there all year. Default UTC"
                  },
                  "pauseAfterFailures": {
                    "type": [
                      "number",
                      "null"
                    ],
                    "description": "1–100 failures in a row pause the job (default 3); null or 0 = never pause"
                  },
                  "enabled": {
                    "type": "boolean",
                    "description": "Default true"
                  },
                  "description": {
                    "type": "string",
                    "description": "Free text"
                  }
                },
                "required": [
                  "name",
                  "schedule",
                  "request"
                ],
                "additionalProperties": true
              },
              "example": {
                "name": "daily-report",
                "env": "dev",
                "schedule": "0 9 * * *",
                "timezone": "Europe/Madrid",
                "request": {
                  "method": "POST",
                  "url": "https://barber-bookings-dev-temporal-link-preview-k3y9x2ab.totalum-project.com/api/cron/daily-report"
                }
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Create Cron Job — Totalum docs",
          "url": "https://www.totalum.app/docs/api/cron-jobs#create-cron-job"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "description": "The job, with the fields of items[] in List Cron Jobs",
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "id": "cj_01k6xw",
                    "name": "daily-report",
                    "schedule": "0 9 * * *",
                    "timezone": "Europe/Madrid",
                    "request": {
                      "method": "POST",
                      "url": "https://barber-bookings-dev-temporal-link-preview-k3y9x2ab.totalum-project.com/api/cron/daily-report"
                    },
                    "env": "dev",
                    "enabled": true,
                    "status": "active",
                    "nextRunAt": "2026-10-09T07:00:00.000Z",
                    "pauseAfterFailures": 3,
                    "createdAt": "2026-10-08T12:00:00.000Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`INVALID_SCHEDULE` — Invalid, or more frequent than your plan allows (errorDetails.minIntervalSeconds)\n`VALIDATION_ERROR` — A field is invalid (an unknown timezone, pauseAfterFailures out of range…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "`CRON_URL_NOT_ALLOWED` — The URL is not on the environment's host (errorDetails.allowedHost)\n`CRON_REQUIRES_PUBLISHED_PROJECT` — A live job on a project that is not published",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "`CRON_LIMIT_REACHED` — The environment already has your plan's number of jobs (errorDetails.limit)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/cron-jobs/{jobId}": {
      "get": {
        "operationId": "getCronJob",
        "summary": "Get Cron Job",
        "description": "One job.\n\nFull reference: https://www.totalum.app/docs/api/cron-jobs#get-cron-job",
        "tags": [
          "Scheduled Jobs"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          },
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The job id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Cron Job — Totalum docs",
          "url": "https://www.totalum.app/docs/api/cron-jobs#get-cron-job"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "description": "The job, as in List Cron Jobs",
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "id": "cj_01k6xw",
                    "name": "daily-report",
                    "schedule": "0 9 * * *",
                    "request": {
                      "method": "POST",
                      "url": "https://barber-bookings-dev-temporal-link-preview-k3y9x2ab.totalum-project.com/api/cron/daily-report"
                    },
                    "env": "dev",
                    "enabled": true,
                    "status": "active",
                    "nextRunAt": "2026-10-09T09:00:00.000Z",
                    "pauseAfterFailures": 3,
                    "createdAt": "2026-10-08T12:00:00.000Z"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "404": {
            "description": "`CRON_JOB_NOT_FOUND` — No such job",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateCronJob",
        "summary": "Update Cron Job",
        "description": "Change any field of a job, or switch it on or off (enabled). A paused job runs again once it is enabled.\n\nFull reference: https://www.totalum.app/docs/api/cron-jobs#update-cron-job",
        "tags": [
          "Scheduled Jobs"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          },
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The job id"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name, schedule, request, env, timezone, pauseAfterFailures, enabled, description": {
                    "description": "Any field of Create Cron Job"
                  }
                },
                "additionalProperties": true
              },
              "example": {
                "enabled": false
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Update Cron Job — Totalum docs",
          "url": "https://www.totalum.app/docs/api/cron-jobs#update-cron-job"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "description": "The job after the change",
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "id": "cj_01k6xw",
                    "name": "daily-report",
                    "schedule": "0 9 * * *",
                    "request": {
                      "method": "POST",
                      "url": "https://barber-bookings-dev-temporal-link-preview-k3y9x2ab.totalum-project.com/api/cron/daily-report"
                    },
                    "env": "dev",
                    "enabled": false,
                    "status": "paused",
                    "nextRunAt": null,
                    "pauseAfterFailures": 3,
                    "createdAt": "2026-10-08T12:00:00.000Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`INVALID_SCHEDULE` — Invalid or too frequent schedule",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "`CRON_URL_NOT_ALLOWED` — The URL is not on the environment's host",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "`CRON_JOB_NOT_FOUND` — No such job",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteCronJob",
        "summary": "Delete Cron Job",
        "description": "Delete a job.\n\nFull reference: https://www.totalum.app/docs/api/cron-jobs#delete-cron-job",
        "tags": [
          "Scheduled Jobs"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          },
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The job id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Delete Cron Job — Totalum docs",
          "url": "https://www.totalum.app/docs/api/cron-jobs#delete-cron-job"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "deleted": {
                          "type": "boolean",
                          "description": "true"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "deleted": true
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "404": {
            "description": "`CRON_JOB_NOT_FOUND` — No such job",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/cron-jobs/{jobId}/run": {
      "post": {
        "operationId": "runCronJob",
        "summary": "Run Cron Job",
        "description": "Run a job now, once. The run appears in its executions. At most 10 manual runs a minute per project.\n\nFull reference: https://www.totalum.app/docs/api/cron-jobs#run-cron-job",
        "tags": [
          "Scheduled Jobs"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          },
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The job id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Run Cron Job — Totalum docs",
          "url": "https://www.totalum.app/docs/api/cron-jobs#run-cron-job"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "runId": {
                          "type": "string",
                          "description": "The execution"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "runId": "cr_01k6xx"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "404": {
            "description": "`CRON_JOB_NOT_FOUND` — No such job",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "`RATE_LIMITED` — More than 10 manual runs in a minute; retry after errorDetails.retryAfterSeconds",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/cron-jobs/{jobId}/executions": {
      "get": {
        "operationId": "listCronJobExecutions",
        "summary": "List Cron Job Executions",
        "description": "A job's executions of the last 30 days, newest first.\n\nFull reference: https://www.totalum.app/docs/api/cron-jobs#list-cron-job-executions",
        "tags": [
          "Scheduled Jobs"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          },
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The job id"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number"
            },
            "description": "Page size"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "nextCursor of the previous page"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "List Cron Job Executions — Totalum docs",
          "url": "https://www.totalum.app/docs/api/cron-jobs#list-cron-job-executions"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "items": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "description": "Execution id"
                              },
                              "scheduledFor": {
                                "type": "string",
                                "description": "When it was due"
                              },
                              "startedAt": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "When it ran"
                              },
                              "status": {
                                "type": [
                                  "number",
                                  "string"
                                ],
                                "description": "HTTP status, or \"timeout\", \"error\", \"skipped\" (not run: no credits, or the cron feature is off or over budget)"
                              },
                              "latencyMs": {
                                "type": [
                                  "number",
                                  "null"
                                ],
                                "description": "Response time"
                              },
                              "error": {
                                "type": "string",
                                "description": "Why it failed or was skipped"
                              },
                              "responseSnippet": {
                                "type": "string",
                                "description": "The first 1 KB of the answer"
                              }
                            },
                            "additionalProperties": true
                          }
                        },
                        "nextCursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Next page"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "items": [
                      {
                        "id": "cr_01k6xx",
                        "scheduledFor": "2026-10-08T12:05:00.000Z",
                        "startedAt": "2026-10-08T12:05:00.000Z",
                        "status": 200,
                        "latencyMs": 142,
                        "responseSnippet": "{\"ok\":true}"
                      }
                    ],
                    "nextCursor": null
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "404": {
            "description": "`CRON_JOB_NOT_FOUND` — No such job",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/domain": {
      "put": {
        "operationId": "addCustomDomain",
        "summary": "Add Custom Domain",
        "description": "Connect a domain you own. Publish the project first. Then create the records in dnsRecordsToAdd at your DNS provider and poll Get Project until customDomain.status and customDomain.sslStatus are \"active\" (usually minutes, up to a few hours for DNS). Calling it again with another hostname replaces the domain.\n\nFull reference: https://www.totalum.app/docs/api/domains#add-custom-domain",
        "tags": [
          "Custom Domains"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "hostname": {
                    "type": "string",
                    "description": "app.example.com or example.com"
                  }
                },
                "required": [
                  "hostname"
                ],
                "additionalProperties": true
              },
              "example": {
                "hostname": "book.barbershop.com"
              }
            }
          }
        },
        "x-totalum-cost": "4 credits (first domain)",
        "externalDocs": {
          "description": "Add Custom Domain — Totalum docs",
          "url": "https://www.totalum.app/docs/api/domains#add-custom-domain"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "success": {
                          "type": "boolean",
                          "description": "true"
                        },
                        "hostname": {
                          "type": "string",
                          "description": "The hostname that will serve the site"
                        },
                        "status": {
                          "type": "string",
                          "description": "\"pending\" until the DNS records are found, then \"active\""
                        },
                        "dnsRecordsToAdd": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "Records to create: { type: \"CNAME\" | \"TXT\" | \"ALIAS\" | \"A\" | \"AAAA\", name, value }; name is the full host name. For a whole domain the bare domain's records come last: optional, they make it redirect to www. — either ALIAS + TXT, or A + AAAA + TXT _totalum-redirect.<domain> (Totalum's redirect service, records every DNS provider supports)"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "success": true,
                    "hostname": "book.barbershop.com",
                    "status": "pending",
                    "dnsRecordsToAdd": [
                      {
                        "type": "CNAME",
                        "name": "book.barbershop.com",
                        "value": "barber-bookings.totalum-project.com"
                      },
                      {
                        "type": "TXT",
                        "name": "_cf-custom-hostname.book.barbershop.com",
                        "value": "4f6a2c9e-…"
                      }
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "`MISSING_HOSTNAME` — hostname is missing\n`VALIDATION_ERROR` — Not a valid domain name, or a Totalum host",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "`INSUFFICIENT_CREDITS` — Not enough credits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "`PLATFORM_CAPABILITY_QUOTA_REACHED` — Custom domains are not included on your plan",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "`NO_DEPLOYMENT` — Publish the project first",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "`DOMAIN_ALREADY_ADDED` — This domain is already on the project\n`DOMAIN_IN_USE` — The domain is connected to another project\n`PROJECT_HAS_CUSTOM_DOMAIN` — The project uses a domain bought on Totalum; detach it first",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "getCustomDomain",
        "summary": "Get Custom Domain",
        "description": "The project's custom domain and the state of each of its addresses — the site and, for a whole domain, the bare domain that redirects to it. Statuses are checked again with Cloudflare while an address is still pending (at most once a minute), so poll this (or Get Project, whose customDomain carries the same fields) until every status and sslStatus is \"active\". New engine projects only. data is null when the project has no custom domain.\n\nFull reference: https://www.totalum.app/docs/api/domains#get-custom-domain",
        "tags": [
          "Custom Domains"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Custom Domain — Totalum docs",
          "url": "https://www.totalum.app/docs/api/domains#get-custom-domain"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "hostname": {
                          "type": "string",
                          "description": "Where the site answers"
                        },
                        "status": {
                          "type": "string",
                          "description": "That address: \"pending\" until its DNS records are found, then \"active\""
                        },
                        "sslStatus": {
                          "type": "string",
                          "description": "Its HTTPS certificate: \"active\" once issued"
                        },
                        "domain": {
                          "type": "string",
                          "description": "The domain (barbershop.io)"
                        },
                        "kind": {
                          "type": "string",
                          "description": "\"domain\" or \"subdomain\""
                        },
                        "canonicalHost": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "\"www\", \"app\", any label, or \"apex\"; null for a subdomain"
                        },
                        "source": {
                          "type": "string",
                          "description": "\"purchase\" (bought on Totalum: no DNS work) or \"manual\""
                        },
                        "accountDomainId": {
                          "type": "string",
                          "description": "The bought domain, when source is \"purchase\""
                        },
                        "hostnames": {
                          "type": "array",
                          "items": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "additionalProperties": true
                            },
                            "description": "Each address: { hostname, role, status, sslStatus, dnsRecordsToAdd, verificationErrors }; role is \"canonical\" (the site), \"alias\" (redirects to it with a 301, path and query kept) or \"sub\""
                          }
                        },
                        "dnsRecordsToAdd": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "Every record still to create, as in Add Custom Domain (empty for a bought domain: Totalum writes them)"
                        },
                        "redirects": {
                          "type": "object",
                          "description": "{ canonical, applyToDefaultHost, rules }",
                          "additionalProperties": true
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "hostname": "app.barbershop.io",
                    "status": "active",
                    "sslStatus": "active",
                    "domain": "barbershop.io",
                    "kind": "domain",
                    "canonicalHost": "app",
                    "source": "purchase",
                    "accountDomainId": "dom_01k6y3",
                    "hostnames": [
                      {
                        "hostname": "app.barbershop.io",
                        "role": "canonical",
                        "status": "active",
                        "sslStatus": "active",
                        "dnsRecordsToAdd": [],
                        "verificationErrors": []
                      },
                      {
                        "hostname": "barbershop.io",
                        "role": "alias",
                        "status": "active",
                        "sslStatus": "active",
                        "dnsRecordsToAdd": [],
                        "verificationErrors": []
                      }
                    ],
                    "dnsRecordsToAdd": [],
                    "redirects": {
                      "canonical": "app.barbershop.io",
                      "applyToDefaultHost": false,
                      "rules": []
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      },
      "delete": {
        "operationId": "removeCustomDomain",
        "summary": "Remove Custom Domain",
        "description": "Disconnect the custom domain. The site keeps answering at <projectId>.totalum-project.com. Your DNS records are not touched. A domain bought on Totalum is detached the same way: it stays yours and is not refunded, and it keeps renewing until you switch autoRenew off (Detach Domain).\n\nFull reference: https://www.totalum.app/docs/api/domains#remove-custom-domain",
        "tags": [
          "Custom Domains"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Remove Custom Domain — Totalum docs",
          "url": "https://www.totalum.app/docs/api/domains#remove-custom-domain"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "success": {
                          "type": "boolean",
                          "description": "true"
                        },
                        "hostname": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "The domain removed"
                        },
                        "message": {
                          "type": "string",
                          "description": "\"Custom domain removed\""
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "success": true,
                    "hostname": "book.barbershop.com",
                    "message": "Custom domain removed"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/domains/search": {
      "get": {
        "operationId": "searchDomains",
        "summary": "Search Domains",
        "description": "Which names are available, and their price.\n\nFull reference: https://www.totalum.app/docs/api/domain-registration#search-domains",
        "tags": [
          "Buy a Domain"
        ],
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "A name (barbershop) or a full domain (barbershop.com)"
          },
          {
            "name": "tlds",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated extensions to check (com,io); default: every extension sold"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Search Domains — Totalum docs",
          "url": "https://www.totalum.app/docs/api/domain-registration#search-domains"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "results": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "domain": {
                                "type": "string",
                                "description": "The domain"
                              },
                              "available": {
                                "type": "boolean",
                                "description": "Can be bought now"
                              },
                              "premium": {
                                "type": "boolean",
                                "description": "Always false (premium names are not offered)"
                              },
                              "price": {
                                "type": "number",
                                "description": "First-year price"
                              },
                              "renewalPrice": {
                                "type": "number",
                                "description": "Yearly renewal price. It can be much higher than price (a registry's first-year promotion), so show both: \"€3.59 first year, then €91.19/year\""
                              },
                              "currency": {
                                "type": "string",
                                "description": "eur or usd"
                              }
                            },
                            "additionalProperties": true
                          }
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "results": [
                      {
                        "domain": "barbershop.io",
                        "available": true,
                        "premium": false,
                        "price": 52.8,
                        "renewalPrice": 52.8,
                        "currency": "eur"
                      },
                      {
                        "domain": "barbershop.com",
                        "available": false,
                        "premium": false,
                        "price": 0,
                        "renewalPrice": 0,
                        "currency": "eur"
                      }
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "`VALIDATION_ERROR` — q is missing",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/domains/tlds": {
      "get": {
        "operationId": "listTlds",
        "summary": "List TLDs",
        "description": "The extensions sold and their prices.\n\nFull reference: https://www.totalum.app/docs/api/domain-registration#list-tlds",
        "tags": [
          "Buy a Domain"
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "List TLDs — Totalum docs",
          "url": "https://www.totalum.app/docs/api/domain-registration#list-tlds"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "tlds": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "tld": {
                                "type": "string",
                                "description": "Extension (com)"
                              },
                              "price": {
                                "type": "number",
                                "description": "First-year price"
                              },
                              "renewalPrice": {
                                "type": "number",
                                "description": "Yearly renewal"
                              },
                              "currency": {
                                "type": "string",
                                "description": "eur or usd"
                              },
                              "requirements": {
                                "type": "boolean",
                                "description": "The registry asks for extra registrant data"
                              }
                            },
                            "additionalProperties": true
                          }
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "tlds": [
                      {
                        "tld": "com",
                        "price": 14.4,
                        "renewalPrice": 14.4,
                        "currency": "usd",
                        "requirements": false
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/domains/purchase": {
      "post": {
        "operationId": "buyDomain",
        "summary": "Buy Domain",
        "description": "Charge the saved card and register the domain. If the registration fails, the payment is refunded at once. Send an Idempotency-Key header so a retried request never buys twice (a retry of a domain you already hold returns it without a new charge). With projectId, the domain is attached to that project in the same call.\n\nFull reference: https://www.totalum.app/docs/api/domain-registration#buy-domain",
        "tags": [
          "Buy a Domain"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "domain": {
                    "type": "string",
                    "description": "The domain to buy"
                  },
                  "contactId": {
                    "type": "string",
                    "description": "The registrant contact"
                  },
                  "years": {
                    "type": "number",
                    "description": "Always 1: a domain is bought for one year, then renews every year. Any other value is refused (400 VALIDATION_ERROR)"
                  },
                  "projectId": {
                    "type": "string",
                    "description": "Attach to this project after the purchase"
                  },
                  "canonicalHost": {
                    "type": "string",
                    "description": "Where the site answers: \"www\" (default), \"app\" or any DNS label (letters, digits, inner hyphens) — the site is served at <label>.<domain> and the bare domain redirects there (301, path and query kept) — or \"apex\" (the bare domain itself). Refused with 400 VALIDATION_ERROR before any charge when it is not a valid label"
                  },
                  "expectedPrice": {
                    "type": "number",
                    "description": "The price you showed: if the live price differs, nothing is bought (409 PRICE_CHANGED)"
                  }
                },
                "required": [
                  "domain",
                  "contactId"
                ],
                "additionalProperties": true
              },
              "example": {
                "domain": "barbershop.io",
                "contactId": "ct_01k6y2",
                "projectId": "barber-bookings",
                "expectedPrice": 52.8
              }
            }
          }
        },
        "x-totalum-cost": "Card payment (not credits)",
        "externalDocs": {
          "description": "Buy Domain — Totalum docs",
          "url": "https://www.totalum.app/docs/api/domain-registration#buy-domain"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "domain": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string",
                              "description": "Domain id"
                            },
                            "domain": {
                              "type": "string",
                              "description": "The domain"
                            },
                            "status": {
                              "type": "string",
                              "description": "\"active\""
                            },
                            "registeredAt": {
                              "type": "string",
                              "description": "ISO 8601"
                            },
                            "expiresAt": {
                              "type": "string",
                              "description": "ISO 8601"
                            },
                            "autoRenew": {
                              "type": "boolean",
                              "description": "true"
                            },
                            "pricePaid": {
                              "type": "number",
                              "description": "What was charged"
                            },
                            "renewalPriceEstimate": {
                              "type": "number",
                              "description": "The expected yearly renewal"
                            },
                            "attachedProjectId": {
                              "type": "string",
                              "description": "The project it serves"
                            },
                            "contactVerificationPending": {
                              "type": "boolean",
                              "description": "The registrant still has to verify their e-mail"
                            }
                          },
                          "additionalProperties": true
                        },
                        "warnings": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "{ code } — e.g. the attach did not happen (attach it with Attach Domain)"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "domain": {
                      "id": "dom_01k6y3",
                      "domain": "barbershop.io",
                      "status": "active",
                      "registeredAt": "2026-10-08T12:30:00.000Z",
                      "expiresAt": "2027-10-08T12:30:00.000Z",
                      "autoRenew": true,
                      "pricePaid": 52.8,
                      "renewalPriceEstimate": 52.8,
                      "attachedProjectId": "barber-bookings",
                      "contactVerificationPending": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`VALIDATION_ERROR` — domain or contactId is missing\n`TLD_NOT_ALLOWED` — The extension is not sold\n`DOMAIN_PREMIUM_NOT_ALLOWED` — Premium names are not sold",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "`NO_PAYMENT_METHOD` — Add a card to your Totalum account first\n`PAYMENT_FAILED` — The card was declined (errorDetails.declineCode)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "`FEATURE_DISABLED` — Buying domains is not available yet on your account\n`PLAN_REQUIRED` — Needs the Starter plan or above\n`DOMAIN_LIMIT_REACHED` — Your plan's number of domains is reached\n`OWNER_ONLY` — Only the account owner can buy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "`DOMAIN_UNAVAILABLE` — The domain is taken\n`PRICE_CHANGED` — The price differs from expectedPrice (errorDetails.newPrice)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "422": {
            "description": "`DOMAIN_CONTACT_REQUIRED` — Create the registrant contact first\n`REGISTRATION_FAILED` — The registration was refused; the payment was refunded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "`RATE_LIMIT_EXCEEDED` — More than 5 purchases today",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/domains": {
      "get": {
        "operationId": "listDomains",
        "summary": "List Domains",
        "description": "The account's domains.\n\nFull reference: https://www.totalum.app/docs/api/domain-registration#list-domains",
        "tags": [
          "Buy a Domain"
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "List Domains — Totalum docs",
          "url": "https://www.totalum.app/docs/api/domain-registration#list-domains"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "domains": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "Domains, with the fields of Get Domain"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "domains": [
                      {
                        "id": "dom_01k6y3",
                        "domain": "barbershop.io",
                        "status": "active",
                        "registeredAt": "2026-10-08T12:30:00.000Z",
                        "expiresAt": "2027-10-08T12:30:00.000Z",
                        "autoRenew": true,
                        "renewal": {
                          "status": "scheduled",
                          "nextChargeAt": "2027-09-08T12:30:00.000Z",
                          "attempts": []
                        },
                        "pricing": {
                          "pricePaid": 52.8,
                          "currency": "eur",
                          "renewalPriceEstimate": 52.8
                        },
                        "privacy": true,
                        "locked": true,
                        "contactId": "ct_01k6y2",
                        "contactVerified": false,
                        "nameservers": [
                          "ns1.totalum-dns.com"
                        ],
                        "dnsManaged": true,
                        "attachedProjectId": "barber-bookings",
                        "canonicalHost": "www",
                        "exportAvailableAt": "2026-12-07T12:30:00.000Z",
                        "verification": {
                          "contactVerificationPending": true,
                          "verifyBy": "2026-10-23T12:30:00.000Z"
                        }
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/domains/{domainId}": {
      "get": {
        "operationId": "getDomain",
        "summary": "Get Domain",
        "description": "One domain.\n\nFull reference: https://www.totalum.app/docs/api/domain-registration#get-domain",
        "tags": [
          "Buy a Domain"
        ],
        "parameters": [
          {
            "name": "domainId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The domain id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Domain — Totalum docs",
          "url": "https://www.totalum.app/docs/api/domain-registration#get-domain"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "Domain id"
                        },
                        "domain": {
                          "type": "string",
                          "description": "The domain"
                        },
                        "status": {
                          "type": "string",
                          "description": "\"active\", \"expired_grace\", \"expired\", \"export_pending\", \"transferred_out\", \"external_dns\" or \"suspended_verification\""
                        },
                        "registeredAt": {
                          "type": "string",
                          "description": "ISO 8601"
                        },
                        "expiresAt": {
                          "type": "string",
                          "description": "ISO 8601"
                        },
                        "autoRenew": {
                          "type": "boolean",
                          "description": "Renews automatically"
                        },
                        "renewal": {
                          "type": "object",
                          "description": "{ status: \"scheduled\" | \"charging\" | \"renewed\" | \"cancelled\", nextChargeAt, attempts[], lastRenewedAt?, cancelledAt? }",
                          "additionalProperties": true
                        },
                        "pricing": {
                          "type": "object",
                          "description": "{ pricePaid, currency, renewalPriceEstimate }",
                          "additionalProperties": true
                        },
                        "privacy": {
                          "type": "boolean",
                          "description": "WHOIS privacy"
                        },
                        "locked": {
                          "type": "boolean",
                          "description": "Transfer lock"
                        },
                        "contactId": {
                          "type": "string",
                          "description": "Registrant contact"
                        },
                        "contactVerified": {
                          "type": "boolean",
                          "description": "Registrant e-mail verified"
                        },
                        "nameservers": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Nameservers"
                        },
                        "dnsManaged": {
                          "type": "boolean",
                          "description": "DNS is managed on Totalum"
                        },
                        "attachedProjectId": {
                          "type": "string",
                          "description": "The project it serves"
                        },
                        "canonicalHost": {
                          "type": "string",
                          "description": "\"www\" or \"apex\""
                        },
                        "exportAvailableAt": {
                          "type": "string",
                          "description": "From when it can be transferred away (60 days after registration)"
                        },
                        "verification": {
                          "type": "object",
                          "description": "{ contactVerificationPending, verifyBy }",
                          "additionalProperties": true
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "id": "dom_01k6y3",
                    "domain": "barbershop.io",
                    "status": "active",
                    "registeredAt": "2026-10-08T12:30:00.000Z",
                    "expiresAt": "2027-10-08T12:30:00.000Z",
                    "autoRenew": true,
                    "renewal": {
                      "status": "scheduled",
                      "nextChargeAt": "2027-09-08T12:30:00.000Z",
                      "attempts": []
                    },
                    "pricing": {
                      "pricePaid": 52.8,
                      "currency": "eur",
                      "renewalPriceEstimate": 52.8
                    },
                    "privacy": true,
                    "locked": true,
                    "contactId": "ct_01k6y2",
                    "contactVerified": true,
                    "nameservers": [
                      "ns1.totalum-dns.com"
                    ],
                    "dnsManaged": true,
                    "attachedProjectId": "barber-bookings",
                    "canonicalHost": "www",
                    "exportAvailableAt": "2026-12-07T12:30:00.000Z",
                    "verification": {
                      "contactVerificationPending": false,
                      "verifyBy": null
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "404": {
            "description": "`DOMAIN_NOT_FOUND` — No such domain in your account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateDomain",
        "summary": "Update Domain",
        "description": "Turn WHOIS privacy or automatic renewal on or off. Owner only.\n\nFull reference: https://www.totalum.app/docs/api/domain-registration#update-domain",
        "tags": [
          "Buy a Domain"
        ],
        "parameters": [
          {
            "name": "domainId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The domain id"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "privacy": {
                    "type": "boolean",
                    "description": "WHOIS privacy"
                  },
                  "autoRenew": {
                    "type": "boolean",
                    "description": "Automatic yearly renewal"
                  }
                },
                "additionalProperties": true
              },
              "example": {
                "autoRenew": false
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Update Domain — Totalum docs",
          "url": "https://www.totalum.app/docs/api/domain-registration#update-domain"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "description": "The domain after the change, as in Get Domain",
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "id": "dom_01k6y3",
                    "domain": "barbershop.io",
                    "status": "active",
                    "autoRenew": false,
                    "renewal": {
                      "status": "cancelled",
                      "nextChargeAt": null,
                      "attempts": []
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/domains/{domainId}/renew": {
      "post": {
        "operationId": "renewDomain",
        "summary": "Renew Domain",
        "description": "Renew now for one year (within 90 days of expiry, or during the grace period after it). Owner only.\n\nFull reference: https://www.totalum.app/docs/api/domain-registration#renew-domain",
        "tags": [
          "Buy a Domain"
        ],
        "parameters": [
          {
            "name": "domainId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The domain id"
          }
        ],
        "x-totalum-cost": "Card payment",
        "externalDocs": {
          "description": "Renew Domain — Totalum docs",
          "url": "https://www.totalum.app/docs/api/domain-registration#renew-domain"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "domain": {
                          "type": "object",
                          "description": "The domain after the renewal",
                          "additionalProperties": true
                        },
                        "order": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "The renewal order",
                          "additionalProperties": true
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "domain": {
                      "id": "dom_01k6y3",
                      "domain": "barbershop.io",
                      "status": "active",
                      "expiresAt": "2028-10-08T12:30:00.000Z"
                    },
                    "order": {
                      "kind": "renewal",
                      "status": "completed",
                      "customerPrice": 52.8,
                      "currency": "eur"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "`PAYMENT_FAILED` — The card was declined",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "409": {
            "description": "`DOMAIN_NOT_RENEWABLE` — Not within 90 days of expiry (errorDetails.expiresAt)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "422": {
            "description": "`REGISTRATION_FAILED` — The renewal was refused; the payment was refunded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/domains/{domainId}/attach": {
      "post": {
        "operationId": "attachDomain",
        "summary": "Attach Domain",
        "description": "Serve a project from this domain; Totalum writes the DNS records itself (and the ones that prove ownership of each address). The project must be published. The site answers at <canonicalHost>.<domain> and the bare domain redirects there (301, path and query kept); follow both addresses with Get Custom Domain.\n\nFull reference: https://www.totalum.app/docs/api/domain-registration#attach-domain",
        "tags": [
          "Buy a Domain"
        ],
        "parameters": [
          {
            "name": "domainId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The domain id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "projectId": {
                    "type": "string",
                    "description": "The project"
                  },
                  "canonicalHost": {
                    "type": "string",
                    "description": "\"www\" (default), \"app\" or any DNS label, or \"apex\" — as in Buy Domain"
                  }
                },
                "required": [
                  "projectId"
                ],
                "additionalProperties": true
              },
              "example": {
                "projectId": "barber-bookings"
              }
            }
          }
        },
        "x-totalum-cost": "4 credits (first domain of the project)",
        "externalDocs": {
          "description": "Attach Domain — Totalum docs",
          "url": "https://www.totalum.app/docs/api/domain-registration#attach-domain"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "domain": {
                          "type": "object",
                          "description": "The domain, as in Get Domain",
                          "additionalProperties": true
                        },
                        "customDomain": {
                          "type": "object",
                          "description": "The project's custom domain: { domain, hostnames, status, … }",
                          "additionalProperties": true
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "domain": {
                      "id": "dom_01k6y3",
                      "domain": "barbershop.io",
                      "attachedProjectId": "barber-bookings",
                      "canonicalHost": "www"
                    },
                    "customDomain": {
                      "domain": "barbershop.io",
                      "status": "pending"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`VALIDATION_ERROR` — projectId is missing, or canonicalHost is not \"apex\" or one DNS label",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "`INSUFFICIENT_CREDITS` — Not enough credits for the domain fee",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "`PLATFORM_CAPABILITY_QUOTA_REACHED` — Custom domains are not included on your plan",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "`PROJECT_NOT_FOUND` — No such project in your account\n`NO_DEPLOYMENT` — Publish the project first",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "`DOMAIN_ALREADY_ATTACHED` — Attached to another project; detach it first",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/domains/{domainId}/detach": {
      "post": {
        "operationId": "detachDomain",
        "summary": "Detach Domain",
        "description": "Stop serving the project from this domain. The domain stays yours and is not refunded. Its automatic renewal keeps running unless you stop it: to remove the domain for good, detach it and then Update Domain with {\"autoRenew\":false} — it stays registered to you until expiresAt, then expires. Afterwards the project can attach another domain you bought, buy one with projectId, or connect one you own.\n\nFull reference: https://www.totalum.app/docs/api/domain-registration#detach-domain",
        "tags": [
          "Buy a Domain"
        ],
        "parameters": [
          {
            "name": "domainId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The domain id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Detach Domain — Totalum docs",
          "url": "https://www.totalum.app/docs/api/domain-registration#detach-domain"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "description": "The domain, as in Get Domain",
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "id": "dom_01k6y3",
                    "domain": "barbershop.io",
                    "status": "active"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/domains/{domainId}/dns/records": {
      "get": {
        "operationId": "listDnsRecords",
        "summary": "List DNS Records",
        "description": "The domain's DNS records. managed: true records serve the attached project and cannot be changed.\n\nFull reference: https://www.totalum.app/docs/api/domain-registration#list-dns-records",
        "tags": [
          "Buy a Domain"
        ],
        "parameters": [
          {
            "name": "domainId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The domain id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "List DNS Records — Totalum docs",
          "url": "https://www.totalum.app/docs/api/domain-registration#list-dns-records"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "records": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "description": "Record id"
                              },
                              "type": {
                                "type": "string",
                                "description": "A, AAAA, CNAME, ALIAS, MX, TXT, SRV or NS"
                              },
                              "host": {
                                "type": "string",
                                "description": "Host (\"\" = the domain itself)"
                              },
                              "answer": {
                                "type": "string",
                                "description": "Value"
                              },
                              "ttl": {
                                "type": "number",
                                "description": "Seconds (≥ 300)"
                              },
                              "priority": {
                                "type": "number",
                                "description": "MX/SRV priority"
                              },
                              "managed": {
                                "type": "boolean",
                                "description": "Written by Totalum for the attached project"
                              }
                            },
                            "additionalProperties": true
                          }
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "records": [
                      {
                        "id": "rec_1",
                        "type": "MX",
                        "host": "",
                        "answer": "mx.mailprovider.com",
                        "ttl": 300,
                        "priority": 10,
                        "managed": false
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      },
      "post": {
        "operationId": "createDnsRecord",
        "summary": "Create DNS Record",
        "description": "Add a record (for example your e-mail provider's MX and TXT records).\n\nFull reference: https://www.totalum.app/docs/api/domain-registration#create-dns-record",
        "tags": [
          "Buy a Domain"
        ],
        "parameters": [
          {
            "name": "domainId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The domain id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "record": {
                    "type": "object",
                    "description": "{ type, host, answer, ttl, priority? } as in List DNS Records",
                    "additionalProperties": true
                  }
                },
                "required": [
                  "record"
                ],
                "additionalProperties": true
              },
              "example": {
                "record": {
                  "type": "TXT",
                  "host": "",
                  "answer": "v=spf1 include:_spf.mailprovider.com ~all",
                  "ttl": 300
                }
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Create DNS Record — Totalum docs",
          "url": "https://www.totalum.app/docs/api/domain-registration#create-dns-record"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "description": "The record, with id and managed: false",
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "id": "rec_2",
                    "type": "TXT",
                    "host": "",
                    "answer": "v=spf1 include:_spf.mailprovider.com ~all",
                    "ttl": 300,
                    "managed": false
                  }
                }
              }
            }
          },
          "400": {
            "description": "`DNS_RECORD_CONFLICT` — Conflicts with an existing record\n`DNS_RECORD_LIMIT` — The domain already has 200 records\n`VALIDATION_ERROR` — Invalid record",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/domains/{domainId}/dns/records/{recordId}": {
      "patch": {
        "operationId": "updateDnsRecord",
        "summary": "Update DNS Record",
        "description": "Change a record you created.\n\nFull reference: https://www.totalum.app/docs/api/domain-registration#update-dns-record",
        "tags": [
          "Buy a Domain"
        ],
        "parameters": [
          {
            "name": "domainId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The domain id"
          },
          {
            "name": "recordId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The record id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "record": {
                    "type": "object",
                    "description": "{ type, host, answer, ttl, priority? }",
                    "additionalProperties": true
                  }
                },
                "required": [
                  "record"
                ],
                "additionalProperties": true
              },
              "example": {
                "record": {
                  "type": "MX",
                  "host": "",
                  "answer": "mx2.mailprovider.com",
                  "ttl": 300,
                  "priority": 20
                }
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Update DNS Record — Totalum docs",
          "url": "https://www.totalum.app/docs/api/domain-registration#update-dns-record"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "description": "The record after the change",
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "id": "rec_1",
                    "type": "MX",
                    "host": "",
                    "answer": "mx2.mailprovider.com",
                    "ttl": 300,
                    "priority": 20,
                    "managed": false
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "404": {
            "description": "`DOMAIN_NOT_FOUND` — No such record",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "`DNS_RECORD_MANAGED` — The record serves the attached project; detach the domain first",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteDnsRecord",
        "summary": "Delete DNS Record",
        "description": "Delete a record you created.\n\nFull reference: https://www.totalum.app/docs/api/domain-registration#delete-dns-record",
        "tags": [
          "Buy a Domain"
        ],
        "parameters": [
          {
            "name": "domainId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The domain id"
          },
          {
            "name": "recordId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The record id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Delete DNS Record — Totalum docs",
          "url": "https://www.totalum.app/docs/api/domain-registration#delete-dns-record"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "deleted": {
                          "type": "boolean",
                          "description": "true"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "deleted": true
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "404": {
            "description": "`DOMAIN_NOT_FOUND` — No such record",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "`DNS_RECORD_MANAGED` — The record serves the attached project",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/domains/{domainId}/forwarding": {
      "get": {
        "operationId": "getForwarding",
        "summary": "Get Forwarding",
        "description": "The domain's URL forwarding rules (a host of the domain redirecting to another URL).\n\nFull reference: https://www.totalum.app/docs/api/domain-registration#get-forwarding",
        "tags": [
          "Buy a Domain"
        ],
        "parameters": [
          {
            "name": "domainId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The domain id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Forwarding — Totalum docs",
          "url": "https://www.totalum.app/docs/api/domain-registration#get-forwarding"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "forwarding": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "host": {
                                "type": "string",
                                "description": "Host of the domain (shop.barbershop.io)"
                              },
                              "forwardsTo": {
                                "type": "string",
                                "description": "Target URL"
                              },
                              "type": {
                                "type": "string",
                                "description": "\"redirect\" (301), \"302\" or \"masked\""
                              }
                            },
                            "additionalProperties": true
                          }
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "forwarding": [
                      {
                        "host": "shop.barbershop.io",
                        "forwardsTo": "https://store.example.com",
                        "type": "redirect"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      },
      "put": {
        "operationId": "setForwarding",
        "summary": "Set Forwarding",
        "description": "Replace the whole set of forwarding rules (up to 50). A host the attached project serves is refused.\n\nFull reference: https://www.totalum.app/docs/api/domain-registration#set-forwarding",
        "tags": [
          "Buy a Domain"
        ],
        "parameters": [
          {
            "name": "domainId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The domain id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "forwarding": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "description": "{ host, forwardsTo, type }; [] removes every rule"
                  }
                },
                "required": [
                  "forwarding"
                ],
                "additionalProperties": true
              },
              "example": {
                "forwarding": [
                  {
                    "host": "shop.barbershop.io",
                    "forwardsTo": "https://store.example.com",
                    "type": "redirect"
                  }
                ]
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Set Forwarding — Totalum docs",
          "url": "https://www.totalum.app/docs/api/domain-registration#set-forwarding"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "forwarding": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "The rules now in place"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "forwarding": [
                      {
                        "host": "shop.barbershop.io",
                        "forwardsTo": "https://store.example.com",
                        "type": "redirect"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/domains/{domainId}/export": {
      "post": {
        "operationId": "getTransferCode",
        "summary": "Get Transfer Code",
        "description": "Unlock the domain and get its transfer (auth) code, to move it to another registrar. Also e-mailed to the owner. Possible 60 days after registration. Owner only.\n\nFull reference: https://www.totalum.app/docs/api/domain-registration#get-transfer-code",
        "tags": [
          "Buy a Domain"
        ],
        "parameters": [
          {
            "name": "domainId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The domain id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Transfer Code — Totalum docs",
          "url": "https://www.totalum.app/docs/api/domain-registration#get-transfer-code"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "authCode": {
                          "type": "string",
                          "description": "The transfer code"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "authCode": "Xk7#pQ2!mZ9w"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "409": {
            "description": "`DOMAIN_NOT_RENEWABLE` — A renewal charge is in progress; retry shortly",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "423": {
            "description": "`DOMAIN_TRANSFER_LOCKED` — Still inside the 60-day lock (errorDetails.availableAt)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/domains/{domainId}/export/cancel": {
      "post": {
        "operationId": "cancelTransfer",
        "summary": "Cancel Transfer",
        "description": "Lock the domain again and cancel a pending transfer. Owner only.\n\nFull reference: https://www.totalum.app/docs/api/domain-registration#cancel-transfer",
        "tags": [
          "Buy a Domain"
        ],
        "parameters": [
          {
            "name": "domainId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The domain id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Cancel Transfer — Totalum docs",
          "url": "https://www.totalum.app/docs/api/domain-registration#cancel-transfer"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "description": "The domain, as in Get Domain",
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "id": "dom_01k6y3",
                    "domain": "barbershop.io",
                    "status": "active",
                    "locked": true
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/domains/{domainId}/orders": {
      "get": {
        "operationId": "listDomainOrders",
        "summary": "List Domain Orders",
        "description": "The domain's payments: registration, renewals and refunds.\n\nFull reference: https://www.totalum.app/docs/api/domain-registration#list-domain-orders",
        "tags": [
          "Buy a Domain"
        ],
        "parameters": [
          {
            "name": "domainId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The domain id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "List Domain Orders — Totalum docs",
          "url": "https://www.totalum.app/docs/api/domain-registration#list-domain-orders"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "kind": {
                            "type": "string",
                            "description": "\"registration\", \"renewal\" or \"refund\""
                          },
                          "status": {
                            "type": "string",
                            "description": "Order status"
                          },
                          "customerPrice": {
                            "type": "number",
                            "description": "Amount"
                          },
                          "currency": {
                            "type": "string",
                            "description": "eur or usd"
                          },
                          "at": {
                            "type": "string",
                            "description": "ISO 8601"
                          },
                          "stripePaymentIntentId": {
                            "type": "string",
                            "description": "The card payment"
                          },
                          "refunded": {
                            "type": "boolean",
                            "description": "The payment was refunded"
                          }
                        },
                        "additionalProperties": true
                      }
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": [
                    {
                      "kind": "registration",
                      "status": "completed",
                      "customerPrice": 52.8,
                      "currency": "eur",
                      "at": "2026-10-08T12:30:00.000Z",
                      "stripePaymentIntentId": "pi_3Q…",
                      "refunded": false
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/domains/contacts": {
      "get": {
        "operationId": "listRegistrantContacts",
        "summary": "List Registrant Contacts",
        "description": "The account's registrant contacts.\n\nFull reference: https://www.totalum.app/docs/api/domain-registration#list-registrant-contacts",
        "tags": [
          "Buy a Domain"
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "List Registrant Contacts — Totalum docs",
          "url": "https://www.totalum.app/docs/api/domain-registration#list-registrant-contacts"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "contacts": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "description": "Contact id (for contactId)"
                              },
                              "label": {
                                "type": "string",
                                "description": "Your label"
                              },
                              "contact": {
                                "type": "object",
                                "description": "The contact data (see Create Registrant Contact)",
                                "additionalProperties": true
                              }
                            },
                            "additionalProperties": true
                          }
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "contacts": [
                      {
                        "id": "ct_01k6y2",
                        "label": "Main",
                        "contact": {
                          "firstName": "Ana",
                          "lastName": "García",
                          "email": "ana@barbershop.io",
                          "phone": "+34600111222",
                          "address1": "Calle Mayor 1",
                          "city": "Madrid",
                          "zip": "28013",
                          "country": "ES"
                        }
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      },
      "post": {
        "operationId": "createRegistrantContact",
        "summary": "Create Registrant Contact",
        "description": "Create the legal owner data used to register domains. Owner only.\n\nFull reference: https://www.totalum.app/docs/api/domain-registration#create-registrant-contact",
        "tags": [
          "Buy a Domain"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "label": {
                    "type": "string",
                    "description": "Up to 100 characters"
                  },
                  "contact": {
                    "type": "object",
                    "description": "The registrant",
                    "properties": {
                      "firstName": {
                        "type": "string",
                        "description": "First name"
                      },
                      "lastName": {
                        "type": "string",
                        "description": "Last name"
                      },
                      "organization": {
                        "type": "string",
                        "description": "Company"
                      },
                      "email": {
                        "type": "string",
                        "description": "E-mail (must be verified after a purchase, see verification.verifyBy)"
                      },
                      "phone": {
                        "type": "string",
                        "description": "International format: +, the country calling code and the number, +34644479777. Spaces, dashes, dots and parentheses are accepted and removed, and a leading 00 is read as + (0034 644 47 97 77 is saved as +34644479777)"
                      },
                      "address1": {
                        "type": "string",
                        "description": "Address"
                      },
                      "address2": {
                        "type": "string",
                        "description": "Address, second line"
                      },
                      "city": {
                        "type": "string",
                        "description": "City"
                      },
                      "state": {
                        "type": "string",
                        "description": "State or province"
                      },
                      "zip": {
                        "type": "string",
                        "description": "Postal code"
                      },
                      "country": {
                        "type": "string",
                        "description": "Two-letter ISO 3166-1 alpha-2 code (ES, US), any case, saved uppercase. A country name (United States) is refused"
                      }
                    },
                    "required": [
                      "firstName",
                      "lastName",
                      "email",
                      "phone",
                      "address1",
                      "city",
                      "zip",
                      "country"
                    ],
                    "additionalProperties": true
                  }
                },
                "required": [
                  "contact"
                ],
                "additionalProperties": true
              },
              "example": {
                "label": "Main",
                "contact": {
                  "firstName": "Ana",
                  "lastName": "García",
                  "email": "ana@barbershop.io",
                  "phone": "+34600111222",
                  "address1": "Calle Mayor 1",
                  "city": "Madrid",
                  "zip": "28013",
                  "country": "ES"
                }
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Create Registrant Contact — Totalum docs",
          "url": "https://www.totalum.app/docs/api/domain-registration#create-registrant-contact"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "Contact id"
                        },
                        "label": {
                          "type": "string",
                          "description": "Label"
                        },
                        "contact": {
                          "type": "object",
                          "description": "The contact",
                          "additionalProperties": true
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "id": "ct_01k6y2",
                    "label": "Main",
                    "contact": {
                      "firstName": "Ana",
                      "lastName": "García",
                      "email": "ana@barbershop.io",
                      "phone": "+34600111222",
                      "address1": "Calle Mayor 1",
                      "city": "Madrid",
                      "zip": "28013",
                      "country": "ES"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`VALIDATION_ERROR` — A field is missing or invalid; the message names it, e.g. country must be a 2-letter ISO code like ES, US or phone must be in international format like +34644479777 (spaces are removed)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "`OWNER_ONLY` — Only the account owner",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/domains/contacts/{contactId}": {
      "patch": {
        "operationId": "updateRegistrantContact",
        "summary": "Update Registrant Contact",
        "description": "Change a contact. Every active domain registered with it is updated; a change of registrant restarts the 60-day transfer lock of those domains.\n\nFull reference: https://www.totalum.app/docs/api/domain-registration#update-registrant-contact",
        "tags": [
          "Buy a Domain"
        ],
        "parameters": [
          {
            "name": "contactId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The contact id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "label": {
                    "type": "string",
                    "description": "Label"
                  },
                  "contact": {
                    "type": "object",
                    "description": "The full contact, as in Create Registrant Contact",
                    "additionalProperties": true
                  }
                },
                "required": [
                  "contact"
                ],
                "additionalProperties": true
              },
              "example": {
                "contact": {
                  "firstName": "Ana",
                  "lastName": "García",
                  "email": "ana@barbershop.io",
                  "phone": "+34600111222",
                  "address1": "Calle Mayor 2",
                  "city": "Madrid",
                  "zip": "28013",
                  "country": "ES"
                }
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Update Registrant Contact — Totalum docs",
          "url": "https://www.totalum.app/docs/api/domain-registration#update-registrant-contact"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "contact": {
                          "type": "object",
                          "description": "The saved contact",
                          "additionalProperties": true
                        },
                        "warnings": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "{ code: \"DOMAIN_TRANSFER_LOCKED\", domains } when domains were re-locked"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "contact": {
                      "id": "ct_01k6y2",
                      "label": "Main"
                    },
                    "warnings": []
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/domains/contacts/{contactId}/resend-verification": {
      "post": {
        "operationId": "resendRegistrantVerification",
        "summary": "Resend Registrant Verification",
        "description": "Send the registrant's verification e-mail again.\n\nFull reference: https://www.totalum.app/docs/api/domain-registration#resend-registrant-verification",
        "tags": [
          "Buy a Domain"
        ],
        "parameters": [
          {
            "name": "contactId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The contact id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Resend Registrant Verification — Totalum docs",
          "url": "https://www.totalum.app/docs/api/domain-registration#resend-registrant-verification"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "sent": {
                          "type": "number",
                          "description": "Verification e-mails sent (0 when nothing is pending)"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "sent": 1
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/mobile/builds": {
      "post": {
        "operationId": "createMobileBuild",
        "summary": "Create Mobile Build",
        "description": "Start a build. Answers 202 with the build queued.\n\nFull reference: https://www.totalum.app/docs/api/mobile#create-mobile-build",
        "tags": [
          "Mobile Apps"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "platform": {
                    "type": "string",
                    "description": "\"android\" or \"ios\""
                  },
                  "artifact": {
                    "type": "string",
                    "description": "Android: \"debug-apk\", \"apk\" (default) or \"aab\" (for Google Play). iOS: \"simulator-app\" (default, no Apple account needed) or \"ipa\" (signed, for TestFlight)"
                  },
                  "mode": {
                    "type": "string",
                    "description": "\"remote_shell\" (Android default: the app loads the site) or \"hybrid\" (iOS default: a bundled shell that loads the site)"
                  },
                  "signed": {
                    "type": "boolean",
                    "description": "Android: sign the apk (default: signed when a key is set)"
                  }
                },
                "required": [
                  "platform"
                ],
                "additionalProperties": true
              },
              "example": {
                "platform": "android",
                "artifact": "aab"
              }
            }
          }
        },
        "x-totalum-cost": "Metered (build time)",
        "externalDocs": {
          "description": "Create Mobile Build — Totalum docs",
          "url": "https://www.totalum.app/docs/api/mobile#create-mobile-build"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "buildId": {
                          "type": "string",
                          "description": "The build"
                        },
                        "status": {
                          "type": "string",
                          "description": "\"queued\""
                        },
                        "creditsReserved": {
                          "type": "number",
                          "description": "Credits held for the build"
                        },
                        "creditsCharged": {
                          "type": "number",
                          "description": "Credits taken now (the reservation)"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "buildId": "mb_01k6y4",
                    "status": "queued",
                    "creditsReserved": 13.3,
                    "creditsCharged": 13.3
                  }
                }
              }
            }
          },
          "400": {
            "description": "`VALIDATION_ERROR` — The artifact does not match the platform",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "`INSUFFICIENT_CREDITS` — Not enough credits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "`PLAN_REQUIRED` — Mobile builds need a paid plan\n`OWNER_ONLY` — A signed build is the owner's\n`FEATURE_DISABLED` — That build type is not available yet",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "`MOBILE_REQUIRES_PUBLISHED_PROJECT` — Publish first: the app opens the published site\n`SIGNING_NOT_CONFIGURED` — A signed build without a signing key\n`MOBILE_BUILD_RUNNING` — A build is already running\n`PROCESS_IN_PROGRESS` — A signed Android build while a prompt runs",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "`MOBILE_BUILD_RATE_LIMITED` — One build per hour; errorDetails.retryAt says when",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listMobileBuilds",
        "summary": "List Mobile Builds",
        "description": "The project's builds, newest first.\n\nFull reference: https://www.totalum.app/docs/api/mobile#list-mobile-builds",
        "tags": [
          "Mobile Apps"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "List Mobile Builds — Totalum docs",
          "url": "https://www.totalum.app/docs/api/mobile#list-mobile-builds"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "builds": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "Builds, with the fields of Get Mobile Build"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "builds": [
                      {
                        "id": "mb_01k6y4",
                        "platform": "android",
                        "mode": "remote_shell",
                        "status": "success",
                        "startedAt": "2026-10-08T13:00:10.000Z",
                        "finishedAt": "2026-10-08T13:06:40.000Z",
                        "artifact": {
                          "type": "aab",
                          "sizeBytes": 4194304,
                          "expiresAt": "2026-11-07T13:06:40.000Z"
                        },
                        "signed": true,
                        "versionName": "1.0.3",
                        "versionCode": 3,
                        "trigger": "user",
                        "hasLog": true
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/mobile/builds/{buildId}": {
      "get": {
        "operationId": "getMobileBuild",
        "summary": "Get Mobile Build",
        "description": "One build. Poll it until status is \"success\", \"failed\" or \"cancelled\".\n\nFull reference: https://www.totalum.app/docs/api/mobile#get-mobile-build",
        "tags": [
          "Mobile Apps"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          },
          {
            "name": "buildId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The build id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Mobile Build — Totalum docs",
          "url": "https://www.totalum.app/docs/api/mobile#get-mobile-build"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "Build id"
                        },
                        "platform": {
                          "type": "string",
                          "description": "\"android\" or \"ios\""
                        },
                        "mode": {
                          "type": "string",
                          "description": "\"remote_shell\" or \"hybrid\""
                        },
                        "status": {
                          "type": "string",
                          "description": "\"queued\", \"running\", \"success\", \"failed\" or \"cancelled\""
                        },
                        "queuePosition": {
                          "type": "number",
                          "description": "Place in the queue while queued"
                        },
                        "startedAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Start"
                        },
                        "finishedAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "End"
                        },
                        "artifact": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "{ type, sizeBytes, expiresAt } once built",
                          "additionalProperties": true
                        },
                        "signed": {
                          "type": "boolean",
                          "description": "Signed build"
                        },
                        "signingFingerprintSha256": {
                          "type": "string",
                          "description": "Certificate fingerprint"
                        },
                        "versionName": {
                          "type": "string",
                          "description": "Version name"
                        },
                        "versionCode": {
                          "type": "number",
                          "description": "Version code"
                        },
                        "trigger": {
                          "type": "string",
                          "description": "\"user\" or \"publish\""
                        },
                        "error": {
                          "type": "object",
                          "description": "{ code, message, logExcerpt? } of a failed build",
                          "additionalProperties": true
                        },
                        "hasLog": {
                          "type": "boolean",
                          "description": "A full log is available"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "id": "mb_01k6y4",
                    "platform": "android",
                    "mode": "remote_shell",
                    "status": "queued",
                    "queuePosition": 2,
                    "startedAt": null,
                    "finishedAt": null,
                    "artifact": null,
                    "signed": true
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "404": {
            "description": "`MOBILE_BUILD_NOT_FOUND` — No such build",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/mobile/builds/{buildId}/download": {
      "get": {
        "operationId": "getMobileBuildDownload",
        "summary": "Get Mobile Build Download",
        "description": "A 15-minute link to the built file.\n\nFull reference: https://www.totalum.app/docs/api/mobile#get-mobile-build-download",
        "tags": [
          "Mobile Apps"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          },
          {
            "name": "buildId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The build id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Mobile Build Download — Totalum docs",
          "url": "https://www.totalum.app/docs/api/mobile#get-mobile-build-download"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "url": {
                          "type": "string",
                          "description": "Download URL"
                        },
                        "fileName": {
                          "type": "string",
                          "description": "File name"
                        },
                        "type": {
                          "type": "string",
                          "description": "The artifact type"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "url": "https://files.totalum.app/mobile/mb_01k6y4/app-release.aab?sig=…",
                    "fileName": "barber-bookings-1.0.3.aab",
                    "type": "aab"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "409": {
            "description": "`MOBILE_BUILD_NOT_READY` — The build has no file (yet)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "410": {
            "description": "`DOWNLOAD_EXPIRED` — The file has expired",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/mobile/builds/{buildId}/log": {
      "get": {
        "operationId": "getMobileBuildLog",
        "summary": "Get Mobile Build Log",
        "description": "A 15-minute link to the build's full log. Ask the agent to fix a failed build (\"the Android build fails\"): it reads the log itself.\n\nFull reference: https://www.totalum.app/docs/api/mobile#get-mobile-build-log",
        "tags": [
          "Mobile Apps"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          },
          {
            "name": "buildId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The build id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Mobile Build Log — Totalum docs",
          "url": "https://www.totalum.app/docs/api/mobile#get-mobile-build-log"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "url": {
                          "type": "string",
                          "description": "Log URL"
                        },
                        "fileName": {
                          "type": "string",
                          "description": "\"build.log\""
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "url": "https://files.totalum.app/mobile/mb_01k6y4/build.log?sig=…",
                    "fileName": "build.log"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "409": {
            "description": "`MOBILE_BUILD_NOT_READY` — The build has no log",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/mobile/builds/{buildId}/cancel": {
      "post": {
        "operationId": "cancelMobileBuild",
        "summary": "Cancel Mobile Build",
        "description": "Cancel a build that is still waiting in the queue (its reservation is given back). A build that has started runs to its end.\n\nFull reference: https://www.totalum.app/docs/api/mobile#cancel-mobile-build",
        "tags": [
          "Mobile Apps"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          },
          {
            "name": "buildId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The build id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Cancel Mobile Build — Totalum docs",
          "url": "https://www.totalum.app/docs/api/mobile#cancel-mobile-build"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "description": "The build after cancelling, as in Get Mobile Build",
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "id": "mb_01k6y4",
                    "platform": "android",
                    "mode": "remote_shell",
                    "status": "cancelled",
                    "startedAt": null,
                    "finishedAt": "2026-10-08T13:01:00.000Z",
                    "artifact": null,
                    "signed": true
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "409": {
            "description": "`MOBILE_BUILD_NOT_CANCELLABLE` — The build is no longer waiting in the queue",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/mobile/builds/{buildId}/store-upload": {
      "post": {
        "operationId": "uploadBuildToStore",
        "summary": "Upload Build To Store",
        "description": "Send a signed build to its store: an aab to the Google Play internal track, an ipa to TestFlight. Promotion to production stays your step in each store's console. At most 10 store uploads a day.\n\nFull reference: https://www.totalum.app/docs/api/mobile#upload-build-to-store",
        "tags": [
          "Mobile Apps"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          },
          {
            "name": "buildId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "A signed aab or ipa build"
          }
        ],
        "x-totalum-cost": "Free (Android) · metered (iOS)",
        "externalDocs": {
          "description": "Upload Build To Store — Totalum docs",
          "url": "https://www.totalum.app/docs/api/mobile#upload-build-to-store"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "uploadId": {
                          "type": "string",
                          "description": "The upload"
                        },
                        "store": {
                          "type": "string",
                          "description": "\"google-play\" or \"app-store\""
                        },
                        "track": {
                          "type": "string",
                          "description": "\"internal\" or \"testflight\""
                        },
                        "status": {
                          "type": "string",
                          "description": "\"queued\""
                        },
                        "creditsReserved": {
                          "type": "number",
                          "description": "Credits held"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "uploadId": "su_01k6y5abcdefghjkmnpqrstvwx",
                    "store": "google-play",
                    "track": "internal",
                    "status": "queued",
                    "creditsReserved": 0
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "409": {
            "description": "`MOBILE_BUILD_NOT_SIGNED` — Only a signed aab or ipa\n`STORE_NOT_CONFIGURED` — Connect the store first\n`STORE_UPLOAD_RUNNING` — An upload is already running",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "`STORE_UPLOAD_LIMIT_REACHED` — 10 uploads today",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/mobile/store-uploads": {
      "get": {
        "operationId": "listStoreUploads",
        "summary": "List Store Uploads",
        "description": "The project's store uploads.\n\nFull reference: https://www.totalum.app/docs/api/mobile#list-store-uploads",
        "tags": [
          "Mobile Apps"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "List Store Uploads — Totalum docs",
          "url": "https://www.totalum.app/docs/api/mobile#list-store-uploads"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "uploads": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "description": "Upload id"
                              },
                              "buildId": {
                                "type": "string",
                                "description": "The build"
                              },
                              "store": {
                                "type": "string",
                                "description": "\"google-play\" or \"app-store\""
                              },
                              "track": {
                                "type": "string",
                                "description": "\"internal\" or \"testflight\""
                              },
                              "status": {
                                "type": "string",
                                "description": "\"queued\", \"uploading\", \"processing\", \"success\", \"failed\" or \"manual_required\" (Google Play's first upload of an app must be made by hand)"
                              },
                              "versionName": {
                                "type": "string",
                                "description": "Version name"
                              },
                              "versionCode": {
                                "type": "number",
                                "description": "Version code"
                              },
                              "consoleUrl": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Link to the store console"
                              },
                              "error": {
                                "type": "object",
                                "description": "{ code, message }",
                                "additionalProperties": true
                              },
                              "createdAt": {
                                "type": "string",
                                "description": "ISO 8601"
                              },
                              "finishedAt": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "ISO 8601"
                              }
                            },
                            "additionalProperties": true
                          }
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "uploads": [
                      {
                        "id": "su_01k6y5abcdefghjkmnpqrstvwx",
                        "buildId": "mb_01k6y4",
                        "store": "google-play",
                        "track": "internal",
                        "status": "success",
                        "versionName": "1.0.3",
                        "versionCode": 3,
                        "consoleUrl": "https://play.google.com/console/…",
                        "createdAt": "2026-10-08T13:07:00.000Z",
                        "finishedAt": "2026-10-08T13:09:00.000Z"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/mobile/store-uploads/{uploadId}": {
      "get": {
        "operationId": "getStoreUpload",
        "summary": "Get Store Upload",
        "description": "One store upload, with the fields of List Store Uploads.\n\nFull reference: https://www.totalum.app/docs/api/mobile#get-store-upload",
        "tags": [
          "Mobile Apps"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          },
          {
            "name": "uploadId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The upload id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Store Upload — Totalum docs",
          "url": "https://www.totalum.app/docs/api/mobile#get-store-upload"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "description": "The upload",
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "id": "su_01k6y5abcdefghjkmnpqrstvwx",
                    "buildId": "mb_01k6y4",
                    "store": "google-play",
                    "track": "internal",
                    "status": "processing",
                    "versionName": "1.0.3",
                    "versionCode": 3,
                    "consoleUrl": null,
                    "createdAt": "2026-10-08T13:07:00.000Z",
                    "finishedAt": null
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/mobile/settings": {
      "get": {
        "operationId": "getMobileSettings",
        "summary": "Get Mobile Settings",
        "description": "The app name and whether publishing also sends the apps to the stores.\n\nFull reference: https://www.totalum.app/docs/api/mobile#get-mobile-settings",
        "tags": [
          "Mobile Apps"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Mobile Settings — Totalum docs",
          "url": "https://www.totalum.app/docs/api/mobile#get-mobile-settings"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "sendToStoresOnPublish": {
                          "type": "boolean",
                          "description": "Every successful publish builds and uploads the signed apps"
                        },
                        "appName": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "The name under the icon (≤ 30 characters); null = the store listing title, else the site's name"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "sendToStoresOnPublish": false,
                    "appName": "Barber Book"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      },
      "put": {
        "operationId": "setMobileSettings",
        "summary": "Set Mobile Settings",
        "description": "Change either setting. Turning on sendToStoresOnPublish needs a connected store.\n\nFull reference: https://www.totalum.app/docs/api/mobile#set-mobile-settings",
        "tags": [
          "Mobile Apps"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "sendToStoresOnPublish": {
                    "type": "boolean",
                    "description": "Build and upload on every publish"
                  },
                  "appName": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "1–30 characters; null = default"
                  }
                },
                "additionalProperties": true
              },
              "example": {
                "appName": "Barber Book"
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Set Mobile Settings — Totalum docs",
          "url": "https://www.totalum.app/docs/api/mobile#set-mobile-settings"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "sendToStoresOnPublish": {
                          "type": "boolean",
                          "description": "After the change"
                        },
                        "appName": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "After the change"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "sendToStoresOnPublish": false,
                    "appName": "Barber Book"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "409": {
            "description": "`STORE_NOT_CONFIGURED` — Connect Google Play or the App Store first",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/mobile/signing/{slot}": {
      "get": {
        "operationId": "getSigningKey",
        "summary": "Get Signing Key",
        "description": "The signing key of one platform (metadata only, never a secret). slot is android, ios, or codemagic (your own Codemagic API token: configured, tokenHint = its last 4 characters, addedAt).\n\nFull reference: https://www.totalum.app/docs/api/mobile#get-signing-key",
        "tags": [
          "Mobile Apps"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          },
          {
            "name": "slot",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "\"android\", \"ios\" or \"codemagic\""
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Signing Key — Totalum docs",
          "url": "https://www.totalum.app/docs/api/mobile#get-signing-key"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "configured": {
                          "type": "boolean",
                          "description": "A key is set"
                        },
                        "source": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Android: \"uploaded\" or \"generated\""
                        },
                        "keyAlias": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Android key alias"
                        },
                        "fingerprintSha256": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Android certificate fingerprint"
                        },
                        "validUntil": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Android certificate expiry"
                        },
                        "keystoreDownloadAvailable": {
                          "type": "boolean",
                          "description": "Android: a generated keystore can still be downloaded"
                        },
                        "keyId, data": {
                          "type": "object",
                          "properties": {
                            "issuerId, data": {
                              "type": "object",
                              "properties": {
                                "teamId, data": {
                                  "type": "object",
                                  "properties": {
                                    "bundleId, data": {
                                      "type": "object",
                                      "properties": {
                                        "validatedAt": {
                                          "type": [
                                            "string",
                                            "null"
                                          ],
                                          "description": "iOS: the App Store Connect key"
                                        }
                                      },
                                      "additionalProperties": true
                                    }
                                  },
                                  "additionalProperties": true
                                }
                              },
                              "additionalProperties": true
                            }
                          },
                          "additionalProperties": true
                        },
                        "createdAt, data": {
                          "type": "object",
                          "properties": {
                            "lastUsedAt": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Dates"
                            }
                          },
                          "additionalProperties": true
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "configured": true,
                    "source": "generated",
                    "keyAlias": "upload",
                    "fingerprintSha256": "AB:CD:…",
                    "validUntil": "2051-10-08T00:00:00.000Z",
                    "keystoreDownloadAvailable": false,
                    "createdAt": "2026-10-08T12:50:00.000Z",
                    "lastUsedAt": "2026-10-08T13:00:10.000Z"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      },
      "put": {
        "operationId": "setSigningKey",
        "summary": "Set Signing Key",
        "description": "Set the signing key. Android (slot = android): multipart/form-data with the keystore file (keystore, a .jks/.keystore up to 64 KB) and its passwords — or generate one with Android Signing Action. iOS (slot = ios): JSON with the App Store Connect API key, checked against Apple. Codemagic (slot = codemagic): JSON { \"apiToken\": \"…\" }, checked against Codemagic; Totalum adds a totalum-mobile-builds app to that Codemagic account and runs the project's next builds there (refused 409 MOBILE_BUILD_RUNNING while a build runs).\n\nFull reference: https://www.totalum.app/docs/api/mobile#set-signing-key",
        "tags": [
          "Mobile Apps"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          },
          {
            "name": "slot",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "\"android\", \"ios\" or \"codemagic\""
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "keystore": {
                    "type": "string",
                    "format": "binary",
                    "description": "The keystore file"
                  },
                  "keyAlias": {
                    "type": "string",
                    "description": "Key alias"
                  },
                  "storePassword": {
                    "type": "string",
                    "description": "6–200 characters"
                  },
                  "keyPassword": {
                    "type": "string",
                    "description": "6–200 characters"
                  },
                  "apiKeyP8": {
                    "type": "string",
                    "description": "The .p8 key, PEM text"
                  },
                  "keyId": {
                    "type": "string",
                    "description": "10-character key id"
                  },
                  "issuerId": {
                    "type": "string",
                    "description": "Issuer UUID"
                  },
                  "bundleId": {
                    "type": "string",
                    "description": "The app's bundle id (com.example.app)"
                  },
                  "apiToken": {
                    "type": "string",
                    "description": "Your Codemagic API token (Account settings → API token)"
                  }
                },
                "additionalProperties": true
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Set Signing Key — Totalum docs",
          "url": "https://www.totalum.app/docs/api/mobile#set-signing-key"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "description": "The key, as in Get Signing Key",
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "configured": true,
                    "source": "uploaded",
                    "keyAlias": "upload",
                    "fingerprintSha256": "AB:CD:…",
                    "validUntil": "2051-10-08T00:00:00.000Z",
                    "keystoreDownloadAvailable": false,
                    "createdAt": "2026-10-08T12:50:00.000Z",
                    "lastUsedAt": null
                  }
                }
              }
            }
          },
          "400": {
            "description": "`SIGNING_INVALID_KEYSTORE` — The keystore was refused (errorDetails.reason: parse, password, alias, expired, weak_key)\n`VALIDATION_ERROR` — Codemagic refused the API token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "`PLAN_REQUIRED` — Needs a paid plan\n`OWNER_ONLY` — Owner only",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "`SIGNING_ALREADY_CONFIGURED` — Delete the current keystore first",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteSigningKey",
        "summary": "Delete Signing Key",
        "description": "Remove a platform's signing key (or, with slot = codemagic, your Codemagic API token: builds go back to Totalum's build servers). Answers 204 with no body.\n\nFull reference: https://www.totalum.app/docs/api/mobile#delete-signing-key",
        "tags": [
          "Mobile Apps"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          },
          {
            "name": "slot",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "\"android\", \"ios\" or \"codemagic\""
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Delete Signing Key — Totalum docs",
          "url": "https://www.totalum.app/docs/api/mobile#delete-signing-key"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "(none)": {
                      "description": "204 No Content"
                    }
                  },
                  "additionalProperties": true
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "409": {
            "description": "`MOBILE_BUILD_RUNNING` — A signed build is using the key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/mobile/signing/android/{action}": {
      "post": {
        "operationId": "androidSigningAction",
        "summary": "Android Signing Action",
        "description": "action = generate: create an Android upload key (RSA 4096, 25 years, alias upload) and get a one-time, 15-minute token to download it. action = keystore-download: exchange that token for the keystore file and its passwords — keep them safe; Google Play needs the same key for every update.\n\nFull reference: https://www.totalum.app/docs/api/mobile#android-signing-action",
        "tags": [
          "Mobile Apps"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          },
          {
            "name": "action",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "\"generate\" or \"keystore-download\""
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "commonName": {
                    "type": "string",
                    "description": "generate: certificate name"
                  },
                  "organization": {
                    "type": "string",
                    "description": "generate: organisation"
                  },
                  "countryCode": {
                    "type": "string",
                    "description": "generate: two-letter country"
                  },
                  "token": {
                    "type": "string",
                    "description": "keystore-download: the token from generate"
                  }
                },
                "additionalProperties": true
              },
              "example": {
                "organization": "Barber Shop SL",
                "countryCode": "ES"
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Android Signing Action — Totalum docs",
          "url": "https://www.totalum.app/docs/api/mobile#android-signing-action"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "keystoreDownload": {
                          "type": "object",
                          "description": "generate: { token, expiresAt } plus the key's fields",
                          "additionalProperties": true
                        },
                        "url": {
                          "type": "string",
                          "description": "keystore-download: a single-use URL (5 minutes)"
                        },
                        "fileName": {
                          "type": "string",
                          "description": "\"upload-keystore.jks\""
                        },
                        "keyAlias, data": {
                          "type": "object",
                          "properties": {
                            "storePassword, data": {
                              "type": "object",
                              "properties": {
                                "keyPassword": {
                                  "type": "string",
                                  "description": "keystore-download: shown once"
                                }
                              },
                              "additionalProperties": true
                            }
                          },
                          "additionalProperties": true
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "configured": true,
                    "source": "generated",
                    "keyAlias": "upload",
                    "fingerprintSha256": "AB:CD:…",
                    "validUntil": "2051-10-08T00:00:00.000Z",
                    "keystoreDownloadAvailable": true,
                    "createdAt": "2026-10-08T12:50:00.000Z",
                    "lastUsedAt": null,
                    "keystoreDownload": {
                      "token": "kd_9f2c…",
                      "expiresAt": "2026-10-08T13:05:00.000Z"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "409": {
            "description": "`SIGNING_ALREADY_CONFIGURED` — A key exists; delete it first\n`KEYSTORE_NOT_DOWNLOADABLE` — An uploaded keystore is never downloadable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "410": {
            "description": "`KEYSTORE_DOWNLOAD_EXPIRED` — The token was used or expired",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/mobile/stores": {
      "get": {
        "operationId": "listStoreConnections",
        "summary": "List Store Connections",
        "description": "The connected store accounts (metadata only).\n\nFull reference: https://www.totalum.app/docs/api/mobile#list-store-connections",
        "tags": [
          "Mobile Apps"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "List Store Connections — Totalum docs",
          "url": "https://www.totalum.app/docs/api/mobile#list-store-connections"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "googlePlay": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "{ clientEmail, packageName, packageFound, validatedAt }",
                          "additionalProperties": true
                        },
                        "appStore": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "{ appAppleId, bundleId, validatedAt }",
                          "additionalProperties": true
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "googlePlay": {
                      "clientEmail": "uploader@my-play.iam.gserviceaccount.com",
                      "packageName": "com.barbershop.book",
                      "packageFound": true,
                      "validatedAt": "2026-10-08T12:55:00.000Z"
                    },
                    "appStore": null
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/mobile/stores/{store}": {
      "get": {
        "operationId": "getStoreConnection",
        "summary": "Get Store Connection",
        "description": "One store's connection (metadata only). The answer has only that store's field: googlePlay for google-play, appStore for app-store; null when it is not connected.\n\nFull reference: https://www.totalum.app/docs/api/mobile#get-store-connection",
        "tags": [
          "Mobile Apps"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          },
          {
            "name": "store",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "\"google-play\" or \"app-store\""
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Store Connection — Totalum docs",
          "url": "https://www.totalum.app/docs/api/mobile#get-store-connection"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "googlePlay": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "google-play only: { clientEmail, packageName, packageFound, validatedAt }",
                          "additionalProperties": true
                        },
                        "appStore": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "app-store only: { appAppleId, bundleId, validatedAt }",
                          "additionalProperties": true
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "appStore": null
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      },
      "put": {
        "operationId": "connectStore",
        "summary": "Connect Store",
        "description": "Connect a store account. Google Play: a Play Console service-account key (the JSON Google downloads) with release rights on the app, and the package name; a package Google does not know yet is stored with packageFound: false and its first bundle must be uploaded by hand. App Store: uses the iOS signing key; the app is found by its bundle id (or give appAppleId). The answer has only the store you connected.\n\nFull reference: https://www.totalum.app/docs/api/mobile#connect-store",
        "tags": [
          "Mobile Apps"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          },
          {
            "name": "store",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "\"google-play\" or \"app-store\""
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "serviceAccountJson": {
                    "type": "string",
                    "description": "The service-account JSON, as text"
                  },
                  "packageName": {
                    "type": "string",
                    "description": "com.example.app"
                  },
                  "appAppleId": {
                    "type": "string",
                    "description": "App Store: the app's Apple id"
                  }
                },
                "additionalProperties": true
              },
              "example": {
                "packageName": "com.barbershop.book",
                "serviceAccountJson": "{\"type\":\"service_account\",…}"
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Connect Store — Totalum docs",
          "url": "https://www.totalum.app/docs/api/mobile#connect-store"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "googlePlay": {
                          "type": "object",
                          "description": "google-play only: the connection, as in List Store Connections",
                          "additionalProperties": true
                        },
                        "appStore": {
                          "type": "object",
                          "description": "app-store only: the connection, as in List Store Connections",
                          "additionalProperties": true
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "googlePlay": {
                      "clientEmail": "uploader@my-play.iam.gserviceaccount.com",
                      "packageName": "com.barbershop.book",
                      "packageFound": true,
                      "validatedAt": "2026-10-08T12:55:00.000Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`VALIDATION_ERROR` — Invalid key or package name",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "409": {
            "description": "`SIGNING_NOT_CONFIGURED` — App Store: add the iOS signing key first",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "disconnectStore",
        "summary": "Disconnect Store",
        "description": "Remove a store connection. Answers 204 with no body.\n\nFull reference: https://www.totalum.app/docs/api/mobile#disconnect-store",
        "tags": [
          "Mobile Apps"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          },
          {
            "name": "store",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "\"google-play\" or \"app-store\""
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Disconnect Store — Totalum docs",
          "url": "https://www.totalum.app/docs/api/mobile#disconnect-store"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "(none)": {
                      "description": "204 No Content"
                    }
                  },
                  "additionalProperties": true
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/payments/status": {
      "get": {
        "operationId": "getPaymentsStatus",
        "summary": "Get Payments Status",
        "description": "Your connected Stripe account and whether it can take payments.\n\nFull reference: https://www.totalum.app/docs/api/payments#get-payments-status",
        "tags": [
          "Payments"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          },
          {
            "name": "mode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "\"live\" (default: your Stripe account) or \"test\" (the preview's test account)"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Payments Status — Totalum docs",
          "url": "https://www.totalum.app/docs/api/payments#get-payments-status"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "enabled": {
                          "type": "boolean",
                          "description": "A Stripe account is connected"
                        },
                        "mode": {
                          "type": "string",
                          "description": "\"connect\""
                        },
                        "accountId": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "The Stripe account id"
                        },
                        "livemode": {
                          "type": "boolean",
                          "description": "true for the live account"
                        },
                        "chargesEnabled": {
                          "type": "boolean",
                          "description": "It can take payments"
                        },
                        "payoutsEnabled": {
                          "type": "boolean",
                          "description": "It can receive payouts"
                        },
                        "detailsSubmitted": {
                          "type": "boolean",
                          "description": "Onboarding is complete"
                        },
                        "requirements": {
                          "type": "object",
                          "description": "{ currentlyDue, pastDue, eventuallyDue }: what Stripe still asks for",
                          "additionalProperties": true
                        },
                        "liveEnabled": {
                          "type": "boolean",
                          "description": "The published site charges in live mode"
                        },
                        "disconnectedAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "When the owner disconnected the account from Stripe"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "enabled": true,
                    "mode": "connect",
                    "accountId": "acct_1Q2w3E4r",
                    "livemode": true,
                    "chargesEnabled": true,
                    "payoutsEnabled": true,
                    "detailsSubmitted": true,
                    "requirements": {
                      "currentlyDue": [],
                      "pastDue": [],
                      "eventuallyDue": []
                    },
                    "liveEnabled": false,
                    "disconnectedAt": null
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/payments/onboarding-link": {
      "post": {
        "operationId": "createPaymentsOnboardingLink",
        "summary": "Create Payments Onboarding Link",
        "description": "A single-use link to Stripe's onboarding, where the owner connects (or creates) their Stripe account to receive real payments. The first link creates the account and needs its country. Publish the project first: real payments go to the published site, so a project that was never published is refused with PAYMENTS_PUBLISH_FIRST. The preview needs no onboarding: it takes test cards with no setup.\n\nFull reference: https://www.totalum.app/docs/api/payments#create-payments-onboarding-link",
        "tags": [
          "Payments"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          },
          {
            "name": "mode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "\"live\" (default and the only one: \"test\" is refused, the preview's test account needs no onboarding)"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "returnUrl": {
                    "type": "string",
                    "description": "https:// page to come back to when done"
                  },
                  "refreshUrl": {
                    "type": "string",
                    "description": "https:// page that asks for a new link if this one expired"
                  },
                  "type": {
                    "type": "string",
                    "description": "\"account_onboarding\" (default) or \"account_update\""
                  },
                  "country": {
                    "type": "string",
                    "description": "Two-letter country of the business: required for the first link (and after a disconnection), cannot change later"
                  }
                },
                "required": [
                  "returnUrl",
                  "refreshUrl"
                ],
                "additionalProperties": true
              },
              "example": {
                "returnUrl": "https://yourapp.com/payments/done",
                "refreshUrl": "https://yourapp.com/payments/retry",
                "country": "ES"
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Create Payments Onboarding Link — Totalum docs",
          "url": "https://www.totalum.app/docs/api/payments#create-payments-onboarding-link"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "url": {
                          "type": "string",
                          "description": "The onboarding link"
                        },
                        "expiresAt": {
                          "type": "string",
                          "description": "When it expires"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "url": "https://connect.stripe.com/setup/e/acct_1Q2w3E4r/…",
                    "expiresAt": "2026-10-08T13:10:00.000Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`VALIDATION_ERROR` — Missing or non-https URLs, or mode=test\n`MISSING_INPUT` — No country for a new account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "`OWNER_ONLY` — Account owner only",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "`PAYMENTS_PUBLISH_FIRST` — The project was never published: publish it, then connect Stripe",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/payments/mode": {
      "put": {
        "operationId": "setPaymentsMode",
        "summary": "Set Payments Mode",
        "description": "Switch the published site between test and real (live) payments (10 switches an hour). Live needs your connected Stripe account to have completed onboarding. The preview always stays in test mode.\n\nFull reference: https://www.totalum.app/docs/api/payments#set-payments-mode",
        "tags": [
          "Payments"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "mode": {
                    "type": "string",
                    "description": "\"test\" or \"live\""
                  }
                },
                "required": [
                  "mode"
                ],
                "additionalProperties": true
              },
              "example": {
                "mode": "live"
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Set Payments Mode — Totalum docs",
          "url": "https://www.totalum.app/docs/api/payments#set-payments-mode"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "mode": {
                          "type": "string",
                          "description": "The mode now"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "mode": "live"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "`PAYMENTS_LIVE_ONBOARDING_REQUIRED` — Finish connecting your Stripe account first\n`OWNER_ONLY` — Account owner only",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "`RATE_LIMITED` — More than 10 switches in an hour",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/webhooks": {
      "put": {
        "operationId": "registerWebhook",
        "summary": "Register Webhook",
        "description": "Subscribe an HTTPS URL to one event. One unfiltered subscription per event; filtered ones (by project or feature) can sit beside it.\n\nFull reference: https://www.totalum.app/docs/api/webhooks#register-webhook",
        "tags": [
          "Webhooks"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "description": "https:// URL that receives the POST"
                  },
                  "event": {
                    "type": "string",
                    "description": "One event from the table above"
                  },
                  "headers": {
                    "type": "object",
                    "description": "Extra headers sent with every delivery (stored encrypted)",
                    "additionalProperties": true
                  },
                  "projectIds": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Only these projects (up to 50)"
                  },
                  "features": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Only these features (ai, email…) — for the project.feature* events"
                  }
                },
                "required": [
                  "url",
                  "event"
                ],
                "additionalProperties": true
              },
              "example": {
                "url": "https://yourserver.com/totalum-webhook",
                "event": "deployment.finished"
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Register Webhook — Totalum docs",
          "url": "https://www.totalum.app/docs/api/webhooks#register-webhook"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "Subscription id"
                        },
                        "url": {
                          "type": "string",
                          "description": "URL"
                        },
                        "headers": {
                          "type": "object",
                          "description": "Extra headers",
                          "additionalProperties": true
                        },
                        "event": {
                          "type": "string",
                          "description": "Event"
                        },
                        "createdAt": {
                          "type": "string",
                          "description": "ISO 8601"
                        },
                        "projectIds": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Project filter"
                        },
                        "features": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Feature filter"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "id": "6701f2a3c4d5e6f7a8b9c0d1",
                    "url": "https://yourserver.com/totalum-webhook",
                    "event": "deployment.finished",
                    "createdAt": "2026-10-08T10:00:00.000Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`MISSING_WEBHOOK_FIELDS` — url and event are required\n`INVALID_WEBHOOK_URL` — The URL is not HTTPS\n`INVALID_WEBHOOK_EVENT` — Unknown event; the message lists every event you can register\n`VALIDATION_ERROR` — projectIds/features is not a list of strings, or more than 50 projects\n`WEBHOOK_FILTER_NOT_APPLICABLE` — features on an event that is not a feature event",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "`WEBHOOK_PROJECT_NOT_OWNED` — A projectIds entry is not your project",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "`WEBHOOK_EVENT_ALREADY_EXISTS` — A subscription for this event (and filter) already exists — delete it first",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listWebhooks",
        "summary": "List Webhooks",
        "description": "Your subscriptions, newest first.\n\nFull reference: https://www.totalum.app/docs/api/webhooks#list-webhooks",
        "tags": [
          "Webhooks"
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "List Webhooks — Totalum docs",
          "url": "https://www.totalum.app/docs/api/webhooks#list-webhooks"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "webhooks": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "description": "Subscription id"
                              },
                              "url": {
                                "type": "string",
                                "description": "URL"
                              },
                              "headers": {
                                "type": "object",
                                "description": "Extra headers",
                                "additionalProperties": true
                              },
                              "event": {
                                "type": "string",
                                "description": "Event"
                              },
                              "createdAt": {
                                "type": "string",
                                "description": "ISO 8601"
                              },
                              "updatedAt": {
                                "type": "string",
                                "description": "ISO 8601"
                              },
                              "projectIds": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                },
                                "description": "Project filter"
                              },
                              "features": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                },
                                "description": "Feature filter"
                              }
                            },
                            "additionalProperties": true
                          }
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "webhooks": [
                      {
                        "id": "6701f2a3c4d5e6f7a8b9c0d1",
                        "url": "https://yourserver.com/totalum-webhook",
                        "event": "deployment.finished",
                        "createdAt": "2026-10-08T10:00:00.000Z",
                        "updatedAt": "2026-10-08T10:00:00.000Z"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/webhooks/{webhookId}": {
      "delete": {
        "operationId": "deleteWebhook",
        "summary": "Delete Webhook",
        "description": "Remove a subscription.\n\nFull reference: https://www.totalum.app/docs/api/webhooks#delete-webhook",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "webhookId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Subscription id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Delete Webhook — Totalum docs",
          "url": "https://www.totalum.app/docs/api/webhooks#delete-webhook"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "success": {
                          "type": "boolean",
                          "description": "true"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "success": true
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "404": {
            "description": "`WEBHOOK_NOT_FOUND` — No such subscription",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/webhooks/{webhookId}/secret": {
      "get": {
        "operationId": "getWebhookSecret",
        "summary": "Get Webhook Secret",
        "description": "The subscription's signing secret, to verify X-Totalum-Signature.\n\nFull reference: https://www.totalum.app/docs/api/webhooks#get-webhook-secret",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "webhookId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Subscription id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Webhook Secret — Totalum docs",
          "url": "https://www.totalum.app/docs/api/webhooks#get-webhook-secret"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "webhookId": {
                          "type": "string",
                          "description": "Subscription id"
                        },
                        "secret": {
                          "type": "string",
                          "description": "whsec_…"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "webhookId": "6701f2a3c4d5e6f7a8b9c0d1",
                    "secret": "whsec_3f9a…"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "404": {
            "description": "`WEBHOOK_NOT_FOUND` — No such subscription",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/webhooks/{webhookId}/deliveries": {
      "get": {
        "operationId": "listWebhookDeliveries",
        "summary": "List Webhook Deliveries",
        "description": "The subscription's deliveries of the last 30 days, newest first.\n\nFull reference: https://www.totalum.app/docs/api/webhooks#list-webhook-deliveries",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "webhookId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Subscription id"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number"
            },
            "description": "1–200 (default 50)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number"
            },
            "description": "nextCursor of the previous page"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "List Webhook Deliveries — Totalum docs",
          "url": "https://www.totalum.app/docs/api/webhooks#list-webhook-deliveries"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "deliveries": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "number",
                                "description": "Delivery id"
                              },
                              "webhookId": {
                                "type": "string",
                                "description": "Subscription"
                              },
                              "event": {
                                "type": "string",
                                "description": "Event"
                              },
                              "eventId": {
                                "type": "string",
                                "description": "The event's id (X-Totalum-Event-Id)"
                              },
                              "projectId": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Project"
                              },
                              "feature": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Feature, for feature events"
                              },
                              "status": {
                                "type": "string",
                                "description": "pending, delivered or failed"
                              },
                              "attempts": {
                                "type": "number",
                                "description": "Attempts made"
                              },
                              "httpStatus": {
                                "type": [
                                  "number",
                                  "null"
                                ],
                                "description": "Your server's last answer"
                              },
                              "durationMs": {
                                "type": [
                                  "number",
                                  "null"
                                ],
                                "description": "Its duration"
                              },
                              "error": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Why it failed"
                              },
                              "at": {
                                "type": "string",
                                "description": "When the event happened"
                              },
                              "updatedAt": {
                                "type": "string",
                                "description": "Last attempt"
                              }
                            },
                            "additionalProperties": true
                          }
                        },
                        "nextCursor": {
                          "type": [
                            "number",
                            "null"
                          ],
                          "description": "Next page"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "deliveries": [
                      {
                        "id": 1042,
                        "webhookId": "6701f2a3c4d5e6f7a8b9c0d1",
                        "event": "deployment.finished",
                        "eventId": "deploy:dep_01k6xf3a9b",
                        "projectId": "barber-bookings",
                        "feature": null,
                        "status": "delivered",
                        "attempts": 1,
                        "httpStatus": 200,
                        "durationMs": 182,
                        "error": null,
                        "at": "2026-10-08T11:23:10.000Z",
                        "updatedAt": "2026-10-08T11:23:10.000Z"
                      }
                    ],
                    "nextCursor": null
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/webhook": {
      "get": {
        "operationId": "getProjectWebhook",
        "summary": "Get Project Webhook",
        "description": "The project's optional extra webhook address (for the app's integration events; payment events reach the app's /api/webhooks/stripe without it).\n\nFull reference: https://www.totalum.app/docs/api/webhooks#get-project-webhook",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Project Webhook — Totalum docs",
          "url": "https://www.totalum.app/docs/api/webhooks#get-project-webhook"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "url": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "The address"
                        },
                        "enabled": {
                          "type": "boolean",
                          "description": "A URL and a secret are set"
                        },
                        "secretPrefix": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "The start of the current secret"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "url": "https://hooks.zapier.com/hooks/catch/123456/abcdef/",
                    "enabled": true,
                    "secretPrefix": "whsec_3f9a"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      },
      "put": {
        "operationId": "setProjectWebhook",
        "summary": "Set Project Webhook",
        "description": "Set the project's optional extra webhook address (your own server, Zapier…). Account owner only.\n\nFull reference: https://www.totalum.app/docs/api/webhooks#set-project-webhook",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "description": "https:// address"
                  }
                },
                "required": [
                  "url"
                ],
                "additionalProperties": true
              },
              "example": {
                "url": "https://hooks.zapier.com/hooks/catch/123456/abcdef/"
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Set Project Webhook — Totalum docs",
          "url": "https://www.totalum.app/docs/api/webhooks#set-project-webhook"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "url": {
                          "type": "string",
                          "description": "The address"
                        },
                        "enabled": {
                          "type": "boolean",
                          "description": "A URL and a secret are set"
                        },
                        "secretPrefix": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "The start of the secret"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "url": "https://hooks.zapier.com/hooks/catch/123456/abcdef/",
                    "enabled": true,
                    "secretPrefix": "whsec_3f9a"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`VALIDATION_ERROR` — Not an https:// URL",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "`OWNER_ONLY` — Account owner only",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/webhook/rotate-secret": {
      "post": {
        "operationId": "rotateProjectWebhookSecret",
        "summary": "Rotate Project Webhook Secret",
        "description": "Create a new signing secret (shown once). The app receives it at once; the old secret keeps signing for 24 hours. Account owner only.\n\nFull reference: https://www.totalum.app/docs/api/webhooks#rotate-project-webhook-secret",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Rotate Project Webhook Secret — Totalum docs",
          "url": "https://www.totalum.app/docs/api/webhooks#rotate-project-webhook-secret"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "secret": {
                          "type": "string",
                          "description": "The new whsec_… secret"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "secret": "whsec_0b1c…"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "`OWNER_ONLY` — Account owner only",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/export": {
      "post": {
        "operationId": "exportProject",
        "summary": "Export Project",
        "description": "Create an export and get its code. At most 5 exports an hour per project. The records exported are the live database's (a project never published exports none).\n\nFull reference: https://www.totalum.app/docs/api/transfer#export-project",
        "tags": [
          "Export & Import"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project to export"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "includeRecords": {
                    "type": "boolean",
                    "description": "Also export the live data (default false: schema only)"
                  },
                  "includeFiles": {
                    "type": "boolean",
                    "description": "Also export the uploaded files (default true)"
                  }
                },
                "additionalProperties": true
              },
              "example": {
                "includeRecords": true
              }
            }
          }
        },
        "x-totalum-cost": "4 credits",
        "externalDocs": {
          "description": "Export Project — Totalum docs",
          "url": "https://www.totalum.app/docs/api/transfer#export-project"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "importCode": {
                          "type": "string",
                          "description": "Secret: anyone with it can import the project"
                        },
                        "includeRecords": {
                          "type": "boolean",
                          "description": "Data was included"
                        },
                        "includeFiles": {
                          "type": "boolean",
                          "description": "Files were included"
                        },
                        "files": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "{ count, bytes } of the files exported",
                          "additionalProperties": true
                        },
                        "message": {
                          "type": "string",
                          "description": "Confirmation"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "importCode": "barber-bookings-export-project-8f3b1c9a47e2d650b9114af0c7e3a2d1",
                    "includeRecords": true,
                    "message": "Export ready. Save the importCode (keep it secret) and pass it to import-project as importCode.",
                    "includeFiles": true,
                    "files": {
                      "count": 12,
                      "bytes": 3145728
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`PROJECT_EXPORT_LIMIT_REACHED` — 5 exports in the last hour",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "`INSUFFICIENT_CREDITS` — Not enough credits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/import": {
      "post": {
        "operationId": "importProject",
        "summary": "Import Project",
        "description": "Import an export into this project, which must be new and empty. The imported project keeps this project's id: to give it an id of your choice, create the project with that id first (with sourceImportCode, so it is made on the code's engine). The data fills both the development and the live database; then the code is built. Runs in the background (a few minutes): poll Get Project until importInProgress is null. Prompts are refused (IMPORT_IN_PROGRESS) meanwhile.\n\nFull reference: https://www.totalum.app/docs/api/transfer#import-project",
        "tags": [
          "Export & Import"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The target project; the imported project keeps this id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "importCode": {
                    "type": "string",
                    "description": "The code from Export Project"
                  }
                },
                "required": [
                  "importCode"
                ],
                "additionalProperties": true
              },
              "example": {
                "importCode": "barber-bookings-export-project-8f3b1c9a47e2d650b9114af0c7e3a2d1"
              }
            }
          }
        },
        "x-totalum-cost": "12 credits",
        "externalDocs": {
          "description": "Import Project — Totalum docs",
          "url": "https://www.totalum.app/docs/api/transfer#import-project"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "projectId": {
                          "type": "string",
                          "description": "The target project"
                        },
                        "status": {
                          "type": "string",
                          "description": "\"importing\""
                        },
                        "message": {
                          "type": "string",
                          "description": "How to follow it"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "projectId": "barber-bookings-copy",
                    "status": "importing",
                    "message": "Import started. Poll GET /api/v1/vcaas/projects/barber-bookings-copy every 10-15s until importInProgress is null, then until agentServerStatus='Active'. Prompting is blocked until the import finishes."
                  }
                }
              }
            }
          },
          "400": {
            "description": "`MISSING_IMPORT_CODE` — importCode is missing\n`INVALID_IMPORT_CODE` — Not an import code, or the export no longer exists\n`PROJECT_NOT_IMPORTABLE` — The target already has content; use a new project",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "`INSUFFICIENT_CREDITS` — Not enough credits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "409": {
            "description": "`ENGINE_MISMATCH` — The code comes from a project on the legacy engine and can only be imported into a legacy project\n`IMPORT_IN_PROGRESS` — An import is already running\n`AGENT_RUNNING` — A prompt is running",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/migrate-to-v2": {
      "post": {
        "operationId": "migrateToTheNewEngine",
        "summary": "Migrate to the New Engine",
        "description": "Move a project built on the legacy engine to the new engine. It makes a new project, <projectId>v2 (with a few random letters added when that name is taken) or the id you pass as projectId in the body, and leaves the legacy project exactly as it is: it keeps working and serving its users until you switch. Needs the Starter plan or above.\n\nFull reference: https://www.totalum.app/docs/api/transfer#migrate-to-the-new-engine",
        "tags": [
          "Export & Import"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The legacy project to migrate"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "projectId": {
                    "type": "string",
                    "description": "The new project's id, with the rules of Create Project. A taken id is refused (PROJECT_ALREADY_EXISTS), never changed. Default <projectId>v2"
                  },
                  "ownerEmail": {
                    "type": "string",
                    "description": "The new app's owner e-mail (its admin once confirmed in the app), as in Launch Project. Default: none — then the first person who signs up in the app becomes its admin after entering the 8-digit code e-mailed to them (the preview and the published app each have their own first sign-up); set one later with Set App Owner. An invalid address is refused (INVALID_OWNER_EMAIL) before anything is read"
                  }
                },
                "additionalProperties": true
              },
              "example": {
                "projectId": "barber-bookings-new"
              }
            }
          }
        },
        "x-totalum-cost": "15 credits",
        "externalDocs": {
          "description": "Migrate to the New Engine — Totalum docs",
          "url": "https://www.totalum.app/docs/api/transfer#migrate-to-the-new-engine"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "projectId": {
                          "type": "string",
                          "description": "The new project"
                        },
                        "sourceProjectId": {
                          "type": "string",
                          "description": "The legacy project (unchanged)"
                        },
                        "engineVersion": {
                          "type": "string",
                          "description": "\"v2\""
                        },
                        "creditsCharged": {
                          "type": "number",
                          "description": "Credits charged for the migration"
                        },
                        "migrated": {
                          "type": "object",
                          "description": "{ tables, records, files, filesNotCopied, filesPending, manyToManyLinks, codeFiles, codeFilesSkipped, secrets, secretsNotCopied }; files = uploaded files copied during the call, filesPending = the ones past the first 2,000, copied in the background shortly after; manyToManyLinks = many-to-many links copied; secrets and secretsNotCopied are secret names",
                          "additionalProperties": true
                        },
                        "agent": {
                          "type": "object",
                          "description": "The first prompt: { started, status, runId, expectedMinutes, message }",
                          "additionalProperties": true
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "projectId": "barber-bookings-new",
                    "sourceProjectId": "barber-bookings",
                    "engineVersion": "v2",
                    "creditsCharged": 15,
                    "migrated": {
                      "tables": 6,
                      "records": 412,
                      "files": 38,
                      "filesNotCopied": 0,
                      "filesPending": 0,
                      "manyToManyLinks": 54,
                      "codeFiles": 126,
                      "codeFilesSkipped": 0,
                      "secrets": [
                        "STRIPE_SECRET_KEY",
                        "RESEND_API_KEY"
                      ],
                      "secretsNotCopied": []
                    },
                    "agent": {
                      "started": true,
                      "status": "init",
                      "runId": "run_01m4b8w0d9",
                      "expectedMinutes": 18,
                      "message": "Process started. …"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`INVALID_PROJECT_NAME` — The body's projectId breaks the id rules (also INVALID_PROJECT_NAME_LENGTH, RESERVED_PROJECT_NAME)\n`INVALID_OWNER_EMAIL` — The body's ownerEmail is not a valid e-mail address",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "`INSUFFICIENT_CREDITS` — Fewer than 15 credits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "`PLAN_REQUIRED` — The account is below the Starter plan (errorDetails.upgradePlan)\n`MAX_PROJECTS_REACHED` — Your plan's project limit is reached (the migration makes a new project)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "`PROJECT_NOT_FOUND` — No legacy project with this id on your account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "`PROJECT_ALREADY_EXISTS` — The body's projectId is taken\n`ENGINE_MISMATCH` — The project is already on the new engine",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "`MIGRATION_TOO_LARGE` — Over 20,000 records, 20 MB of data or 20 MB of code: contact support",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "`RATE_LIMITED` — This project is already being migrated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "502": {
            "description": "`MIGRATION_START_FAILED` — The migration could not start; nothing was charged, try again",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/migrate-to-v2/refresh-data": {
      "post": {
        "operationId": "refreshMigratedData",
        "summary": "Refresh Migrated Data",
        "description": "The legacy app keeps working while its new version is being built, so its data keeps changing. Call this on the new project (the one Migrate to the New Engine made) to read the legacy project again, records, many-to-many links and files, into a fresh legacy-database.json (same file, same key). Files already copied are not copied again; new ones are, private as above (past 2,000 new files, in the background). The legacy project is only read. It costs nothing beyond the storage of the new files.\n\nFull reference: https://www.totalum.app/docs/api/transfer#refresh-migrated-data",
        "tags": [
          "Export & Import"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The new project made by the migration"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Refresh Migrated Data — Totalum docs",
          "url": "https://www.totalum.app/docs/api/transfer#refresh-migrated-data"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "projectId": {
                          "type": "string",
                          "description": "The new project"
                        },
                        "sourceProjectId": {
                          "type": "string",
                          "description": "The legacy project that was read again"
                        },
                        "snapshotKey": {
                          "type": "string",
                          "description": "The key of legacy-database.json (unchanged)"
                        },
                        "refreshed": {
                          "type": "object",
                          "description": "{ tables, records, manyToManyLinks, files, filesAlreadyCopied, filesNotCopied, filesPending }; files = new files copied now",
                          "additionalProperties": true
                        },
                        "message": {
                          "type": "string",
                          "description": "What to send the agent next"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "projectId": "barber-bookings-new",
                    "sourceProjectId": "barber-bookings",
                    "snapshotKey": "pv/barber-bookings-new/…/legacy-database.json",
                    "refreshed": {
                      "tables": 6,
                      "records": 431,
                      "manyToManyLinks": 57,
                      "files": 3,
                      "filesAlreadyCopied": 38,
                      "filesNotCopied": 0,
                      "filesPending": 0
                    },
                    "message": "legacy-database.json now holds the legacy project as it is now. …"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "404": {
            "description": "`PROJECT_NOT_FOUND` — Not a project made by Migrate to the New Engine, or its legacy project is no longer on your account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "`MIGRATION_ALREADY_PUBLISHED` — The new project has been published: its live database holds the app's data now\n`OPERATION_IN_PROGRESS` — Files of the migration (or of the last refresh) are still being copied: try again in a few minutes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "`MIGRATION_TOO_LARGE` — The legacy project has grown past what one migration copies",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "`RATE_LIMITED` — A refresh of this legacy project is already running (one every 2 minutes)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/github/connect": {
      "post": {
        "operationId": "connectGithubRepository",
        "summary": "Connect GitHub Repository",
        "description": "Connect a GitHub repository to your project using a Fine-grained Personal Access Token (PAT). This validates permissions, stores credentials, sets up branches (develop and main), and performs the initial sync. After connecting, every new version is pushed to develop, and the published code to main on every publish.\n\nFull reference: https://www.totalum.app/docs/api/github#connect-github-repository",
        "tags": [
          "GitHub"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project ID"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "token": {
                    "type": "string",
                    "description": "GitHub Fine-grained Personal Access Token"
                  },
                  "repositoryFullName": {
                    "type": "string",
                    "description": "Full repository name (e.g. \"owner/repo\")"
                  },
                  "syncDirection": {
                    "type": "string",
                    "description": "\"totalum_to_github\" (default) or \"github_to_totalum\". Controls behavior when repo has existing content with no common history"
                  }
                },
                "required": [
                  "token",
                  "repositoryFullName"
                ],
                "additionalProperties": true
              },
              "example": {
                "token": "github_pat_xxx",
                "repositoryFullName": "myuser/my-repo",
                "syncDirection": "totalum_to_github"
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Connect GitHub Repository — Totalum docs",
          "url": "https://www.totalum.app/docs/api/github#connect-github-repository"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "connected": {
                          "type": "boolean",
                          "description": "true if connection was successful"
                        },
                        "repositoryFullName": {
                          "type": "string",
                          "description": "The connected repository"
                        },
                        "syncAction": {
                          "type": "string",
                          "description": "\"push_new\", \"push\", \"pull\", \"merge_and_push\", or \"already_synced\""
                        },
                        "repoHasContent": {
                          "type": "boolean",
                          "description": "Whether the repo had existing content"
                        },
                        "requiresRebuild": {
                          "type": "boolean",
                          "description": "Whether a rebuild was triggered. If true, poll GET /github/pull-status until status is \"success\" or \"error\""
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "connected": true,
                    "repositoryFullName": "myuser/my-repo",
                    "syncAction": "push_new",
                    "repoHasContent": false,
                    "requiresRebuild": false
                  }
                }
              }
            }
          },
          "400": {
            "description": "`MISSING_GITHUB_FIELDS` — token and repositoryFullName are required\n`INVALID_SYNC_DIRECTION` — syncDirection must be \"totalum_to_github\" or \"github_to_totalum\"\n`GITHUB_VALIDATION_FAILED` — Token invalid, missing permissions, or repo not found\n`GITHUB_SYNC_FAILED` — Initial sync with GitHub failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "errors": {
                    "errorCode": "MISSING_GITHUB_FIELDS",
                    "errorMessage": "token and repositoryFullName are required"
                  },
                  "data": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "`PLATFORM_CAPABILITY_QUOTA_REACHED` — GitHub sync is not included on your plan",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "`AGENT_RUNNING` — Cannot connect while agent is running",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "disconnectGithub",
        "summary": "Disconnect GitHub",
        "description": "Remove the GitHub integration from your project. Deletes the stored token and repository credentials. Code already in your project is not affected.\n\nFull reference: https://www.totalum.app/docs/api/github#disconnect-github",
        "tags": [
          "GitHub"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project ID"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Disconnect GitHub — Totalum docs",
          "url": "https://www.totalum.app/docs/api/github#disconnect-github"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "success": {
                          "type": "boolean",
                          "description": "true on success"
                        },
                        "message": {
                          "type": "string",
                          "description": "Confirmation message"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "success": true,
                    "message": "GitHub disconnected successfully"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`GITHUB_NOT_CONNECTED` — GitHub is not connected to this project",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "errors": {
                    "errorCode": "GITHUB_NOT_CONNECTED",
                    "errorMessage": "GitHub is not connected to this project"
                  },
                  "data": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/github/status": {
      "get": {
        "operationId": "getGithubStatus",
        "summary": "Get GitHub Status",
        "description": "Check whether GitHub is connected and the token is still valid.\n\nFull reference: https://www.totalum.app/docs/api/github#get-github-status",
        "tags": [
          "GitHub"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project ID"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get GitHub Status — Totalum docs",
          "url": "https://www.totalum.app/docs/api/github#get-github-status"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "connected": {
                          "type": "boolean",
                          "description": "Whether GitHub is connected"
                        },
                        "tokenValid": {
                          "type": "boolean",
                          "description": "Whether the PAT token is still valid"
                        },
                        "tokenExpired": {
                          "type": "boolean",
                          "description": "True when the last linked PAT was detected as expired/revoked. Sticky until the user reconnects. Use this to prompt the user to reconnect"
                        },
                        "repositoryFullName": {
                          "type": "string",
                          "description": "Connected repository, or last-known repo when tokenExpired is true"
                        },
                        "developBranch": {
                          "type": "string",
                          "description": "\"develop\" (only if connected)"
                        },
                        "productionBranch": {
                          "type": "string",
                          "description": "\"main\" (only if connected)"
                        },
                        "lastPushAt": {
                          "type": "string",
                          "description": "When Totalum last pushed to GitHub"
                        },
                        "lastPushSha": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "The commit it pushed"
                        },
                        "needsReconnect": {
                          "type": "boolean",
                          "description": "true when the token must be replaced (connect again)"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "connected": true,
                    "tokenValid": true,
                    "tokenExpired": false,
                    "repositoryFullName": "myuser/my-repo",
                    "developBranch": "develop",
                    "productionBranch": "main"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/github/pull": {
      "post": {
        "operationId": "pullFromGithub",
        "summary": "Pull from GitHub",
        "description": "Pull the latest changes from the GitHub develop branch into your project. If files changed, the server rebuilds automatically in the background. Poll the pull status endpoint until complete. This is an async operation.\n\nFull reference: https://www.totalum.app/docs/api/github#pull-from-github",
        "tags": [
          "GitHub"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project ID"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Pull from GitHub — Totalum docs",
          "url": "https://www.totalum.app/docs/api/github#pull-from-github"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string",
                          "description": "\"pulling\" (async rebuild started) or \"no_changes\""
                        },
                        "message": {
                          "type": "string",
                          "description": "Status message"
                        },
                        "filesUpdated": {
                          "type": "number",
                          "description": "Number of files updated"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "status": "pulling",
                    "message": "Pull started successfully",
                    "filesUpdated": 5
                  }
                }
              }
            }
          },
          "400": {
            "description": "`GITHUB_NOT_CONNECTED` — GitHub is not connected (connect first)\n`GITHUB_PULL_ERROR` — Failed to pull changes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "errors": {
                    "errorCode": "GITHUB_NOT_CONNECTED",
                    "errorMessage": "GitHub is not connected (connect first)"
                  },
                  "data": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "`PLATFORM_CAPABILITY_QUOTA_REACHED` — GitHub sync is not included on your plan",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "`AGENT_RUNNING` — Cannot pull while agent is running",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/github/pull-status": {
      "get": {
        "operationId": "getPullStatus",
        "summary": "Get Pull Status",
        "description": "Poll this endpoint after calling Pull from GitHub, OR after a Connect GitHub call that returned requiresRebuild: true (e.g. github_to_totalum direction). Returns the current rebuild status. Auto-completes after 10 minutes.\n\nFull reference: https://www.totalum.app/docs/api/github#get-pull-status",
        "tags": [
          "GitHub"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project ID"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Pull Status — Totalum docs",
          "url": "https://www.totalum.app/docs/api/github#get-pull-status"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string",
                          "description": "\"pulling\", \"success\", \"error\", or null (no pull)"
                        },
                        "createdAt": {
                          "type": "string",
                          "description": "ISO 8601 date when the pull started"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "status": "success",
                    "createdAt": "2026-03-17T10:00:00.000Z"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/github/env": {
      "get": {
        "operationId": "downloadEnvironmentVariables",
        "summary": "Download Environment Variables",
        "description": "Get the project's environment variables as .env file content for both development and production environments. Use this to set up a local development environment or configure production deployments.\n\nFull reference: https://www.totalum.app/docs/api/github#download-environment-variables",
        "tags": [
          "GitHub"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project ID"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Download Environment Variables — Totalum docs",
          "url": "https://www.totalum.app/docs/api/github#download-environment-variables"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "envDev": {
                          "type": "string",
                          "description": ".env file content for development (KEY=VALUE format, one per line)"
                        },
                        "envProd": {
                          "type": "string",
                          "description": ".env file content for production (KEY=VALUE format, one per line)"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "envDev": "TOTALUM_ENV=dev\nTOTALUM_PROJECT_KEY=tlm_pk_xxx\nBETTER_AUTH_SECRET=xxxx\nNEXT_PUBLIC_APP_URL=http://localhost:3100\n...",
                    "envProd": "TOTALUM_ENV=live\nTOTALUM_PROJECT_KEY=tlm_pk_xxx\nBETTER_AUTH_SECRET=xxxx\nNEXT_PUBLIC_APP_URL=https://my-app.totalum-project.com\n..."
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "`PLATFORM_CAPABILITY_QUOTA_REACHED` — Source download is not included on your plan",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "`PROJECT_NOT_READY` — The project is still being set up; retry after Retry-After seconds",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/figma/connect": {
      "post": {
        "operationId": "connectFigma",
        "summary": "Connect Figma",
        "description": "Link a Figma account to the project. The token is checked with Figma before anything is stored. Launch Project also takes figma.token.\n\nFull reference: https://www.totalum.app/docs/api/figma#connect-figma",
        "tags": [
          "Figma"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "token": {
                    "type": "string",
                    "description": "Figma personal or plan access token"
                  }
                },
                "required": [
                  "token"
                ],
                "additionalProperties": true
              },
              "example": {
                "token": "figd_xxx"
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Connect Figma — Totalum docs",
          "url": "https://www.totalum.app/docs/api/figma#connect-figma"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "connected": {
                          "type": "boolean",
                          "description": "true"
                        },
                        "account": {
                          "type": "object",
                          "description": "{ id, handle, email?, imgUrl? } of the Figma account",
                          "additionalProperties": true
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "connected": true,
                    "account": {
                      "id": "123456",
                      "handle": "Ada Lovelace",
                      "email": "ada@example.com",
                      "imgUrl": "https://s3-alpha.figma.com/profile/…"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`MISSING_FIGMA_TOKEN` — token is missing\n`FIGMA_TOKEN_MALFORMED` — Not a Figma token (whitespace, a URL, too short)\n`FIGMA_TOKEN_INVALID` — Figma rejected it: wrong, expired or revoked\n`FIGMA_TOKEN_FORBIDDEN` — Missing the current_user:read / file_content:read scopes\n`FIGMA_RATE_LIMITED` — Figma is rate-limiting; retry shortly\n`FIGMA_UNREACHABLE` — Figma could not be reached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "409": {
            "description": "`AGENT_RUNNING` — A prompt is running",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "disconnectFigma",
        "summary": "Disconnect Figma",
        "description": "Remove the Figma connection (nothing changes in your Figma account). Calling it on a project that is not connected also answers 200.\n\nFull reference: https://www.totalum.app/docs/api/figma#disconnect-figma",
        "tags": [
          "Figma"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Disconnect Figma — Totalum docs",
          "url": "https://www.totalum.app/docs/api/figma#disconnect-figma"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "disconnected": {
                          "type": "boolean",
                          "description": "true"
                        },
                        "message": {
                          "type": "string",
                          "description": "Confirmation"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "disconnected": true,
                    "message": "Figma disconnected successfully"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/figma/validate": {
      "post": {
        "operationId": "checkAFigmaToken",
        "summary": "Check a Figma Token",
        "description": "Check a token without connecting it — for a connect form. 10 checks a minute per account.\n\nFull reference: https://www.totalum.app/docs/api/figma#check-a-figma-token",
        "tags": [
          "Figma"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "token": {
                    "type": "string",
                    "description": "The token"
                  }
                },
                "required": [
                  "token"
                ],
                "additionalProperties": true
              },
              "example": {
                "token": "figd_xxx"
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Check a Figma Token — Totalum docs",
          "url": "https://www.totalum.app/docs/api/figma#check-a-figma-token"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "valid": {
                          "type": "boolean",
                          "description": "true"
                        },
                        "account": {
                          "type": "object",
                          "description": "{ id, handle, email?, imgUrl? }",
                          "additionalProperties": true
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "valid": true,
                    "account": {
                      "id": "123456",
                      "handle": "Ada Lovelace",
                      "email": "ada@example.com"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`FIGMA_TOKEN_MISSING` — No token\n`FIGMA_TOKEN_MALFORMED / FIGMA_TOKEN_INVALID / FIGMA_TOKEN_FORBIDDEN / FIGMA_RATE_LIMITED / FIGMA_UNREACHABLE` — As in Connect Figma",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "429": {
            "description": "`RATE_LIMITED` — More than 10 checks a minute",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/figma/status": {
      "get": {
        "operationId": "getFigmaStatus",
        "summary": "Get Figma Status",
        "description": "Whether Figma is connected, and to which account. A failed re-check never disconnects it.\n\nFull reference: https://www.totalum.app/docs/api/figma#get-figma-status",
        "tags": [
          "Figma"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          },
          {
            "name": "verify",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "true re-checks the token with Figma (a live call: on screen open, not in a poll)"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Figma Status — Totalum docs",
          "url": "https://www.totalum.app/docs/api/figma#get-figma-status"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "connected": {
                          "type": "boolean",
                          "description": "Connected"
                        },
                        "account": {
                          "type": "object",
                          "description": "{ id, handle, email?, imgUrl? }",
                          "additionalProperties": true
                        },
                        "connectedAt": {
                          "type": "string",
                          "description": "When it was connected"
                        },
                        "tokenValid": {
                          "type": "boolean",
                          "description": "With verify=true: Figma still accepts the token"
                        },
                        "tokenError": {
                          "type": "string",
                          "description": "With verify=true: why it failed"
                        },
                        "expiresAt": {
                          "type": "string",
                          "description": "Token expiry, when known"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "connected": true,
                    "account": {
                      "id": "123456",
                      "handle": "Ada Lovelace"
                    },
                    "connectedAt": "2026-10-08T10:24:00.000Z",
                    "tokenValid": true
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/visual-edit/apply": {
      "post": {
        "operationId": "applyVisualEdit",
        "summary": "Apply Visual Edit",
        "description": "Apply a batch. Answers 202; follow it with Get Visual Edit. Sending the same batchId again returns the same result without a second charge.\n\nFull reference: https://www.totalum.app/docs/api/visual-edit#apply-visual-edit",
        "tags": [
          "Visual Edits"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "batchId": {
                    "type": "string",
                    "description": "A UUID you generate (the idempotency key)"
                  },
                  "baseVersionId": {
                    "type": "string",
                    "description": "The version the preview showed"
                  },
                  "changes": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "loc": {
                          "type": "string",
                          "description": "The element's data-tlm-loc (path:line:column)"
                        },
                        "kind": {
                          "type": "string",
                          "description": "\"text\", \"style\", \"image\", \"link\", \"visibility\" or \"delete\""
                        },
                        "before": {
                          "type": [
                            "string",
                            "object"
                          ],
                          "description": "The current value (text, classes, src or href)",
                          "additionalProperties": true
                        },
                        "after": {
                          "type": [
                            "string",
                            "object",
                            "null"
                          ],
                          "description": "text: the new text · style: { add?, remove?, replace? } of Tailwind classes · image: { src, alt? } · link: { href, target? } · visibility: { hidden } · delete: null",
                          "additionalProperties": true
                        },
                        "id": {
                          "type": "string",
                          "description": "Your id for the change"
                        }
                      },
                      "required": [
                        "loc",
                        "kind",
                        "after"
                      ],
                      "additionalProperties": true
                    },
                    "description": "1–200 changes"
                  }
                },
                "required": [
                  "batchId",
                  "baseVersionId",
                  "changes"
                ],
                "additionalProperties": true
              },
              "example": {
                "batchId": "5f0c2e1a-8d3b-4c6e-9a7f-1b2c3d4e5f60",
                "baseVersionId": "ver_01k6xd2m8q",
                "changes": [
                  {
                    "loc": "src/app/page.tsx:14:7",
                    "kind": "text",
                    "before": "Book now",
                    "after": "Book your cut"
                  }
                ]
              }
            }
          }
        },
        "x-totalum-cost": "0.6 credits",
        "externalDocs": {
          "description": "Apply Visual Edit — Totalum docs",
          "url": "https://www.totalum.app/docs/api/visual-edit#apply-visual-edit"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "batchId": {
                          "type": "string",
                          "description": "The batch"
                        },
                        "versionId": {
                          "type": "string",
                          "description": "The version being saved"
                        },
                        "operation": {
                          "type": "object",
                          "description": "{ kind: \"visualEdit\", id, status: \"building\" }",
                          "additionalProperties": true
                        },
                        "creditsCharged": {
                          "type": "number",
                          "description": "0.6 the first time, 0 on a repeat"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "batchId": "5f0c2e1a-8d3b-4c6e-9a7f-1b2c3d4e5f60",
                    "versionId": "ver_01k6y6",
                    "operation": {
                      "kind": "visualEdit",
                      "id": "op_01k6y7",
                      "status": "building"
                    },
                    "creditsCharged": 0.6
                  }
                }
              }
            }
          },
          "400": {
            "description": "`VALIDATION_ERROR` — batchId is not a UUID, or a change is invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "`INSUFFICIENT_CREDITS` — Not enough credits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "`FREE_PLAN_NO_SOURCE_EDITING` — Editing code needs a paid plan",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "`BATCH_ID_IN_USE` — The batchId belongs to another project\n`AGENT_RUNNING` — A prompt is running",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/projects/{projectId}/visual-edit/{batchId}": {
      "get": {
        "operationId": "getVisualEdit",
        "summary": "Get Visual Edit",
        "description": "Whether a batch was saved. A batch that failed before it was saved is refunded.\n\nFull reference: https://www.totalum.app/docs/api/visual-edit#get-visual-edit",
        "tags": [
          "Visual Edits"
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The project id"
          },
          {
            "name": "batchId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The batch"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Visual Edit — Totalum docs",
          "url": "https://www.totalum.app/docs/api/visual-edit#get-visual-edit"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "batchId": {
                          "type": "string",
                          "description": "The batch"
                        },
                        "versionId": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Its version"
                        },
                        "state": {
                          "type": "string",
                          "description": "\"saving\", \"saved\" or \"failed\""
                        },
                        "errorCode": {
                          "type": "string",
                          "description": "On failure, e.g. VISUAL_EDIT_NOT_PATCHABLE, VISUAL_EDIT_TYPECHECK_FAILED, VISUAL_EDIT_BASE_MISMATCH (the file changed since baseVersionId)"
                        },
                        "errorMessage": {
                          "type": "string",
                          "description": "On failure"
                        },
                        "refunded": {
                          "type": "boolean",
                          "description": "The credits were given back"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "batchId": "5f0c2e1a-8d3b-4c6e-9a7f-1b2c3d4e5f60",
                    "versionId": "ver_01k6y6",
                    "state": "saved",
                    "refunded": false
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "404": {
            "description": "`VISUAL_EDIT_NOT_FOUND` — No such batch on this project",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/project-groups": {
      "post": {
        "operationId": "createProjectGroup",
        "summary": "Create Project Group",
        "description": "Create a folder for projects.\n\nFull reference: https://www.totalum.app/docs/api/project-groups#create-project-group",
        "tags": [
          "Project Groups"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Trimmed, up to 80 characters. Required — an empty name is rejected"
                  },
                  "description": {
                    "type": "string",
                    "description": "Trimmed and truncated to 500 characters rather than rejected"
                  }
                },
                "required": [
                  "name"
                ],
                "additionalProperties": true
              },
              "example": {
                "name": "Client work",
                "description": "Everything billed to clients"
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Create Project Group — Totalum docs",
          "url": "https://www.totalum.app/docs/api/project-groups#create-project-group"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "groupId": {
                          "type": "string",
                          "description": "The new group's ID — use this as groupId elsewhere"
                        },
                        "name": {
                          "type": "string",
                          "description": "The group name"
                        },
                        "description": {
                          "type": "string",
                          "description": "The description, or an empty string when none was given"
                        },
                        "createdAt": {
                          "type": "string",
                          "description": "ISO 8601 creation date"
                        },
                        "updatedAt": {
                          "type": "string",
                          "description": "ISO 8601 last-modified date"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "groupId": "65f1a2b3c4d5e6f7a8b9c0d1",
                    "name": "Client work",
                    "description": "Everything billed to clients",
                    "createdAt": "2026-08-04T10:00:00.000Z",
                    "updatedAt": "2026-08-04T10:00:00.000Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`CREATE_PROJECT_GROUP_ERROR` — Name missing or longer than 80 characters, or the account already has 3,000 groups",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "errors": {
                    "errorCode": "CREATE_PROJECT_GROUP_ERROR",
                    "errorMessage": "Group name is required"
                  },
                  "data": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      },
      "get": {
        "operationId": "listProjectGroups",
        "summary": "List Project Groups",
        "description": "Your groups, newest first, each with the number of projects currently filed under it.\n\nFull reference: https://www.totalum.app/docs/api/project-groups#list-project-groups",
        "tags": [
          "Project Groups"
        ],
        "parameters": [
          {
            "name": "search",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Case-insensitive match on the group name only"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number"
            },
            "description": "Page size, default 100, maximum 200"
          },
          {
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number"
            },
            "description": "Groups to skip, for paging (default: 0)"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "List Project Groups — Totalum docs",
          "url": "https://www.totalum.app/docs/api/project-groups#list-project-groups"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "array",
                      "description": "Array of group objects, newest first",
                      "items": {
                        "type": "object",
                        "properties": {
                          "groupId": {
                            "type": "string",
                            "description": "The group ID"
                          },
                          "name": {
                            "type": "string",
                            "description": "The group name"
                          },
                          "description": {
                            "type": "string",
                            "description": "The description, or an empty string"
                          },
                          "createdAt": {
                            "type": "string",
                            "description": "ISO 8601 creation date"
                          },
                          "updatedAt": {
                            "type": "string",
                            "description": "ISO 8601 last-modified date"
                          },
                          "projectCount": {
                            "type": "number",
                            "description": "How many of your projects are filed under this group"
                          }
                        },
                        "additionalProperties": true
                      }
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": [
                    {
                      "groupId": "65f1a2b3c4d5e6f7a8b9c0d1",
                      "name": "Client work",
                      "description": "Everything billed to clients",
                      "createdAt": "2026-08-04T10:00:00.000Z",
                      "updatedAt": "2026-08-04T10:00:00.000Z",
                      "projectCount": 12
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "`LIST_PROJECT_GROUPS_ERROR` — Internal error listing project groups",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "errors": {
                    "errorCode": "LIST_PROJECT_GROUPS_ERROR",
                    "errorMessage": "Error listing project groups"
                  },
                  "data": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/project-groups/{groupId}": {
      "get": {
        "operationId": "getProjectGroup",
        "summary": "Get Project Group",
        "description": "One group, with its current project count.\n\nFull reference: https://www.totalum.app/docs/api/project-groups#get-project-group",
        "tags": [
          "Project Groups"
        ],
        "parameters": [
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The group ID"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Project Group — Totalum docs",
          "url": "https://www.totalum.app/docs/api/project-groups#get-project-group"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "groupId": {
                          "type": "string",
                          "description": "The group ID"
                        },
                        "name": {
                          "type": "string",
                          "description": "The group name"
                        },
                        "description": {
                          "type": "string",
                          "description": "The description, or an empty string"
                        },
                        "createdAt": {
                          "type": "string",
                          "description": "ISO 8601 creation date"
                        },
                        "updatedAt": {
                          "type": "string",
                          "description": "ISO 8601 last-modified date"
                        },
                        "projectCount": {
                          "type": "number",
                          "description": "How many of your projects are filed under this group"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "groupId": "65f1a2b3c4d5e6f7a8b9c0d1",
                    "name": "Client work",
                    "description": "",
                    "createdAt": "2026-08-04T10:00:00.000Z",
                    "updatedAt": "2026-08-04T10:00:00.000Z",
                    "projectCount": 12
                  }
                }
              }
            }
          },
          "400": {
            "description": "`GET_PROJECT_GROUP_ERROR` — Internal error getting the project group",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "404": {
            "description": "`PROJECT_GROUP_NOT_FOUND` — No such group, the id is malformed, or it is not yours",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "errors": {
                    "errorCode": "PROJECT_GROUP_NOT_FOUND",
                    "errorMessage": "Project group not found"
                  },
                  "data": null
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateProjectGroup",
        "summary": "Update Project Group",
        "description": "Rename a group or change its description. Keys you do not send are left alone, so renaming a group cannot blank its description.\n\nFull reference: https://www.totalum.app/docs/api/project-groups#update-project-group",
        "tags": [
          "Project Groups"
        ],
        "parameters": [
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The group ID"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Trimmed, up to 80 characters. Sending an empty name is an error — omit the key instead"
                  },
                  "description": {
                    "type": "string",
                    "description": "Trimmed and truncated to 500 characters. Send an empty string to clear it"
                  }
                },
                "additionalProperties": true
              },
              "example": {
                "name": "Client work 2026"
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Update Project Group — Totalum docs",
          "url": "https://www.totalum.app/docs/api/project-groups#update-project-group"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "groupId": {
                          "type": "string",
                          "description": "The group ID"
                        },
                        "name": {
                          "type": "string",
                          "description": "The name after the update"
                        },
                        "description": {
                          "type": "string",
                          "description": "The description after the update"
                        },
                        "createdAt": {
                          "type": "string",
                          "description": "ISO 8601 creation date"
                        },
                        "updatedAt": {
                          "type": "string",
                          "description": "ISO 8601 last-modified date"
                        },
                        "projectCount": {
                          "type": "number",
                          "description": "How many of your projects are filed under this group"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "groupId": "65f1a2b3c4d5e6f7a8b9c0d1",
                    "name": "Client work 2026",
                    "description": "Everything billed to clients",
                    "createdAt": "2026-08-04T10:00:00.000Z",
                    "updatedAt": "2026-08-04T12:30:00.000Z",
                    "projectCount": 12
                  }
                }
              }
            }
          },
          "400": {
            "description": "`UPDATE_PROJECT_GROUP_ERROR` — Empty name, name longer than 80 characters, or an internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "404": {
            "description": "`PROJECT_GROUP_NOT_FOUND` — No such group, the id is malformed, or it is not yours",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "errors": {
                    "errorCode": "PROJECT_GROUP_NOT_FOUND",
                    "errorMessage": "Project group not found"
                  },
                  "data": null
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteProjectGroup",
        "summary": "Delete Project Group",
        "description": "Delete the folder only.\n\nFull reference: https://www.totalum.app/docs/api/project-groups#delete-project-group",
        "tags": [
          "Project Groups"
        ],
        "parameters": [
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The group ID"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Delete Project Group — Totalum docs",
          "url": "https://www.totalum.app/docs/api/project-groups#delete-project-group"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "deleted": {
                          "type": "boolean",
                          "description": "true on successful deletion"
                        },
                        "releasedProjects": {
                          "type": "number",
                          "description": "How many projects became ungrouped. None were deleted"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "deleted": true,
                    "releasedProjects": 12
                  }
                }
              }
            }
          },
          "400": {
            "description": "`DELETE_PROJECT_GROUP_ERROR` — Internal error deleting the project group",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "404": {
            "description": "`PROJECT_GROUP_NOT_FOUND` — No such group, the id is malformed, or it is not yours",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "errors": {
                    "errorCode": "PROJECT_GROUP_NOT_FOUND",
                    "errorMessage": "Project group not found"
                  },
                  "data": null
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/account": {
      "get": {
        "operationId": "getAccountInfo",
        "summary": "Get Account Info",
        "description": "Your spendable credit balance. Check it before a large batch of prompts.\n\nFull reference: https://www.totalum.app/docs/api/account#get-account-info",
        "tags": [
          "Account"
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Account Info — Totalum docs",
          "url": "https://www.totalum.app/docs/api/account#get-account-info"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "credits": {
                          "type": "number",
                          "description": "Total spendable balance (recurrentCredits + oneTimeCredits)"
                        },
                        "recurrentCredits": {
                          "type": "number",
                          "description": "Plan credits left this billing period (used first)"
                        },
                        "oneTimeCredits": {
                          "type": "number",
                          "description": "Purchased credits (never expire)"
                        },
                        "engineOptIn": {
                          "type": "object",
                          "description": "{ eligible, mode }: whether new projects can be created with engineVersion: \"v2\"",
                          "additionalProperties": true
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "credits": 425.5,
                    "recurrentCredits": 100,
                    "oneTimeCredits": 325.5,
                    "engineOptIn": {
                      "eligible": true,
                      "mode": "default"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          },
          "503": {
            "description": "`ACCOUNT_SERVICE_UNAVAILABLE` — The balance cannot be read right now; retry in a few minutes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vcaas/credit-costs": {
      "get": {
        "operationId": "getCreditCosts",
        "summary": "Get Credit Costs",
        "description": "The price in credits of every fixed-price action, and the monthly fees. Read it at runtime instead of hard-coding prices. Prompts are not listed: they are metered (at least 3 credits each). The app's own usage (hosting, database, AI, e-mail…) is metered too: see Usage & Analytics.\n\nFull reference: https://www.totalum.app/docs/api/account#get-credit-costs",
        "tags": [
          "Account"
        ],
        "parameters": [
          {
            "name": "engine",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "v2 (default for new accounts)"
          }
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Credit Costs — Totalum docs",
          "url": "https://www.totalum.app/docs/api/account#get-credit-costs"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "creditCosts": {
                          "type": "object",
                          "properties": {
                            "CREATE_PROJECT": {
                              "type": "number",
                              "description": "Creating a project"
                            },
                            "CREATE_DEPLOYMENT": {
                              "type": "number",
                              "description": "Publishing"
                            },
                            "START_SERVER": {
                              "type": "number",
                              "description": "Restarting the development environment"
                            },
                            "GET_SOURCE_CODE": {
                              "type": "number",
                              "description": "Downloading the source code"
                            },
                            "RECOVER_VERSION": {
                              "type": "number",
                              "description": "Restoring a version"
                            },
                            "UPLOAD_FILE": {
                              "type": "number",
                              "description": "Uploading a file (free)"
                            },
                            "ADD_CUSTOM_DOMAIN": {
                              "type": "number",
                              "description": "Adding a custom domain"
                            },
                            "EXPORT_PROJECT": {
                              "type": "number",
                              "description": "Exporting a project"
                            },
                            "IMPORT_PROJECT": {
                              "type": "number",
                              "description": "Importing a project"
                            },
                            "UPDATE_FILE": {
                              "type": "number",
                              "description": "Writing a file (free)"
                            },
                            "REBUILD_PROJECT": {
                              "type": "number",
                              "description": "Rebuilding the preview"
                            },
                            "BACKUP_CREATE_MANUAL": {
                              "type": "number",
                              "description": "A manual database backup"
                            },
                            "BACKUP_RESTORE": {
                              "type": "number",
                              "description": "Restoring a backup or a point in time"
                            },
                            "VISUAL_EDIT_APPLY": {
                              "type": "number",
                              "description": "Applying a visual-edit batch"
                            },
                            "PAUSE_RESUME": {
                              "type": "number",
                              "description": "Pausing, or resuming, a project"
                            },
                            "MONTHLY_PROJECT_FEE": {
                              "type": "number",
                              "description": "A month a project is published on a paid plan"
                            },
                            "MONTHLY_HOSTING_FEE": {
                              "type": "number",
                              "description": "That project's hosting, the same month"
                            },
                            "MONTHLY_CUSTOM_DOMAIN_FEE": {
                              "type": "number",
                              "description": "A month a custom domain is active"
                            }
                          },
                          "additionalProperties": true
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "creditCosts": {
                      "CREATE_PROJECT": 2,
                      "CREATE_DEPLOYMENT": 0.5,
                      "START_SERVER": 2,
                      "GET_SOURCE_CODE": 2,
                      "RECOVER_VERSION": 2,
                      "UPLOAD_FILE": 0,
                      "ADD_CUSTOM_DOMAIN": 4,
                      "EXPORT_PROJECT": 4,
                      "IMPORT_PROJECT": 12,
                      "UPDATE_FILE": 0,
                      "REBUILD_PROJECT": 2,
                      "BACKUP_CREATE_MANUAL": 2,
                      "BACKUP_RESTORE": 4,
                      "VISUAL_EDIT_APPLY": 0.6,
                      "PAUSE_RESUME": 2,
                      "MONTHLY_PROJECT_FEE": 1,
                      "MONTHLY_HOSTING_FEE": 2,
                      "MONTHLY_CUSTOM_DOMAIN_FEE": 3
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      }
    },
    "/api/v1/vcaas/account/data-residency": {
      "get": {
        "operationId": "getDataResidency",
        "summary": "Get Data Residency",
        "description": "The account's default for new projects: global (each database placed nearest its users, with read copies elsewhere) or eu (databases created and kept inside the European Union only).\n\nFull reference: https://www.totalum.app/docs/api/account#get-data-residency",
        "tags": [
          "Account"
        ],
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Get Data Residency — Totalum docs",
          "url": "https://www.totalum.app/docs/api/account#get-data-residency"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "dataResidency": {
                          "type": "string",
                          "description": "\"global\" or \"eu\""
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "dataResidency": "global"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/NoCredits"
          }
        }
      },
      "put": {
        "operationId": "setDataResidency",
        "summary": "Set Data Residency",
        "description": "Set the default for projects created from now on. Existing projects never move; a project's own dataResidency on create or launch wins. A key restricted to some projects cannot change it.\n\nFull reference: https://www.totalum.app/docs/api/account#set-data-residency",
        "tags": [
          "Account"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "dataResidency": {
                    "type": "string",
                    "description": "\"global\" or \"eu\""
                  }
                },
                "required": [
                  "dataResidency"
                ],
                "additionalProperties": true
              },
              "example": {
                "dataResidency": "eu"
              }
            }
          }
        },
        "x-totalum-cost": "Free",
        "externalDocs": {
          "description": "Set Data Residency — Totalum docs",
          "url": "https://www.totalum.app/docs/api/account#set-data-residency"
        },
        "responses": {
          "200": {
            "description": "Success. `errors` is null and `data` holds the result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "null",
                      "description": "Null on success."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "dataResidency": {
                          "type": "string",
                          "description": "The new default"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "errors": null,
                  "data": {
                    "dataResidency": "eu"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`INVALID_DATA_RESIDENCY` — Not \"global\" or \"eu\"",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "`API_KEY_SCOPE_FORBIDDEN` — This key cannot change account settings",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "api-key",
        "description": "Your Totalum API key, prefixed `tlm_sk_`. Server-side only."
      }
    },
    "schemas": {
      "ErrorEnvelope": {
        "type": "object",
        "description": "A failed request: `data` is null and `errors` holds the code and message.",
        "properties": {
          "errors": {
            "$ref": "#/components/schemas/ApiError"
          },
          "data": {
            "type": "null"
          }
        },
        "required": [
          "errors"
        ]
      },
      "ApiError": {
        "type": "object",
        "properties": {
          "errorCode": {
            "type": "string",
            "examples": [
              "PROJECT_NOT_FOUND"
            ]
          },
          "errorMessage": {
            "type": "string",
            "examples": [
              "Project does not exist or you don't own it"
            ]
          }
        },
        "required": [
          "errorCode",
          "errorMessage"
        ]
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Missing or invalid `api-key` header. Note this is the one response that does NOT use the `{ errors, data }` envelope — it returns a bare `{ error }` string, so clients should branch on the status code rather than only checking `errors`.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "error": {
                  "type": "string"
                }
              },
              "required": [
                "error"
              ],
              "additionalProperties": true
            },
            "example": {
              "error": "Unauthorized api key"
            }
          }
        }
      },
      "NoCredits": {
        "description": "Credit balance is zero. The API requires a positive balance on every plan (`VCAAS_INSUFFICIENT_CREDITS`).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            }
          }
        }
      }
    }
  }
}