Skip to main content

vercel

Emulated Vercel REST API for local development and testing. Use when the user needs to interact with Vercel API endpoints locally, test Vercel integrations, emulate projects/deployments/domains, set up Vercel OAuth flows, manage environment variables, create API keys, configure protection bypass, emulate Vercel Blob storage, or test without hitting the real Vercel API. Triggers include "Vercel API", "emulate Vercel", "mock Vercel", "test Vercel OAuth", "Vercel integration", "Vercel Blob", "local Vercel", or any task requiring a local Vercel API.

Source facts

Repository
vercel-labs/emulate
Last source activity
October 14, 2026 at 20:57
Detected SKILL.md language
English
Stars
1,893
Forks
138

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
vercel
description
Emulated Vercel REST API for local development and testing. Use when the user needs to interact with Vercel API endpoints locally, test Vercel integrations, emulate projects/deployments/domains, set up Vercel OAuth flows, manage environment variables, create API keys, configure protection bypass, emulate Vercel Blob storage, or test without hitting the real Vercel API. Triggers include "Vercel API", "emulate Vercel", "mock Vercel", "test Vercel OAuth", "Vercel integration", "Vercel Blob", "local Vercel", or any task requiring a local Vercel API.
allowed-tools
Bash(npx emulate:*), Bash(curl:*)
# Vercel API Emulator Fully stateful Vercel REST API emulation with Vercel-style JSON responses and cursor-based pagination. ## Start Local listeners bind to `127.0.0.1` by default. For access from containers or other machines, pass `--host 0.0.0.0` to the CLI or `hostname: '0.0.0.0'` to `createEmulator`. Configure `--base-url` or `baseUrl` for advertised URLs reachable by those clients. ```bash # Vercel only npx emulate --service vercel # Default port # http://localhost:4000 ``` Or programmatically: ```typescript import { createEmulator } from 'emulate' const vercel = await createEmulator({ service: 'vercel', port: 4000 }) // vercel.url === 'http://localhost:4000' ``` ## Auth Pass tokens as `Authorization: Bearer <token>`. All endpoints accept `teamId` or `slug` 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 `teamId` or `slug` query parameter. User-scoped requests resolve the account from the authenticated user. ## Pointing Your App at the Emulator ### Environment Variable ```bash VERCEL_EMULATOR_URL=http://localhost:4000 ``` ### Vercel SDK / Custom 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}` }, }) ``` ### OAuth URL Mapping | 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` | ### 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, } }, } ``` ## Seed Config ```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 ``` ## Pagination Cursor-based pagination using `limit`, `since`, and `until` query params. Responses include a `pagination` object: ```bash curl "http://localhost:4000/v10/projects?limit=10" \ -H "Authorization: Bearer $TOKEN" ``` ## API Endpoints ### User & Teams ```bash # Registration check curl http://localhost:4000/registration # Authenticated user curl http://localhost:4000/v2/user -H "Authorization: Bearer $TOKEN" # Update 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"}' # List teams (cursor paginated) curl http://localhost:4000/v2/teams -H "Authorization: Bearer $TOKEN" # Get team (by ID or slug) curl http://localhost:4000/v2/teams/my-team -H "Authorization: Bearer $TOKEN" # Create 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) curl -X PATCH http://localhost:4000/v2/teams/my-team \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"name": "Updated Team", "description": "New description"}' # List members curl http://localhost:4000/v2/teams/my-team/members -H "Authorization: Bearer $TOKEN" # Add member (by uid or email, with role) 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`. ### Projects ```bash # Create project (with optional env vars, git, and build config) 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) curl "http://localhost:4000/v10/projects?search=my-app" \ -H "Authorization: Bearer $TOKEN" # Get project (includes env vars) curl http://localhost:4000/v9/projects/my-app \ -H "Authorization: Bearer $TOKEN" # Update project (framework, buildCommand, devCommand, installCommand, # outputDirectory, rootDirectory, nodeVersion, serverlessFunctionRegion, # publicSource, autoAssignCustomDomains, gitForkProtection, # commandForIgnoringBuildStep) curl -X PATCH http://localhost:4000/v9/projects/my-app \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"framework": "remix"}' # Delete project (cascades deployments, domains, env vars, protection bypasses) curl -X DELETE http://localhost:4000/v9/projects/my-app \ -H "Authorization: Bearer $TOKEN" # Promote aliases status curl http://localhost:4000/v1/projects/my-app/promote/aliases \ -H "Authorization: Bearer $TOKEN" # Protection bypass: generate, revoke, regenerate curl -X PATCH http://localhost:4000/v1/projects/my-app/protection-bypass \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"generate": {"note": "CI preview", "scope": "deployment"}}' # Revoke protection bypass secrets curl -X PATCH http://localhost:4000/v1/projects/my-app/protection-bypass \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"revoke": ["secret_to_revoke"]}' # Regenerate protection bypass secrets curl -X PATCH http://localhost:4000/v1/projects/my-app/protection-bypass \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"regenerate": ["old_secret"]}' ``` ### Deployments ```bash # Create deployment (auto-transitions to 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"}}' # Targets: "production", "preview", "staging" # Get deployment (by ID or URL) curl http://localhost:4000/v13/deployments/dpl_abc123 \ -H "Authorization: Bearer $TOKEN" # List deployments (filter by projectId, app, target, state; cursor paginated) curl "http://localhost:4000/v6/deployments?projectId=my-app&target=production&limit=10" \ -H "Authorization: Bearer $TOKEN" # List deployments (filter by commit SHA) curl "http://localhost:4000/v7/deployments?sha=abc123" \ -H "Authorization: Bearer $TOKEN" # Delete deployment curl -X DELETE http://localhost:4000/v13/deployments/dpl_abc123 \ -H "Authorization: Bearer $TOKEN" # Cancel building deployment curl -X PATCH http://localhost:4000/v12/deployments/dpl_abc123/cancel \ -H "Authorization: Bearer $TOKEN" # List deployment aliases curl http://localhost:4000/v2/deployments/dpl_abc123/aliases \ -H "Authorization: Bearer $TOKEN" # Get build events/logs (supports direction, limit) curl "http://localhost:4000/v3/deployments/dpl_abc123/events?direction=forward&limit=50" \ -H "Authorization: Bearer $TOKEN" # List deployment files curl http://localhost:4000/v6/deployments/dpl_abc123/files \ -H "Authorization: Bearer $TOKEN" # Upload file (by SHA digest) 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 ``` ### Domains ```bash # Add domain (with optional redirect, gitBranch, customEnvironmentId) curl -X POST http://localhost:4000/v10/projects/my-app/domains \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"name": "example.com", "redirect": null, "redirectStatusCode": null, "gitBranch": null}' # *.vercel.app domains are auto-verified # List domains (cursor paginated) curl http://localhost:4000/v9/projects/my-app/domains \ -H "Authorization: Bearer $TOKEN" # Get, update, remove domain curl http://localhost:4000/v9/projects/my-app/domains/example.com \ -H "Authorization: Bearer $TOKEN" # Verify domain curl -X POST http://localhost:4000/v9/projects/my-app/domains/example.com/verify \ -H "Authorization: Bearer $TOKEN" ``` Redirect status codes: `301`, `302`, `307`, `308`. ### Environment Variables ```bash # List env vars (with decrypt option; filter by gitBranch, customEnvironmentId) curl "http://localhost:4000/v10/projects/my-app/env?decrypt=true" \ -H "Authorization: Bearer $TOKEN" # Create env vars (single, batch, or upsert) curl -X POST "http://localhost:4000/v10/projects/my-app/env?upsert=true" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub