← Back to the library
Coding

Vercel CLI with tokens

Deploy and manage projects on Vercel using token-based authentication. Use when working with Vercel CLI using access tokens rather than interactive login — e.g. "deploy to vercel", "set up vercel", "add environment variables to vercel".

Works with the context you provideVersion 1.0.0

# Vercel CLI with Tokens

Deploy and manage projects on Vercel using the CLI with token-based authentication, without relying on `vercel login`.

Step 1: Locate the Vercel Token

Before running any Vercel CLI commands, identify where the token is coming from. Work through these scenarios in order:

A) `VERCEL_TOKEN` is already set in the environment

```bash printenv VERCEL_TOKEN ```

If this returns a value, you're ready. Skip to Step 2.

B) Token is in a `.env` file under `VERCEL_TOKEN`

```bash grep '^VERCEL_TOKEN=' .env 2>/dev/null ```

If found, export it:

```bash export VERCEL_TOKEN=$(grep '^VERCEL_TOKEN=' .env | cut -d= -f2-) ```

C) Token is in a `.env` file under a different name

Look for any variable that looks like a Vercel token (Vercel tokens typically start with `vca_`):

```bash grep -i 'vercel' .env 2>/dev/null ```

Inspect the output to identify which variable holds the token, then export it as `VERCEL_TOKEN`:

```bash export VERCEL_TOKEN=$(grep '^<VARIABLE_NAME>=' .env | cut -d= -f2-) ```

D) No token found — ask the user

If none of the above yield a token, ask the user to provide one. They can create a Vercel access token at vercel.com/account/tokens.

---

**Important:** Once `VERCEL_TOKEN` is exported as an environment variable, the Vercel CLI reads it natively — **do not pass it as a `--token` flag**. Putting secrets in command-line arguments exposes them in shell history and process listings.

```bash # Bad — token visible in shell history and process listings vercel deploy --token "vca_abc123"

# Good — CLI reads VERCEL_TOKEN from the environment export VERCEL_TOKEN="vca_abc123" vercel deploy ```

Step 2: Locate the Project and Team

Similarly, check for the project ID and team scope. These let the CLI target the right project without needing `vercel link`.

```bash # Check environment printenv VERCEL_PROJECT_ID printenv VERCEL_ORG_ID

# Or check .env grep -i 'vercel' .env 2>/dev/null ```

**If you have a project URL** (e.g. `https://vercel.com/my-team/my-project`), extract the team slug:

```bash # e.g. "my-team" from "https://vercel.com/my-team/my-project" echo "$PROJECT_URL" | sed 's|https://vercel.com/||' | cut -d/ -f1 ```

**If you have both `VERCEL_ORG_ID` and `VERCEL_PROJECT_ID` in your environment**, export them — the CLI will use these automatically and skip any `.vercel/` directory:

```bash export VERCEL_ORG_ID="<org-id>" export VERCEL_PROJECT_ID="<project-id>" ```

Note: `VERCEL_ORG_ID` and `VERCEL_PROJECT_ID` must be set together — setting only one causes an error.

CLI Setup

Ensure the Vercel CLI is installed and up to date:

```bash npm install -g vercel vercel --version ```

Deploying a Project

Always deploy as **preview** unless the user explicitly requests production. Choose a method based on what you have available.

Quick Deploy (have project ID — no linking needed)

When `VERCEL_TOKEN` and `VERCEL_PROJECT_ID` are set in the environment, deploy directly:

```bash vercel deploy -y --no-wait ```

With a team scope (either via `VERCEL_ORG_ID` or `--scope`):

```bash vercel deploy --scope <team-slug> -y --no-wait ```

Production (only when explicitly requested):

```bash vercel deploy --prod --scope <team-slug> -y --no-wait ```

Check status:

```bash vercel inspect <deployment-url> ```

Full Deploy Flow (no project ID — need to link)

Use this when you have a token and team but no pre-existing project ID.

Check project state first

```bash # Does the project have a git remote? git remote get-url origin 2>/dev/null

# Is it already linked to a Vercel project? cat .vercel/project.json 2>/dev/null || cat .vercel/repo.json 2>/dev/null ```

Link the project

**With git remote (preferred):**

```bash vercel link --repo --scope <team-slug> -y ```

Reads the git remote and connects to the matching Vercel project. Creates `.vercel/repo.json`. More reliable than plain `vercel link`, which matches by directory name.

**Without git remote:**

```bash vercel link --scope <team-slug> -y ```

Creates `.vercel/project.json`.

**Link to a specific project by name:**

```bash vercel link --project <project-name> --scope <team-slug> -y ```

If the project is already linked, check `orgId` in `.vercel/project.json` or `.vercel/repo.json` to verify it matches the intended team.

Deploy after linking

**A) Git Push Deploy — has git remote (preferred)**

Git pushes trigger automatic Vercel deployments.

1. **Ask the user before pushing.** Never push without explicit approval. 2. Commit and push: ```bash git add . git commit -m "deploy: <description of changes>" git push ``` 3. Vercel builds automatically. Non-production branches get preview deployments. 4. Retrieve the deployment URL: ```bash sleep 5 vercel ls --format json --scope <team-slug> ``` Find the latest entry in the `deployments` array.

