API Structure

Overview

Resource Hierarchy

Architecture Diagram ASCII
Profile   (create instance with profile)Instance (orchestrator resource)   (create tab in instance)Tab (primary resource - where all work happens)   Navigate   Snapshot   Action / Actions   Text   Evaluate   Screenshot   PDF   Cookies   Lock / Unlock   Close

Complete Endpoint List

Profile Management

MethodPathPayloadResponsePurpose
GET/profiles-[{id, name, createdAt, usedAt}]List profiles
POST/profiles{name}{id, name, createdAt}Create profile
GET/profiles/{id}-{id, name, createdAt, usedAt}Get profile info
DELETE/profiles/{id}-{id, deleted: true}Delete profile

Instance Management

MethodPathPayloadResponsePurpose
GET/instances-[{id, profileId, port, mode, status, startTime}]List instances
GET/instances/{id}-{id, profileId, port, mode, status, startTime}Get instance status (read-only)
POST/instances/start{profileId?, mode?, port?}{id, profileId, port, mode, status}Start instance
POST/instances/{id}/start-{status: "chrome_ready"} or {id, profileId, port, mode, status}Start browser for existing instance
POST/instances/{id}/stop-{id, stopped: true}Stop instance
GET/instances/{id}/logs-textGet instance logs

Tab Management (NEW)

MethodPathPayloadResponsePurpose
POST/tabs/new{instanceId, url?}{id, instanceId, url?, status}Create tab
GET/tabs-[{id, instanceId, url, title, type}]List all tabs
GET/tabs?instanceId={id}-[{id, instanceId, url, title}]List instance tabs
GET/tabs/{id}-{id, instanceId, url, title, type, status}Get tab info
POST/tabs/{id}/close-{id, closed: true}Close tab

Tab Operations (NEW - Replaces /instances/{id}/…)

MethodPathQuery/BodyResponsePurpose
NAVIGATE
POST/tabs/{id}/navigate{url, timeout?, blockImages?, blockAds?}{url, status, title}Navigate to URL
SNAPSHOT
GET/tabs/{id}/snapshot?interactive&compact&depth=3&maxTokens=2000{elements: [], tree: ...}Page structure
ACTION
POST/tabs/{id}/action{kind, ref?, text?, key?, value?, ...}{kind, result?, error?}Single action
POST/tabs/{id}/actions{actions: [{kind, ...}, ...]}{results: [...]}Multiple actions
TEXT & EVALUATION
GET/tabs/{id}/text?raw{text: "...", elements: [...]}Extract text
POST/tabs/{id}/evaluate{expression, await?}{result: any, type: string}Run JS
MEDIA
GET/tabs/{id}/screenshot?format=png&quality=80binary (PNG/JPEG)Screenshot
GET/tabs/{id}/pdf?landscape&margins=0.5&scale=1.0&pages=1-3binary (PDF)PDF export
COOKIES
GET/tabs/{id}/cookies-[{name, value, domain, ...}]Get cookies
POST/tabs/{id}/cookies`{action: “set""delete”, cookies: […]}`{set: [...], deleted: [...]}
LOCKING
POST/tabs/{id}/lock{owner: string, ttl: number}{locked: true, owner, expiresAt}Lock tab
POST/tabs/{id}/unlock{owner: string}{unlocked: true}Unlock tab
GET/tabs/{id}/locks-{locked: bool, owner?, expiresAt?}Check lock
FINGERPRINTING
POST/tabs/{id}/fingerprint/rotate-{rotated: true, userAgent, ...}Rotate fingerprint
GET/tabs/{id}/fingerprint/status-`{stealth: “light""full”, ua, …}`

Comparison: Old vs New

Example 1: Click Element

OLD (instance-scoped):

bash terminal
curl -X POST http://localhost:9867/instances/inst_abc123/action \  -d '{"kind": "click", "ref": "e5"}'
  • Requires instance ID
  • Path has 3 segments

NEW (tab-scoped):

bash terminal
curl -X POST http://localhost:9867/tabs/tab_xyz789/action \  -d '{"kind": "click", "ref": "e5"}'
  • Requires tab ID (which identifies instance)
  • Path has 2 segments
  • Cleaner for multi-tab workflows

Example 2: Navigate to URL

OLD:

bash terminal
curl -X POST http://localhost:9867/instances/inst_abc123/navigate \  -d '{"url": "https://example.com"}'

NEW:

bash terminal
curl -X POST http://localhost:9867/tabs/tab_xyz789/navigate \  -d '{"url": "https://example.com"}'

Example 3: Create Tab

OLD:

bash terminal
curl -X POST http://localhost:9867/instances/inst_abc123/tabs/open \  -d '{}'# Response: {id: "tab_xyz", ...}

NEW:

bash terminal
curl -X POST http://localhost:9867/tabs/new \  -d '{"instanceId": "inst_abc123"}'# Response: {id: "tab_xyz", ...}

Example 4: List tabs

OLD:

bash terminal
curl http://localhost:9867/instances/inst_abc123/tabs# Returns just tabs from that instance

NEW:

bash terminal
# All tabs (across instances)curl http://localhost:9867/tabs# Specific instancecurl http://localhost:9867/tabs?instanceId=inst_abc123

