BROWSER USE

- Browser Use Agents: give Browser Use a task and receive completed work. API V4 is current for new integrations.
- Browser Infrastructure: connect your agent or automation to managed browsers through SDK, REST, or CDP. Starts at $0.02/browser-hour.
- Developer tools: Open Source, Browser Harness, SDK, and MCP support the two products above.

[Developer Index](https://browser-use.com/index.md)
[Product Map](https://browser-use.com/llms.txt)
[Full Product Context](https://browser-use.com/llms-full.txt)
[Pricing](https://browser-use.com/pricing.md)
[Cloud Docs](https://docs.browser-use.com/cloud/quickstart)
[Open Source Docs](https://docs.browser-use.com/open-source/introduction)

---

# Automate Vercel with an AI agent

Source: https://browser-use.com/skills/vercel. 3 files from github.com/browser-use/browser-harness, MIT licensed. Written for browser-harness: code calls its helpers (http_get, js, goto_url). Sites change; these notes describe what worked when last updated.

---

<!-- https://github.com/browser-use/browser-harness/blob/main/agent-workspace/domain-skills/vercel/archive-and-audit.md (updated 2026-10-09) -->

# Vercel — project identification and archival checks

Use the existing authenticated browser for project dashboards; prefer the public GitHub API/git for source archival once the repository is known. This guide does not require exporting cookies or environment-variable values.

## Identity and routes

- Team overview: `https://vercel.com/<team>`.
- Project overview: `https://vercel.com/<team>/<project>`.
- Project analytics: `https://vercel.com/<team>/<project>/analytics`.
- Production Deployment on the overview exposes the source repository, branch, abbreviated commit, full commit link, deployment domain, and creation date. Compare the full commit with the archived Git checkout; do not assume default-branch HEAD is deployed.
- A 404 on a known team route may be **account mismatch**, not a missing project. Read the rendered account identity after hydration.
- Use an existing tab from the intended Chrome profile. `Target.createTarget` does not guarantee that profile. Verify the visible Vercel account before reading project data. If no matching tab exists, ask the user to open the intended profile. Do not copy its credential store.
- Navigation completion is not dashboard hydration completion. After `wait_for_load()`, verify the visible account/project text and take a new screenshot before concluding that a team is unavailable.

## Read-only audit boundaries

The overview may show an Action Required / vulnerable-dependencies banner. Save the visible warning and its destination link. Remediation pages can initialize code-generation workflows, so **do not navigate into a fix workflow merely to inspect a warning**. Repository versions and official advisories are sufficient for initial verification. Do not click Redeploy, Update, or Rotate unless the user authorized that action.

Analytics reports are scoped to the displayed date range and can contain tiny samples. Save the date range alongside counts; do not interpret 100% bounce on a single-page site as proof that all readers disliked it. Custom-event availability depends on the account plan.

## Static media traps

A `.mp4` URL can return HTTP 200 with `Content-Type: video/mp4` but contain a **Git LFS pointer**, not video. The body starts with `version https://git-lfs.github.com/spec/v1` and is only about 130 bytes. Check bytes/magic and decode media, not just status codes.

For a complete source archive:

1. Clone source and record the exact production commit.
2. Fetch needed/all referenced LFS objects and check integrity.
3. Preserve hydrated working-tree media and `.git/lfs/objects`.
4. A `git bundle --all` preserves Git history **but not LFS object bodies**; retain the full source directory too.
5. Capture external CDN delivery URLs separately. Versioned and unversioned URLs can serve identical bytes; record URL-to-hash mappings rather than assuming every URL is a distinct work.
6. Preserve already-broken live responses as evidence and list recovered originals separately. Do not silently replace historical failures with guessed assets.

---

<!-- https://github.com/browser-use/browser-harness/blob/main/agent-workspace/domain-skills/vercel/observability.md (updated 2026-10-09) -->

# Vercel — project identity, visitor analytics and request traffic

The contributor supplied these observations without a validation date. Verify current labels and routes in the visible dashboard.

## Resolve the actual project first

- Team overview: `/{team_slug}`.
- Project overview: `/{team_slug}/{project_slug}`.
- A repository can be linked to multiple Vercel projects. Match the live domain
  on the project's Production Deployment card, not just a similar project name.
- The production card shows its source commit. A newer failed deployment does
  not replace the live commit. Record web and separately hosted backend revisions
  independently.

## Visitor analytics versus operational traffic

- Project **Analytics** links to the visitor dashboard. An **Enable** button and
  **Demo Data** label mean the sample chart is not measured visitor activity.
- Project **Observability → Edge Requests** provides operational request counts
  even when visitor analytics is not enabled.
- The edge-request view supports **Routes**, **Paths**, and **Bot Name** groupings.
  Inspect the exact time range and environment (e.g. Production).
- Page hits, sign-in route requests, function invocations and edge requests are
  not counts of people, successful sign-ins or conversions. The requesting agent,
  bots, scanners, static assets and prefetches may contribute.
- Named-bot counts do not imply the unclassified remainder is human.
- Longer lookback choices can be gated behind an observability plan. Do not
  enable/upgrade a paid feature just to answer a traffic question.

## UI traps

- **Edge Requests** may be both a sidebar link and a card link with identical
  destinations. Scope to the known navigation region or disambiguate the links.
- Client-side navigation may return a stale previous-page snapshot immediately
  after clicking. Check URL/next state rather than repeating the click blindly.
- A deployment's **Logs** page may show runtime request logs, not build logs.
  No runtime entries does not explain why a build failed.

Keep account names, customer domains, project IDs and traffic measurements out
of reusable public skills.

---

<!-- https://github.com/browser-use/browser-harness/blob/main/agent-workspace/domain-skills/vercel/vercel.md (updated 2026-05-04) -->

# Vercel Dashboard

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

```python
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

```python
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

```python
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

```python
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:

```python
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):

```python
# 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):
1. **Deployment Settings** — build machine, Node.js version, protection, etc. Shows "N Recommendations" badge when Vercel has upsell suggestions.
2. **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.
3. **Deployment Summary** — resource breakdown
4. **Deployment Checks** — external check integrations
5. **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

- **`/dashboard` always redirects** — canonical URL is `/<team-slug>`. Always check `page_info()["url"]` after navigation.
- **Build logs are in a virtual list** — `document.body.innerText` only contains what's currently scrolled into view. Use `/api/v3/deployments/<dep["uid"]>/events` to 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 the `dpl_` 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.
