Skip to content
Development
Skill

/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

From plugin
emulate
1.5k14 skills
Install
$ npx -y skills add vercel-labs/emulate --skill vercel --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/vercel

Context preview

The summary Claude sees to decide when to auto-load this skill.

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

SKILL.md

vercel.SKILL.md
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(emulate:*), Bash(curl:*)

Vercel API Emulator

Fully stateful Vercel REST API emulation with Vercel-style JSON responses and cursor-based pagination.

Start

# Vercel only
npx emulate --service vercel

# Default port
# http://localhost:4000

Or programmatically:

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.

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

VERCEL_EMULATOR_URL=http://localhost:4000

Vercel SDK / Custom Fetch

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

{
  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

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:

curl "http://localhost:4000/v10/projects?limit=10" \
  -H "Authorization: Bearer $TOKEN"

API Endpoints

User & Teams

# 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

# 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,
Read more
Ships withemulate

Local drop-in replacement services for CI and no-network sandboxes. Fully stateful, production-fidelity API emulation. Not mocks.

Get the whole plugin
Stats
1,543
Stars
109
Forks
Active
Maintenance
TypeScript
Language
Apache-2.0
License
20d ago
Last commit
4mo ago
Created

Repo: vercel-labs/emulate

Other skills on emulate.