vercel-env-sync
Sync environment variables from local .env to a Vercel project and trigger redeploy. Use this skill whenever the user wants to update Vercel env vars, fix a missing API key on production, sync .env to
Files1
View on GitHubSKILL.md.claude/skills/vercel-env-sync/SKILL.md
GitHubVercel Env Sync
Sync env vars from local .env to a Vercel project via the Vercel REST API, then trigger a redeploy.
Step 1 — Find the working Vercel token
Read .env and extract all tokens starting with vcp_. Try each until one works:
curl -s -H "Authorization: Bearer <token>" "https://api.vercel.com/v9/projects?limit=5"
A working token returns {"projects": [...]}. An invalid one returns {"error": {"invalidToken": true}}.
The .env may have multiple
vcp_tokens (e.g.VERCEL_TOKEN,vcp_...raw lines). Try all of them.
Step 2 — Find the project ID
From the projects list, match by name (e.g. keyway-construction). Save project.id (format: prj_...).
curl -s -H "Authorization: Bearer <TOKEN>" "https://api.vercel.com/v9/projects?limit=20" \
| python3 -c "import sys,json; [print(p['id'], p['name']) for p in json.load(sys.stdin).get('projects',[])]"
Ask the user which project if ambiguous.
Step 3 — List current Vercel env vars
curl -s "https://api.vercel.com/v9/projects/<PROJECT_ID>/env" \
-H "Authorization: Bearer <TOKEN>" \
| python3 -c "import sys,json; [print(e['id'], e['key']) for e in json.load(sys.stdin).get('envs',[])]"
This returns a list of {id, key, value (encrypted)}. Build a map of key → [list of env ids].
Step 4 — Parse .env and decide what to sync
Read .env. For each line matching KEY=VALUE:
- Skip keys that are git tokens or clearly not needed on Vercel:
GIT_ACC_*,X_USERNAME,X_PASSWORD,X_AUTH_TOKEN,X_CT0DATAIMPULSE_*,DATAFORSEO_*(unless user says otherwise)
- Sync everything else:
RESEND_API_KEY,STRIPE_*,NEXT_PUBLIC_*,VERCEL_TOKEN,FIRECRAWL_*, etc.
Show the user the list of keys you're about to sync and confirm before proceeding.
Step 5 — Update or create each env var
If key already exists (one entry): PATCH to update the value:
curl -s -X PATCH \
"https://api.vercel.com/v9/projects/<PROJECT_ID>/env/<ENV_ID>" \
-H "Authorization: Bearer <TOKEN>" \
-H "Content-Type: application/json" \
-d '{"value": "<VALUE>"}'
If key has duplicates: DELETE all but the first, then PATCH the remaining one:
# Delete duplicate
curl -s -X DELETE \
"https://api.vercel.com/v9/projects/<PROJECT_ID>/env/<DUPLICATE_ID>" \
-H "Authorization: Bearer <TOKEN>"
# Update the kept one
curl -s -X PATCH \
"https://api.vercel.com/v9/projects/<PROJECT_ID>/env/<KEPT_ID>" \
-H "Authorization: Bearer <TOKEN>" \
-H "Content-Type: application/json" \
-d '{"value": "<VALUE>"}'
If key doesn't exist yet: POST to create:
curl -s -X POST \
"https://api.vercel.com/v10/projects/<PROJECT_ID>/env" \
-H "Authorization: Bearer <TOKEN>" \
-H "Content-Type: application/json" \
-d '{"key":"<KEY>","value":"<VALUE>","type":"encrypted","target":["production","preview","development"]}'
PATCH body only needs
{"value": "..."}— do NOT includetargetin PATCH or you'll get a conflict error.
Step 6 — Trigger redeploy
Get the latest deployment ID:
curl -s "https://api.vercel.com/v6/deployments?projectId=<PROJECT_ID>&limit=1" \
-H "Authorization: Bearer <TOKEN>" \
| python3 -c "import sys,json; d=json.load(sys.stdin)['deployments'][0]; print(d['uid'], d['url'])"
Trigger redeploy from that deployment:
curl -s -X POST \
"https://api.vercel.com/v13/deployments?forceNew=1" \
-H "Authorization: Bearer <TOKEN>" \
-H "Content-Type: application/json" \
-d '{"deploymentId":"<DEPLOYMENT_ID>","name":"<PROJECT_NAME>","target":"production"}' \
| python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('url','?'), d.get('state','?'))"
Common errors
| Error | Fix |
|---|---|
invalidToken |
Try the next vcp_ token from .env |
ENV_CONFLICT |
Key already exists with that target — use PATCH not POST |
bad_request: should NOT have additional property projectId |
Remove projectId from POST /deployments body |
| PATCH returns conflict | Don't include target in PATCH body, only value |
Summary output
After completing, report:
- How many keys were synced (updated / created / skipped)
- Redeploy URL (e.g.
keyway-construction-xxx.vercel.app) - Whether the deployment is BUILDING or READY