Domain skill
vercel
Markdown synced from browser-harness domain skills.
- Host
- vercel
- Files
- 1
Agent prompt
Use this skill
Copy this prompt into your coding agent to make it enable browser-harness domain skills and read this exact domain folder before automating.
Set up https://github.com/browser-use/browser-harness for me if it is not already installed. If setup is needed, read `install.md` first to install and connect it to my real browser. Then read `SKILL.md` for normal usage and always read `helpers.py` because that is where the browser-harness functions are. Enable domain skills if they are not already enabled by setting `BH_DOMAIN_SKILLS=1` for browser-harness. Use the `vercel` domain skill from `agent-workspace/domain-skills/vercel/`. Read every markdown file for this domain before inventing an approach: - agent-workspace/domain-skills/vercel/vercel.md Use those domain-skill notes to complete my task for `vercel` in my real browser. When you open a setup, verification, or task tab, activate it so I can see the active browser tab.
Skill contents
What the agent will read
Vercel Dashboard
vercel.md
- Field-tested against vercel.com on 2026-05-03/04 using a logged-in Chrome session and the browser cookie auth pattern below.
- pageinfo()["url"] after navigating /dashboard gives you the real /<team-slug> URL.
- State filter: append &state=READY|ERROR|CANCELED|BUILDING|QUEUED|INITIALIZING Target filter: append &target=production|preview|development
- Deployment object keys: uid, name, projectId, url, created, source, state, readyState, readySubstate, type, creator, inspectorUrl, meta, target, aliasError, aliasAssigned, isRollbackCandidate, createdAt, buildingAt,...
Show full markdown
Field-tested against vercel.com on 2026-05-03/04 using a logged-in Chrome session and the browser cookie auth pattern below.
Auth — browser cookies, no separate token needed
import json
cookies = cdp("Network.getCookies", urls=["https://vercel.com"])
parts = [c["name"] + "=" + c["value"] for c in cookies.get("cookies", [])]
headers = {"Cookie": "; ".join(parts), "Accept": "application/json"}
URL patterns
/dashboard → redirects to /<team-slug> /<team-slug> → projects overview /<team-slug>/<project>/deployments → deployment list /<team-slug>/~/deployments → all-team deployments /<team-slug>/<project>/<uid-no-prefix> → deployment inspector /<team-slug>/<project>/<uid-no-prefix>/logs → runtime logs tab (requests, not build) /<team-slug>/<project>/logs?deploymentIds=<dep["uid"]> → runtime logs scoped to one deploy (dep["uid"] includes dpl_ prefix)
page_info()["url"] after navigating /dashboard gives you the real /<team-slug> URL.
REST API
List deployments
resp = http_get(
"https://vercel.com/api/v6/deployments?limit=100&teamId=<team-slug>",
headers=headers
)
# teamId accepts the URL slug (e.g. "my-team") — confirmed working.
# Vercel also has a separate internal team ID (team_xxx); slug is more practical here.
data = json.loads(resp)
deps = data["deployments"] # list of deployment objects
next_ts = data["pagination"]["next"] # pass as &until=<ts> to paginate; None when done
State filter: append &state=READY|ERROR|CANCELED|BUILDING|QUEUED|INITIALIZING
Target filter: append &target=production|preview|development
Deployment object keys: uid, name, projectId, url, created, source, state, readyState, readySubstate, type, creator, inspectorUrl, meta, target, aliasError, aliasAssigned, isRollbackCandidate, createdAt, buildingAt, ready, projectSettings
dep["inspectorUrl"] gives the correct inspector URL directly — use it rather than constructing the URL manually. dep["uid"] is the full dpl_<...> string for API calls; URL paths use the same string with the dpl_ prefix stripped.
List projects
data = json.loads(http_get(
"https://vercel.com/api/v9/projects?teamId=<team-slug>&limit=50",
headers=headers
))
# data["projects"][i]["latestDeployments"] → recent deploys per project
Build log
import json, re
dep = deps[0] # a deployment object from the list above; swap index as needed
uid = dep["uid"] # e.g. "dpl_2tySoj6ceJkTgtsWHvd5r1Hpgyd1" — already includes dpl_ prefix
resp = http_get(
"https://vercel.com/api/v3/deployments/" + uid + "/events?builds=1&limit=5000&teamId=<team-slug>",
headers=headers
)
# No pagination cursor in response — all events returned in one shot.
# limit=5000 is a safe ceiling. limit=-1 does NOT work (returns empty).
# API event count differs from the "N lines" shown in the UI header — do not use that as limit.
# Response is a JSON array, one object per line, separated by ",\n"
lines = [l.strip().rstrip(",") for l in resp.strip().split("\n") if l.strip() not in ("[", "]", "")]
events = [json.loads(l) for l in lines]
# Strip ANSI escape codes from text field
clean = "\n".join(re.sub(r"\x1b\[[0-9;]*m", "", e["text"]) for e in events)
Event schema: {created, date, deploymentId, id, text, type: "stdout"|"stderr", serial, info: {type: "build", name: "bld_<id>", entrypoint: "."}}
Scraping projects and deployment status
Fastest approach — document.body.innerText is reliable; the Projects section renders near the end:
new_tab("https://vercel.com/dashboard")
wait_for_load()
text = js("document.body.innerText")
# Each project card block in innerText (confirmed live):
# <project-name>\n<commit msg>\n<date>\n on\n<branch>
# Note: .vercel.app and <owner>/<repo> are separate link elements, not in this text block
For deployment links specifically (inspector URLs contain the project name):
# Replace <project-name> with the actual project slug
links = js("Array.from(document.querySelectorAll('a[href]')).filter(a=>a.href.includes('/<project-name>/')).map(a=>a.href+'|'+a.innerText.trim().slice(0,80)).join('||')")
Deployment inspector page structure
URL: /<team-slug>/<project>/<uid-no-prefix> — title: <project> – Deployment Overview – Vercel
Tabs across the top: Deployment | Logs | Resources | Source | Open Graph
Accordion sections (all expand on click):
- Deployment Settings — build machine, Node.js version, protection, etc. Shows "N Recommendations" badge when Vercel has upsell suggestions.
- Build Logs — header shows duration +
N lines(UI line count) + warning count + ✅/❌. Content is a virtual list — only visible rows are in the DOM. Use the API endpoint above to get all lines. Note: the UI line count does not equal the API event count. - Deployment Summary — resource breakdown
- Deployment Checks — external check integrations
- Assigning Custom Domains — alias assignment status
Bottom cards: Runtime Logs | Observability | Speed Insights | BotID
Runtime logs page structure
URL: /<team-slug>/<project>/<uid-no-prefix>/logs — title: <project> – Deployment Runtime Logs – Vercel
This is request/response logs (serverless function traffic), not build output. Left panel filters: Timeline, Console Level (Warning/Error/Fatal with counts), Resource, Environment, Route, Request Path, Status Code, Request Type, Host, Request Method, Cache, Branch, Workflow Run, Workflow Step.
Gotchas
/dashboardalways redirects — canonical URL is/<team-slug>. Always checkpage_info()["url"]after navigation.- Build logs are in a virtual list —
document.body.innerTextonly contains what's currently scrolled into view. Use/api/v3/deployments/<dep["uid"]>/eventsto get all lines. - Build log text has ANSI escape codes — strip with
re.sub(r"\x1b\[[0-9;]*m", "", text)before displaying. - Short UID vs full UID —
dep["uid"]=dpl_2tySoj6ceJkTgtsWHvd5r1Hpgyd1(full, with prefix). URL paths strip thedpl_prefix but keep the full string:/<team-slug>/<project>/2tySoj6ceJkTgtsWHvd5r1Hpgyd1. The breadcrumb displays a truncated form (2tySoj6ce) but that is not the URL.dep["inspectorUrl"]gives you the correct URL directly. - Preview deployment URLs follow
<project>-git-<branch-slug>-<team-slug>.vercel.app. The branch slug is truncated with a hex suffix (e.g.vercel/install-analytics→vercel-install-v-f236ab). - Status filter shows 5/6 by default — Canceled is excluded from the deployments list by default. The 6 states in order: Ready (green), Error (red), Building (orange), Queued, Initializing, Canceled. DOM marker:
aria-label="N of 6 statuses selected"on the badge. - "Error: Forbidden" in the preview thumbnail = the deployed app requires auth, not a deployment failure.
- Project card
!icon = Speed Insights performance alert, not a build error. - Page title prefix is a status signal —
🟢 Vercel/🟢 <project>= all systems nominal. - Hobby plan: Alerts (anomaly monitoring) requires Pro. Deployment Settings shows "N Recommendations" for plan-upsell config suggestions.