Query Parameters vs Body

Query Parameters (GET)

bash terminal
# Snapshot with optionscurl 'http://localhost:9867/tabs/tab_xyz/snapshot?interactive&compact&depth=2&maxTokens=2000'# Screenshot with formatcurl 'http://localhost:9867/tabs/tab_xyz/screenshot?format=jpeg&quality=85'# List with filtercurl 'http://localhost:9867/tabs?instanceId=inst_abc123'

Body (POST)

bash terminal
# Navigate with optionscurl -X POST http://localhost:9867/tabs/tab_xyz/navigate \  -d '{    "url": "https://example.com",    "timeout": 30,    "blockImages": true,    "blockAds": false  }'# Action (already body-based)curl -X POST http://localhost:9867/tabs/tab_xyz/action \  -d '{    "kind": "click",    "ref": "e5",    "timeout": 5  }'

HTTP Status Codes

CodeMeaningExample
200Success (GET/action)Snapshot returned, action completed
201CreatedTab created, instance started
204No contentClose successful
400Bad requestInvalid action kind, malformed JSON
404Not foundTab ID doesn’t exist, instance stopped
409ConflictTab locked by another agent, port in use
500Server errorChrome crashed, internal error
503UnavailableChrome not initialized, instance starting

Response Format

Success Response

{
  "kind": "action",
  "result": {
    "text": "Element text",
    "visible": true,
    "rect": {...}
  }
}

Error Response

{
  "error": "tab not found",
  "code": "ERR_TAB_NOT_FOUND",
  "statusCode": 404
}

Snapshot Response

{
  "elements": [
    {
      "ref": "e1",
      "tag": "button",
      "text": "Click me",
      "interactive": true,
      "rect": {"x": 100, "y": 50, "w": 80, "h": 30}
    }
  ],
  "tree": {...},
  "meta": {"count": 45, "interactive": 12}
}

CLI Command Mapping

Profile Management

bash terminal
# Listpinchtab profiles# Createpinchtab profile create my-profile# Deletepinchtab profile delete my-profile

Instance Management

bash terminal
# Listpinchtab instances# Startpinchtab instance start --profile my-profile --mode headed --port 9868# Stoppinchtab instance stop inst_abc123# Logspinchtab instance logs inst_abc123

Tab Management

bash terminal
# List all tabspinchtab tabs# List instance tabspinchtab --instance inst_abc123 tabs# Create tabpinchtab --instance inst_abc123 tab new https://example.com# → tab_xyz789# Close tabpinchtab --tab tab_xyz789 close

Tab Operations

bash terminal
# Navigatepinchtab --tab tab_xyz789 nav https://example.com# Snapshotpinchtab --tab tab_xyz789 snap -i -c# Clickpinchtab --tab tab_xyz789 click e5# Get textpinchtab --tab tab_xyz789 text# Run actioncat << 'EOF' | pinchtab --tab tab_xyz789 action{  "kind": "actions",  "actions": [    {"kind": "click", "ref": "e1"},    {"kind": "type", "ref": "e2", "text": "search"},    {"kind": "press", "key": "Enter"}  ]}EOF# Lock tab (exclusive access)pinchtab --tab tab_xyz789 lock --owner my-agent --ttl 60# Unlockpinchtab --tab tab_xyz789 unlock --owner my-agent

Full Workflow Example

Setup

bash terminal
# 1. Create profilePROF=$(pinchtab profile create my-app | jq -r .id)# 2. Start instanceINST=$(pinchtab instance start --profile my-app --mode headed | jq -r .id)# 3. Create tabTAB=$(pinchtab --instance $INST tab new | jq -r .id)

Work

bash terminal
# 4. Navigatepinchtab --tab $TAB nav https://example.com# 5. Get page structurepinchtab --tab $TAB snap -i -c | jq .# 6. Interactpinchtab --tab $TAB click e5pinchtab --tab $TAB type e12 "search text"pinchtab --tab $TAB press Enter# 7. Check resultpinchtab --tab $TAB snap -d | jq .# 8. Extract datapinchtab --tab $TAB text

Cleanup

bash terminal
# 9. Close tab (optional, instance cleanup closes all)pinchtab --tab $TAB close# 10. Stop instancepinchtab instance stop $INST

Data Flow

Request Path

Architecture Diagram ASCII
CLI Command  HTTP Request (curl or SDK)  Orchestrator Server (9867)  Tab Resolver (tab ID  instance ID)  Route to Instance (HTTP call to 9868+)  Bridge Server  Chrome (DevTools Protocol)

Response Path

Architecture Diagram ASCII
Chrome responds  Bridge returns JSON  Instance Server returns JSON  Orchestrator aggregates/proxies  CLI/SDK receives JSON

Deprecation Timeline

Phase 1 (Now - v1.0)

  • New tab endpoints available
  • Old instance endpoints still work
  • Deprecation headers on old endpoints

Phase 2 (v1.1)

  • CLI prefers --tab over --instance
  • Documentation focuses on new API
  • Users migrated gradually

Phase 3 (v2.0)

  • Old instance endpoints removed
  • Only tab-centric API