**B) CLI Deploy — no git remote**

```bash vercel deploy --scope <team-slug> -y --no-wait ```

Check status:

```bash vercel inspect <deployment-url> ```

Deploying from a Remote Repository (code not cloned locally)

1. Clone the repository: ```bash git clone <repo-url> cd <repo-name> ``` 2. Link to Vercel: ```bash vercel link --repo --scope <team-slug> -y ``` 3. Deploy via git push (if you have push access) or CLI deploy.

About `.vercel/` Directory

A linked project has either: - `.vercel/project.json` — from `vercel link`. Contains `projectId` and `orgId`. - `.vercel/repo.json` — from `vercel link --repo`. Contains `orgId`, `remoteName`, and a `projects` map.

Not needed when `VERCEL_ORG_ID` + `VERCEL_PROJECT_ID` are both set in the environment.

**Do NOT** run `vercel project inspect` or `vercel link` in an unlinked directory to detect state — they will interactively prompt or silently link as a side-effect. `vercel ls` is safe (in an unlinked directory it defaults to showing all deployments for the scope). `vercel whoami` is safe anywhere.

Managing Environment Variables

```bash # Set for all environments echo "value" | vercel env add VAR_NAME --scope <team-slug>

# Set for a specific environment (production, preview, development) echo "value" | vercel env add VAR_NAME production --scope <team-slug>

# List environment variables vercel env ls --scope <team-slug>

# Pull env vars to local .env.local file vercel env pull --scope <team-slug>

# Remove a variable vercel env rm VAR_NAME --scope <team-slug> -y ```

Inspecting Deployments

```bash # List recent deployments vercel ls --format json --scope <team-slug>

# Inspect a specific deployment vercel inspect <deployment-url>

# View build logs (requires Vercel CLI v35+) vercel inspect <deployment-url> --logs

# View runtime request logs (follows live by default; add --no-follow for a one-shot snapshot) vercel logs <deployment-url> ```

Managing Domains

```bash # List domains vercel domains ls --scope <team-slug>

# Add a domain to the project — linked or env-linked directory (1 arg) vercel domains add <domain> --scope <team-slug>

# Add a domain — unlinked directory (requires <project> positional) vercel domains add <domain> <project> --scope <team-slug> ```

Stripe Projects Plan Changes

If this project is managed by Stripe Projects. **Ask the user before running any paid or destructive plan change** — upgrades bill a real card, downgrades remove seats.

First run `stripe projects status --json` to confirm the Vercel resource's local name. The examples below assume the default (`vercel-plan`); substitute the actual name if it was renamed at `stripe projects add` time.

  • **Upgrade to Pro:** `stripe projects add vercel/pro` (or `stripe projects upgrade vercel-plan pro`)
  • **Downgrade to Hobby:** `stripe projects downgrade vercel-plan hobby`

What Pro gives you

  • $20/month platform fee, includes $20/month of usage credit.
  • Turbo build machines (30 vCPUs, 60 GB memory) by default for new projects — significantly faster builds than Hobby.
  • 1 deploying seat + unlimited free Viewer seats (read-only collaborators, preview comments).
  • Higher included allocations (1 TB Fast Data Transfer, 10M Edge Requests per month).
  • Paid add-ons available: SAML SSO, HIPAA BAA, Flags Explorer, Observability Plus, Speed Insights, Web Analytics Plus.

Full details: https://vercel.com/docs/plans/pro-plan

Working Agreement

  • **Never pass `VERCEL_TOKEN` as a `--token` flag.** Export it as an environment variable and let the CLI read it natively.
  • **Check the environment for tokens before asking the user.** Look in the current env and `.env` files first.
  • **Default to preview deployments.** Only deploy to production when explicitly asked.
  • **Ask before pushing to git.** Never push commits without the user's approval.
  • **Do not modify `.vercel/` files directly.** The CLI manages this directory. Reading them (e.g. to verify `orgId`) is fine.
  • **Do not curl/fetch deployed URLs to verify.** Just return the link to the user.
  • **Use `--format json`** when structured output will help with follow-up steps.
  • **Use `-y`** on commands that prompt for confirmation to avoid interactive blocking.

Troubleshooting

Token not found

Check the environment and any `.env` files present:

```bash printenv | grep -i vercel grep -i vercel .env 2>/dev/null ```

Authentication error

If the CLI fails with `Authentication required`: - The token may be expired or invalid. - Verify: `vercel whoami` (uses `VERCEL_TOKEN` from environment). - Ask the user for a fresh token.

Wrong team

Verify the scope is correct:

```bash vercel whoami --scope <team-slug> ```

Build failure

Check the build logs:

```bash vercel inspect <deployment-url> --logs ```

Common causes: - Missing dependencies — ensure `package.json` is complete and committed. - Missing environment variables — add with `vercel env add`. - Framework misconfiguration — check `vercel.json`. Vercel auto-detects frameworks (Next.js, Remix, Vite, etc.) from `package.json`; override with `vercel.json` if detection is wrong.

CLI not installed

```bash npm install -g vercel ```