Skip to content

Verception API docs

Deploy apps, run sandboxes, and call AI models with the Verception REST API, OAuth 2.0, and the MCP server.

Updated

What can the Verception API do?

The Verception REST API does each action of the dashboard: projects, deployments, environment variables, domains, stores, Git, the project chat, sandboxes, and AI models. The dashboard uses the same endpoints.

  • Base URL: https://vercel-on.vercel.app/api/v1
  • Request and response bodies are JSON. Timestamps are ISO 8601 strings in UTC
  • OpenAPI 3.1 document: /openapi.json, with an operation ID, a description, and a scope for each operation
  • MCP server: https://vercel-on.vercel.app/mcp, with one tool for each operation
  • Agent index: /llms.txt. Each public page also has a Markdown copy, such as /docs.md

When should an agent use Verception?

Use Verception when a task needs one of these jobs:

  • Put a folder, generated code, or a GitHub repository on a public HTTPS URL
  • Get a preview URL for a change, then promote it to production or roll it back
  • Run code that you do not trust in an isolated Linux sandbox, and open its ports on a public URL
  • Call AI models from many providers in the OpenAI format with one API key
  • Serve an app on a custom subdomain with automatic HTTPS

Verception is a free experiment with small limits: 5 projects and 50 deployments a day for each account. Use a different platform for large production traffic, apex domains, or data that must stay in one region.

How do I start?

  • Free tier: every account is free while the experiment runs. No credit card
  • Self-serve sign-up: create an account at /signup with an email, a username, and a password
  • Self-serve keys: create an API key in the account settings, or with POST /v1/user/api-keys. An agent can also get a key with the OAuth sign-in
  • Test environment: each preview deployment is a test copy of an app, and each sandbox is an isolated machine that you can delete at any time

How do I authenticate?

Send an API key or an OAuth access token in the Authorization header. A request with no valid token gets 401 with a WWW-Authenticate header that names the OAuth metadata.

curl https://vercel-on.vercel.app/api/v1/user \
  -H "Authorization: Bearer $VERCEPTION_API_KEY"

Each key and each token has scopes. A request without the scope that it needs gets 403 insufficient_scope.

ScopeWhat it allows
readRead your account, projects, deployments, domains, sandboxes, and AI usage (GET requests only).
writeCreate, change, and delete projects, deployments, env vars, domains, stores, and sandboxes, and call AI models.

OAuth 2.0: Verception is an authorization server for the authorization code flow with PKCE (S256). A client registers itself with dynamic client registration, so it needs no client secret. An access token works for 30 days, and the user can revoke it in the account settings.

Document or endpointURL
Authorization server metadata (RFC 8414)https://vercel-on.vercel.app/.well-known/oauth-authorization-server
Protected resource metadata (RFC 9728)https://vercel-on.vercel.app/.well-known/oauth-protected-resource
Authorizationhttps://vercel-on.vercel.app/oauth/authorize
Tokenhttps://vercel-on.vercel.app/api/oauth/token
Client registration (RFC 7591)https://vercel-on.vercel.app/api/oauth/register
Token revocation (RFC 7009)https://vercel-on.vercel.app/api/oauth/revoke

How do I deploy a static site?

Create a project, upload each file by its SHA-1, then create a deployment from a manifest. The API answers 400 missing_files with the SHA-1 of each file that it does not have yet.

API=https://vercel-on.vercel.app/api/v1
AUTH="Authorization: Bearer $VERCEPTION_API_KEY"

curl -X POST $API/projects -H "$AUTH" \
  -H "Content-Type: application/json" -d '{"name":"hello"}'

echo "<h1>Hello</h1>" > index.html
SHA=$(shasum index.html | cut -d" " -f1)
curl -X POST $API/files -H "$AUTH" -H "x-sha: $SHA" \
  -H "Content-Type: application/octet-stream" --data-binary @index.html

curl -X POST $API/deployments -H "$AUTH" -H "Content-Type: application/json" \
  -d "{\"projectId\":\"proj_...\",\"target\":\"production\",\"files\":[{\"file\":\"index.html\",\"sha\":\"$SHA\",\"size\":15}]}"

Poll GET /v1/deployments/:id until readyState is READY or ERROR. Read the build log with GET /v1/deployments/:id/events.

What does an error look like?

Every error is JSON with a stable code and a message that tells what to do next. A 500 or a 502 also has a reference for a support request. An unknown path under /api also returns a JSON 404.

{ "error": { "code": "not_found", "message": "Project not found." } }
HTTPCodeWhen
400bad_requestThe body or the query does not match the schema. message names the field
400missing_filesA deployment names files that are not uploaded. The body adds missing
401unauthorizedNo valid API key, token, or session
403insufficient_scopeThe key or the token does not have the scope of the request
403forbiddenA browser sent a change from another site
404not_foundThe resource does not exist, or it belongs to another user
409conflictThe name is taken, or the state does not allow the action
413file_too_largeA file is larger than 4.0 MB
429limit_exceededA limit of the account is reached. message names the limit
429rate_limitedToo many requests of this kind. Wait for the seconds in retry-after
500internal_errorA bug in Verception
502upstream_errorThe hosting step failed. Try again later

Which limits apply?

LimitValue
Projects for each user5
Deployments for each user in one day50
API keys and OAuth tokens for each user20
File size4.0 MB
Files in one deployment5,000
Sandboxes for each user5
Chat messages for each user in one day20

Lists return the resource name as the key, such as { "projects": [...] }. The limits keep each list short, so lists have no pages.

How do I connect an MCP client?

