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.
| Scope | What it allows |
|---|---|
read | Read your account, projects, deployments, domains, sandboxes, and AI usage (GET requests only). |
write | Create, 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 endpoint | URL |
|---|---|
| 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 |
| Authorization | https://vercel-on.vercel.app/oauth/authorize |
| Token | https://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." } }| HTTP | Code | When |
|---|---|---|
| 400 | bad_request | The body or the query does not match the schema. message names the field |
| 400 | missing_files | A deployment names files that are not uploaded. The body adds missing |
| 401 | unauthorized | No valid API key, token, or session |
| 403 | insufficient_scope | The key or the token does not have the scope of the request |
| 403 | forbidden | A browser sent a change from another site |
| 404 | not_found | The resource does not exist, or it belongs to another user |
| 409 | conflict | The name is taken, or the state does not allow the action |
| 413 | file_too_large | A file is larger than 4.0 MB |
| 429 | limit_exceeded | A limit of the account is reached. message names the limit |
| 429 | rate_limited | Too many requests of this kind. Wait for the seconds in retry-after |
| 500 | internal_error | A bug in Verception |
| 502 | upstream_error | The hosting step failed. Try again later |
Which limits apply?
| Limit | Value |
|---|---|
| Projects for each user | 5 |
| Deployments for each user in one day | 50 |
| API keys and OAuth tokens for each user | 20 |
| File size | 4.0 MB |
| Files in one deployment | 5,000 |
| Sandboxes for each user | 5 |
| Chat messages for each user in one day | 20 |
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.
| Method | Path | Scope | What it does |
|---|---|---|---|
| GET | `` | None | Lists the documents of the API: the docs, the OpenAPI document, the MCP server, and the OAuth metadata. |
| GET | /health | None | Reports that the API serves requests. |
| GET | /openapi.json | None | Returns the OpenAPI 3.1 document of the API, for client generators. |
| GET | /user | read | Returns the current user. |
| DELETE | /user | write | Starts 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-keys | read | Lists the API keys, without their secrets. |
| POST | /user/api-keys | write | Creates an API key. The response is the only time the full key appears. |
| DELETE | /user/api-keys/:id | write | Revokes an API key. |
| GET | /projects | read | Lists the projects. |
| POST | /projects | write | Creates a project. |
| GET | /projects/:id | read | Returns a project. |
| PATCH | /projects/:id | write | Changes the build settings for the next deployment. null sets buildCommand, outputDirectory, or rootDirectory to automatic, and framework to no framework. |
| DELETE | /projects/:id | write | Starts 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 | /files | write | Uploads the raw bytes of one file for a deployment manifest. |
| POST | /deployments | write | Creates a deployment from a file manifest, or builds the files of an earlier deployment again with fromDeploymentId. |
| GET | /deployments | read | Lists the newest 50 deployments of one project. |
| GET | /deployments/:id | read | Returns a deployment. Poll it until readyState is READY, ERROR, or CANCELED. |
| GET | /deployments/:id/events | read | Returns the build output. since, an ISO 8601 time, returns only newer lines. |
| POST | /projects/:id/promote/:deploymentId | write | Makes a READY deployment serve production. |
| POST | /projects/:id/rollback/:deploymentId | write | Makes an earlier production deployment serve production again, with no build. |
| GET | /projects/:id/git | read | Returns the connected repository, or null. |
| PUT | /projects/:id/git | write | Connects a repository, then deploys the head of its default branch to production. |
| POST | /projects/:id/git/deploy | write | Deploys the head of the default branch to production again. |
| DELETE | /projects/:id/git | write | Disconnects the repository. Old deployments stay. |
| DELETE | /user/github | write | Disconnects the GitHub account of the user. |
| GET | /user/github/repositories | read | Lists the repositories that the GitHub account can read. |
| GET | /projects/:id/env | read | Lists the env vars. Values are write-only and never return. |
| POST | /projects/:id/env | write | Adds 1 to 100 env vars, all or none. They apply to the next deployment. |
| PATCH | /projects/:id/env/:envId | write | Changes the value, the targets, or both, of an env var. |
| DELETE | /projects/:id/env/:envId | write | Deletes an env var. |
| GET | /projects/:id/stores | read | Lists the stores of a project. |
| POST | /projects/:id/stores | write | Adds a Postgres database or file storage. Its env vars apply to the next deployment. |
| GET | /projects/:id/stores/:storeId | read | Returns the live status and usage of a store. |
| DELETE | /projects/:id/stores/:storeId | write | Deletes a store, all of its data, and its env vars. |
| GET | /projects/:id/domains | read | Lists the domains of a project. |
| POST | /projects/:id/domains | write | Adds a custom domain. The response has the DNS records that the user must create. |
| GET | /projects/:id/domains/:domain | read | Returns the DNS state of a domain and the missing records. |
| POST | /projects/:id/domains/:domain/verify | write | Verifies a custom domain, then returns its state. |
| DELETE | /projects/:id/domains/:domain | write | Removes a custom domain. |
| GET | /projects/:id/chat | read | Returns the project chat as stored, or null. |
| POST | /projects/:id/chat/refresh | write | Checks the code generator. A ready reply deploys its code as a preview. Send it while you poll. |
| POST | /projects/:id/chat/messages | write | Sends a message to the project chat, which writes code and deploys it as a preview. |
| GET | /projects/:id/chat/files | read | Returns the files of the latest generated code. |
| POST | /projects/:id/chat/deploy | write | Deploys the latest generated code again, for example to production. |
| GET | /sandboxes | read | Lists the sandboxes. |
| POST | /sandboxes | write | Creates a sandbox and starts it. An empty body works. |
| GET | /sandboxes/:id | read | Returns a sandbox. It does not start a stopped sandbox. |
| POST | /sandboxes/:id/stop | write | Stops a sandbox. Its files stay. |
| POST | /sandboxes/:id/start | write | Starts a stopped sandbox with its files. |
| DELETE | /sandboxes/:id | write | Deletes a sandbox, its files, and its commands. |
| POST | /sandboxes/:id/commands | write | Runs a command in bash and waits for its exit code and output, or starts it in the background. |
| GET | /sandboxes/:id/commands/:commandId | read | Returns a command, with its exit code and output when it is done. |
| POST | /sandboxes/:id/commands/:commandId/kill | write | Stops a running command. |
| POST | /sandboxes/:id/terminal | write | Opens an interactive shell for the dashboard terminal. |
| PUT | /sandboxes/:id/files | write | Writes files in a sandbox. Send binary files as base64. |
| GET | /sandboxes/:id/files | read | Returns the raw bytes of one file. |
| POST | /ai/chat/completions | write | Sends a chat to a model, in the OpenAI chat completions format. With "stream": true, the response is server-sent events. |
| GET | /ai/models | read | Lists the chat models. |
| GET | /ai/usage | read | Returns the AI use and limits of the current UTC day. |