Vercel API Emulator
Vercel API模拟器
Fully stateful Vercel REST API emulation with Vercel-style JSON responses and cursor-based pagination.
具备完整状态的Vercel REST API模拟工具,支持Vercel风格的JSON响应和基于游标分页功能。
npx emulate --service vercel
npx emulate --service vercel
Or programmatically:
```typescript
import { createEmulator } from 'emulate'
const vercel = await createEmulator({ service: 'vercel', port: 4000 })
// vercel.url === 'http://localhost:4000'
或以编程方式启动:
```typescript
import { createEmulator } from 'emulate'
const vercel = await createEmulator({ service: 'vercel', port: 4000 })
// vercel.url === 'http://localhost:4000'
Pass tokens as
Authorization: Bearer <token>
. All endpoints accept
or
query params for team scoping.
bash
curl http://localhost:4000/v2/user \
-H "Authorization: Bearer test_token_admin"
Team-scoped requests resolve the account from the
or
query parameter. User-scoped requests resolve the account from the authenticated user.
通过
Authorization: Bearer <token>
传递令牌。所有端点均支持通过
或
查询参数指定团队作用域。
bash
curl http://localhost:4000/v2/user \
-H "Authorization: Bearer test_token_admin"
指定团队作用域的请求会通过
或
查询参数解析账户信息。用户作用域的请求则通过已认证用户解析账户信息。
Pointing Your App at the Emulator
将应用指向模拟器
Environment Variable
环境变量配置
bash
VERCEL_EMULATOR_URL=http://localhost:4000
bash
VERCEL_EMULATOR_URL=http://localhost:4000
Vercel SDK / Custom Fetch
Vercel SDK / 自定义Fetch
typescript
const VERCEL_API = process.env.VERCEL_EMULATOR_URL ?? 'https://api.vercel.com'
const res = await fetch(`${VERCEL_API}/v10/projects`, {
headers: { Authorization: `Bearer ${token}` },
})
typescript
const VERCEL_API = process.env.VERCEL_EMULATOR_URL ?? 'https://api.vercel.com'
const res = await fetch(`${VERCEL_API}/v10/projects`, {
headers: { Authorization: `Bearer ${token}` },
})
OAuth URL Mapping
OAuth URL映射
| Real Vercel URL | Emulator URL |
|---|
https://vercel.com/integrations/oauth/authorize
| $VERCEL_EMULATOR_URL/oauth/authorize
|
https://api.vercel.com/login/oauth/token
| $VERCEL_EMULATOR_URL/login/oauth/token
|
https://api.vercel.com/login/oauth/userinfo
| $VERCEL_EMULATOR_URL/login/oauth/userinfo
|
| 真实Vercel URL | 模拟器URL |
|---|
https://vercel.com/integrations/oauth/authorize
| $VERCEL_EMULATOR_URL/oauth/authorize
|
https://api.vercel.com/login/oauth/token
| $VERCEL_EMULATOR_URL/login/oauth/token
|
https://api.vercel.com/login/oauth/userinfo
| $VERCEL_EMULATOR_URL/login/oauth/userinfo
|
Auth.js / NextAuth.js
Auth.js / NextAuth.js配置
typescript
{
id: 'vercel',
name: 'Vercel',
type: 'oauth',
authorization: {
url: `${process.env.VERCEL_EMULATOR_URL}/oauth/authorize`,
},
token: {
url: `${process.env.VERCEL_EMULATOR_URL}/login/oauth/token`,
},
userinfo: {
url: `${process.env.VERCEL_EMULATOR_URL}/login/oauth/userinfo`,
},
clientId: process.env.VERCEL_CLIENT_ID,
clientSecret: process.env.VERCEL_CLIENT_SECRET,
profile(profile) {
return {
id: profile.sub,
name: profile.name,
email: profile.email,
image: profile.picture,
}
},
}
typescript
{
id: 'vercel',
name: 'Vercel',
type: 'oauth',
authorization: {
url: `${process.env.VERCEL_EMULATOR_URL}/oauth/authorize`,
},
token: {
url: `${process.env.VERCEL_EMULATOR_URL}/login/oauth/token`,
},
userinfo: {
url: `${process.env.VERCEL_EMULATOR_URL}/login/oauth/userinfo`,
},
clientId: process.env.VERCEL_CLIENT_ID,
clientSecret: process.env.VERCEL_CLIENT_SECRET,
profile(profile) {
return {
id: profile.sub,
name: profile.name,
email: profile.email,
image: profile.picture,
}
},
}
yaml
tokens:
test_token_admin:
login: admin
scopes: []
vercel:
users:
- username: developer
name: Developer
email: dev@example.com
teams:
- slug: my-team
name: My Team
description: Engineering team
projects:
- name: my-app
team: my-team
framework: nextjs
buildCommand: next build
outputDirectory: .next
rootDirectory: null
nodeVersion: "20.x"
envVars:
- key: DATABASE_URL
value: postgres://localhost/mydb
type: encrypted
target: [production, preview]
integrations:
- client_id: oac_abc123
client_secret: secret_abc123
name: My Vercel App
redirect_uris:
- http://localhost:3000/api/auth/callback/vercel
yaml
tokens:
test_token_admin:
login: admin
scopes: []
vercel:
users:
- username: developer
name: Developer
email: dev@example.com
teams:
- slug: my-team
name: My Team
description: Engineering team
projects:
- name: my-app
team: my-team
framework: nextjs
buildCommand: next build
outputDirectory: .next
rootDirectory: null
nodeVersion: "20.x"
envVars:
- key: DATABASE_URL
value: postgres://localhost/mydb
type: encrypted
target: [production, preview]
integrations:
- client_id: oac_abc123
client_secret: secret_abc123
name: My Vercel App
redirect_uris:
- http://localhost:3000/api/auth/callback/vercel
Cursor-based pagination using
,
, and
query params. Responses include a
object:
bash
curl "http://localhost:4000/v10/projects?limit=10" \
-H "Authorization: Bearer $TOKEN"
使用
、
和
查询参数实现基于游标的分页。响应结果包含
对象:
bash
curl "http://localhost:4000/v10/projects?limit=10" \
-H "Authorization: Bearer $TOKEN"
Authenticated user
获取已认证用户信息
curl -X PATCH
http://localhost:4000/v2/user
-H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d '{"name": "New Name", "email": "
new@example.com"}'
curl -X PATCH
http://localhost:4000/v2/user
-H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d '{"name": "New Name", "email": "
new@example.com"}'
List teams (cursor paginated)
列出团队(游标分页)
Get team (by ID or slug)
获取团队信息(通过ID或slug)
curl -X POST
http://localhost:4000/v2/teams
-H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d '{"slug": "new-team", "name": "New Team"}'
curl -X POST
http://localhost:4000/v2/teams
-H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d '{"slug": "new-team", "name": "New Team"}'
Update team (name, slug, description)
更新团队信息(名称、slug、描述)
Add member (by uid or email, with role)
添加团队成员(通过uid或邮箱,指定角色)
curl -X POST "
http://localhost:4000/v2/teams/team_id/members"
-H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d '{"email": "
dev@example.com", "role": "MEMBER"}'
Roles: `OWNER`, `MEMBER`, `DEVELOPER`, `VIEWER`.
Create project (with optional env vars, git, and build config)
创建项目(可配置环境变量、Git和构建参数)
curl -X POST
http://localhost:4000/v11/projects
-H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d '{"name": "my-app", "framework": "nextjs", "buildCommand": "next build", "outputDirectory": ".next", "nodeVersion": "20.x", "environmentVariables": [{"key": "API_KEY", "value": "secret", "type": "encrypted", "target": ["production"]}]}'
curl -X POST
http://localhost:4000/v11/projects
-H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d '{"name": "my-app", "framework": "nextjs", "buildCommand": "next build", "outputDirectory": ".next", "nodeVersion": "20.x", "environmentVariables": [{"key": "API_KEY", "value": "secret", "type": "encrypted", "target": ["production"]}]}'
List projects (search, cursor pagination)
列出项目(支持搜索、游标分页)
Get project (includes env vars)
获取项目信息(包含环境变量)
Update project (framework, buildCommand, devCommand, installCommand,
更新项目信息(框架、构建命令、开发命令、安装命令、
outputDirectory, rootDirectory, nodeVersion, serverlessFunctionRegion,
输出目录、根目录、Node版本、无服务器函数区域、
publicSource, autoAssignCustomDomains, gitForkProtection,
公开源码、自动分配自定义域名、Git分支保护、
commandForIgnoringBuildStep)
忽略构建步骤命令)
Delete project (cascades deployments, domains, env vars, protection bypasses)
删除项目(会级联删除部署、域名、环境变量、防护绕过配置)
Promote aliases status
提升别名状态
Protection bypass: generate, revoke, regenerate
防护绕过:生成、撤销、重新生成
Revoke protection bypass secrets
撤销防护绕过密钥
Regenerate protection bypass secrets
重新生成防护绕过密钥
Create deployment (auto-transitions to READY)
创建部署(自动转换为READY状态)
curl -X POST
http://localhost:4000/v13/deployments
-H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d '{"name": "my-app", "target": "production", "meta": {"commit": "abc123"}, "regions": ["iad1"], "gitSource": {"type": "github", "ref": "main", "sha": "abc123", "repoId": "123", "org": "my-org", "repo": "my-app", "message": "Deploy", "authorName": "dev", "commitAuthorName": "dev"}}'
curl -X POST
http://localhost:4000/v13/deployments
-H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d '{"name": "my-app", "target": "production", "meta": {"commit": "abc123"}, "regions": ["iad1"], "gitSource": {"type": "github", "ref": "main", "sha": "abc123", "repoId": "123", "org": "my-org", "repo": "my-app", "message": "Deploy", "authorName": "dev", "commitAuthorName": "dev"}}'
Targets: "production", "preview", "staging"
目标环境选项:"production"、"preview"、"staging"
Get deployment (by ID or URL)
获取部署信息(通过ID或URL)
List deployments (filter by projectId, app, target, state; cursor paginated)
列出部署(支持按projectId、应用、目标环境、状态过滤;游标分页)
Cancel building deployment
取消正在构建的部署
List deployment aliases
列出部署别名
Get build events/logs (supports direction, limit)
获取构建事件/日志(支持方向、数量限制)
List deployment files
列出部署文件
Upload file (by SHA digest)
上传文件(通过SHA摘要)
curl -X POST
http://localhost:4000/v2/files
-H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/octet-stream"
-H "x-vercel-digest: sha256hash"
--data-binary @file.txt
curl -X POST
http://localhost:4000/v2/files
-H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/octet-stream"
-H "x-vercel-digest: sha256hash"
--data-binary @file.txt
Add domain (with optional redirect, gitBranch, customEnvironmentId)
添加域名(可配置重定向、Git分支、自定义环境ID)
*.vercel.app domains are auto-verified
*.vercel.app域名会自动验证
List domains (cursor paginated)
列出域名(游标分页)
Get, update, remove domain
获取、更新、删除域名
Redirect status codes: `301`, `302`, `307`, `308`.
重定向状态码选项:`301`、`302`、`307`、`308`。
Environment Variables
环境变量
List env vars (with decrypt option; filter by gitBranch, customEnvironmentId)
列出环境变量(支持解密选项;可按Git分支、自定义环境ID过滤)
Create env vars (single, batch, or upsert)
创建环境变量(支持单个、批量或更新插入)
Env var types: `system`, `encrypted`, `plain`, `secret`, `sensitive`.
环境变量类型:`system`、`encrypted`、`plain`、`secret`、`sensitive`。
Create API key (optional teamId scope)
创建API密钥(可选指定teamId作用域)
List API keys (optional teamId filter)
列出API密钥(可选按teamId过滤)
OAuth / Integrations
OAuth / 集成
Authorize (browser flow, shows user picker)
授权(浏览器流程,显示用户选择器)
GET /oauth/authorize?client_id=...&redirect_uri=...&scope=...&state=...
GET /oauth/authorize?client_id=...&redirect_uri=...&scope=...&state=...
Token exchange (supports PKCE; accepts JSON or form-urlencoded)
令牌交换(支持PKCE;接受JSON或表单编码格式)
User info (returns sub, email, email_verified, name, preferred_username, picture)
用户信息(返回sub、email、email_verified、name、preferred_username、picture)
Create Project and Deploy
创建项目并部署
bash
TOKEN="test_token_admin"
BASE="http://localhost:4000"
bash
TOKEN="test_token_admin"
BASE="http://localhost:4000"
curl -X POST $BASE/v11/projects
-H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d '{"name": "my-app", "framework": "nextjs"}'
curl -X POST $BASE/v11/projects
-H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d '{"name": "my-app", "framework": "nextjs"}'
curl -X POST $BASE/v10/projects/my-app/env
-H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d '{"key": "DATABASE_URL", "value": "postgres://...", "type": "encrypted", "target": ["production"]}'
curl -X POST $BASE/v10/projects/my-app/env
-H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d '{"key": "DATABASE_URL", "value": "postgres://...", "type": "encrypted", "target": ["production"]}'
curl -X POST $BASE/v13/deployments
-H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d '{"name": "my-app", "target": "production"}'
curl -X POST $BASE/v13/deployments
-H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d '{"name": "my-app", "target": "production"}'
OAuth Integration Flow
OAuth集成流程
- Redirect user to
$VERCEL_EMULATOR_URL/oauth/authorize?client_id=...&redirect_uri=...&state=...
- User picks a seeded user on the emulator's UI
- Emulator redirects back with
- Exchange code for token via
- Fetch user info via
GET /login/oauth/userinfo
PKCE is supported. Pass
and
on authorize, then
on token exchange.
- 将用户重定向至
$VERCEL_EMULATOR_URL/oauth/authorize?client_id=...&redirect_uri=...&state=...
- 用户在模拟器UI中选择一个预配置的用户
- 模拟器重定向回原地址并携带
- 通过 交换令牌
- 通过
GET /login/oauth/userinfo
获取用户信息
支持PKCE流程。在授权时传递
和
,然后在令牌交换时传递
。
Team-Scoped Requests
团队作用域请求
All endpoints accept
or
query params:
bash
curl "http://localhost:4000/v10/projects?teamId=team_abc123" \
-H "Authorization: Bearer $TOKEN"
curl "http://localhost:4000/v10/projects?slug=my-team" \
-H "Authorization: Bearer $TOKEN"
bash
curl "http://localhost:4000/v10/projects?teamId=team_abc123" \
-H "Authorization: Bearer $TOKEN"
curl "http://localhost:4000/v10/projects?slug=my-team" \
-H "Authorization: Bearer $TOKEN"