Add https://vercel-on.vercel.app/mcp as a remote MCP server with the Streamable HTTP transport. The client lists the tools with no token. A tool call needs a token: the client gets one with the OAuth sign-in, or you send an API key as Authorization: Bearer <key>. Each tool is one operation of the API, with the same name as its operation ID.

{
  "mcpServers": {
    "verception": {
      "url": "https://vercel-on.vercel.app/mcp"
    }
  }
}

How does the API change?

Every path starts with /v1. Verception is an experiment, so a change can also change /v1. The OpenAPI document always shows the current API.

Which endpoints does the API have?

Each path follows the base URL. The scope column shows the scope that a key or a token needs.

MethodPathScopeWhat it does
GET``NoneLists the documents of the API: the docs, the OpenAPI document, the MCP server, and the OAuth metadata.
GET/healthNoneReports that the API serves requests.
GET/openapi.jsonNoneReturns the OpenAPI 3.1 document of the API, for client generators.
GET/userreadReturns the current user.
DELETE/userwriteStarts the delete of the account with all projects, deployments, domains, and API keys. Each credential stops at once, and the rest goes in the background. This cannot be undone.
GET/user/api-keysreadLists the API keys, without their secrets.
POST/user/api-keyswriteCreates an API key. The response is the only time the full key appears.
DELETE/user/api-keys/:idwriteRevokes an API key.
GET/projectsreadLists the projects.
POST/projectswriteCreates a project.
GET/projects/:idreadReturns a project.
PATCH/projects/:idwriteChanges the build settings for the next deployment. null sets buildCommand, outputDirectory, or rootDirectory to automatic, and framework to no framework.
DELETE/projects/:idwriteStarts the delete of the project with its deployments, env vars, stores, and domains. The project leaves the API at once, and its URLs stop when the background delete ends.
POST/fileswriteUploads the raw bytes of one file for a deployment manifest.
POST/deploymentswriteCreates a deployment from a file manifest, or builds the files of an earlier deployment again with fromDeploymentId.
GET/deploymentsreadLists the newest 50 deployments of one project.
GET/deployments/:idreadReturns a deployment. Poll it until readyState is READY, ERROR, or CANCELED.
GET/deployments/:id/eventsreadReturns the build output. since, an ISO 8601 time, returns only newer lines.
POST/projects/:id/promote/:deploymentIdwriteMakes a READY deployment serve production.
POST/projects/:id/rollback/:deploymentIdwriteMakes an earlier production deployment serve production again, with no build.
GET/projects/:id/gitreadReturns the connected repository, or null.
PUT/projects/:id/gitwriteConnects a repository, then deploys the head of its default branch to production.
POST/projects/:id/git/deploywriteDeploys the head of the default branch to production again.
DELETE/projects/:id/gitwriteDisconnects the repository. Old deployments stay.
DELETE/user/githubwriteDisconnects the GitHub account of the user.
GET/user/github/repositoriesreadLists the repositories that the GitHub account can read.
GET/projects/:id/envreadLists the env vars. Values are write-only and never return.
POST/projects/:id/envwriteAdds 1 to 100 env vars, all or none. They apply to the next deployment.
PATCH/projects/:id/env/:envIdwriteChanges the value, the targets, or both, of an env var.
DELETE/projects/:id/env/:envIdwriteDeletes an env var.
GET/projects/:id/storesreadLists the stores of a project.
POST/projects/:id/storeswriteAdds a Postgres database or file storage. Its env vars apply to the next deployment.
GET/projects/:id/stores/:storeIdreadReturns the live status and usage of a store.
DELETE/projects/:id/stores/:storeIdwriteDeletes a store, all of its data, and its env vars.
GET/projects/:id/domainsreadLists the domains of a project.
POST/projects/:id/domainswriteAdds a custom domain. The response has the DNS records that the user must create.
GET/projects/:id/domains/:domainreadReturns the DNS state of a domain and the missing records.
POST/projects/:id/domains/:domain/verifywriteVerifies a custom domain, then returns its state.
DELETE/projects/:id/domains/:domainwriteRemoves a custom domain.
GET/projects/:id/chatreadReturns the project chat as stored, or null.
POST/projects/:id/chat/refreshwriteChecks the code generator. A ready reply deploys its code as a preview. Send it while you poll.
POST/projects/:id/chat/messageswriteSends a message to the project chat, which writes code and deploys it as a preview.
GET/projects/:id/chat/filesreadReturns the files of the latest generated code.
POST/projects/:id/chat/deploywriteDeploys the latest generated code again, for example to production.
GET/sandboxesreadLists the sandboxes.
POST/sandboxeswriteCreates a sandbox and starts it. An empty body works.
GET/sandboxes/:idreadReturns a sandbox. It does not start a stopped sandbox.
POST/sandboxes/:id/stopwriteStops a sandbox. Its files stay.
POST/sandboxes/:id/startwriteStarts a stopped sandbox with its files.
DELETE/sandboxes/:idwriteDeletes a sandbox, its files, and its commands.
POST/sandboxes/:id/commandswriteRuns a command in bash and waits for its exit code and output, or starts it in the background.
GET/sandboxes/:id/commands/:commandIdreadReturns a command, with its exit code and output when it is done.
POST/sandboxes/:id/commands/:commandId/killwriteStops a running command.
POST/sandboxes/:id/terminalwriteOpens an interactive shell for the dashboard terminal.
PUT/sandboxes/:id/fileswriteWrites files in a sandbox. Send binary files as base64.
GET/sandboxes/:id/filesreadReturns the raw bytes of one file.
POST/ai/chat/completionswriteSends a chat to a model, in the OpenAI chat completions format. With "stream": true, the response is server-sent events.
GET/ai/modelsreadLists the chat models.
GET/ai/usagereadReturns the AI use and limits of the current UTC day.