Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/pinchtab/pinchtab/llms.txt

Use this file to discover all available pages before exploring further.

Overview

Tabs are individual browser pages within an instance. Each tab:
  • Has a unique ID in format tab_XXXXXXXX
  • Belongs to a specific instance
  • Can navigate to different URLs
  • Maintains its own state (cookies inherited from profile)
  • Can be locked for multi-agent coordination
Tab IDs use hash-based format (tab_XXXXXXXX) for security. Raw Chrome DevTools Protocol target IDs are never exposed.

List All Tabs

Get all tabs across all instances, or filter by instance.
GET /tabs
curl http://localhost:9867/tabs | jq .

Query Parameters

instanceId
string
Filter tabs to a specific instance

Response

[
  {
    "id": "tab_abc123",
    "instanceId": "inst_xyz",
    "url": "https://example.com",
    "title": "Example Domain",
    "status": "ready",
    "createdAt": "2026-03-01T05:25:30Z"
  },
  {
    "id": "tab_def456",
    "instanceId": "inst_xyz",
    "url": "https://google.com",
    "title": "Google",
    "status": "ready",
    "createdAt": "2026-03-01T05:26:00Z"
  }
]

Response Fields

id
string
required
Tab ID (format: tab_XXXXXXXX)
instanceId
string
required
Instance ID that owns this tab
url
string
required
Current URL
title
string
required
Page title
status
string
required
Tab status: ready, loading, error
createdAt
string
required
ISO 8601 timestamp when tab was created

Open Tab

Create a new tab in an instance.
POST /instances/{id}/tabs/open
curl -X POST http://localhost:9867/instances/inst_xyz/tabs/open \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com"}'

Request Body

url
string
URL to navigate to after opening tab. If omitted, opens a blank tab.

Response (201 Created)

{
  "tabId": "tab_abc123",
  "url": "https://example.com",
  "title": "Example Domain"
}
Every call to this endpoint creates a new tab. Use /tabs/{id}/navigate to navigate an existing tab.

Get Tab Info

Get details for a specific tab.
GET /tabs/{id}
curl http://localhost:9867/tabs/tab_abc123 | jq .

Response (200 OK)

{
  "id": "tab_abc123",
  "instanceId": "inst_xyz",
  "url": "https://example.com",
  "title": "Example Domain",
  "status": "ready",
  "createdAt": "2026-03-01T05:25:30Z"
}

Close Tab

Close a tab and remove it from the instance.
POST /tabs/{id}/close
curl -X POST http://localhost:9867/tabs/tab_abc123/close

Response (200 OK)

{
  "id": "tab_abc123",
  "status": "closed"
}
Closed tabs cannot be reopened. Create a new tab if needed.

Lock Tab

Lock a tab to prevent concurrent access (useful for multi-agent scenarios).
POST /tabs/{id}/lock
curl -X POST http://localhost:9867/tabs/tab_abc123/lock \
  -H "Content-Type: application/json" \
  -d '{
    "owner": "agent-1",
    "ttl": 120
  }'

Request Body

owner
string
required
Unique identifier for the agent/user locking the tab
ttl
integer
default:"60"
Time-to-live in seconds. Lock expires after this duration.

Response (200 OK)

{
  "locked": true,
  "owner": "agent-1",
  "expiresAt": "2026-03-03T12:34:56Z"
}

Unlock Tab

Release a tab lock.
POST /tabs/{id}/unlock
curl -X POST http://localhost:9867/tabs/tab_abc123/unlock \
  -H "Content-Type: application/json" \
  -d '{
    "owner": "agent-1"
  }'

Request Body

owner
string
required
Owner who locked the tab (must match)

Response (200 OK)

{
  "unlocked": true
}
If the owner doesn’t match, returns 423 Locked error.

Complete Workflow Example

#!/bin/bash

BASE="http://localhost:9867"

# 1. Start instance
INST=$(curl -s -X POST $BASE/instances/start \
  -d '{"mode":"headed"}' | jq -r '.id')
echo "Instance: $INST"

# 2. Open first tab
TAB1=$(curl -s -X POST "$BASE/instances/$INST/tabs/open" \
  -d '{"url":"https://example.com"}' | jq -r '.tabId')
echo "Tab 1: $TAB1"

# 3. Open second tab
TAB2=$(curl -s -X POST "$BASE/instances/$INST/tabs/open" \
  -d '{"url":"https://google.com"}' | jq -r '.tabId')
echo "Tab 2: $TAB2"

# 4. List all tabs in instance
echo -e "\nTabs in instance:"
curl -s "$BASE/tabs?instanceId=$INST" | jq '.[] | {id, url, title}'

# 5. Get info on tab 1
echo -e "\nTab 1 info:"
curl -s "$BASE/tabs/$TAB1" | jq .

# 6. Lock tab 2
curl -s -X POST "$BASE/tabs/$TAB2/lock" \
  -d '{"owner":"my-script","ttl":300}' | jq .

# 7. Do work...
sleep 2

# 8. Unlock tab 2
curl -s -X POST "$BASE/tabs/$TAB2/unlock" \
  -d '{"owner":"my-script"}' | jq .

# 9. Close tabs
curl -s -X POST "$BASE/tabs/$TAB1/close" | jq .
curl -s -X POST "$BASE/tabs/$TAB2/close" | jq .

# 10. Stop instance
curl -s -X POST "$BASE/instances/$INST/stop" | jq .

Multi-Agent Example

import requests
import time
from contextlib import contextmanager

BASE = "http://localhost:9867"
AGENT_ID = "agent-1"

@contextmanager
def locked_tab(tab_id, owner, ttl=300):
    """Context manager for tab locking"""
    # Lock
    requests.post(f"{BASE}/tabs/{tab_id}/lock",
        json={"owner": owner, "ttl": ttl})
    
    try:
        yield tab_id
    finally:
        # Always unlock
        requests.post(f"{BASE}/tabs/{tab_id}/unlock",
            json={"owner": owner})

# Start instance
inst = requests.post(f"{BASE}/instances/start",
    json={"mode": "headed"}).json()

# Open tab
tab = requests.post(f"{BASE}/instances/{inst['id']}/tabs/open",
    json={"url": "https://example.com"}).json()

tab_id = tab["tabId"]

# Use locked tab
with locked_tab(tab_id, AGENT_ID):
    # Tab is locked - only this agent can interact
    
    # Navigate
    requests.post(f"{BASE}/tabs/{tab_id}/navigate",
        json={"url": "https://google.com"})
    
    time.sleep(2)
    
    # Get snapshot
    snapshot = requests.get(
        f"{BASE}/tabs/{tab_id}/snapshot?filter=interactive"
    ).json()
    
    print(f"Elements: {len(snapshot['nodes'])}")

# Tab automatically unlocked when exiting context

# Cleanup
requests.post(f"{BASE}/instances/{inst['id']}/stop")

Tab Status Values

StatusDescription
readyTab is loaded and ready to accept commands
loadingTab is navigating to a URL
errorTab failed to load

Error Handling

Instance Not Found (404)

curl -X POST http://localhost:9867/instances/nonexistent/tabs/open \
  -d '{"url":"https://example.com"}'
Response:
{
  "error": "instance not found",
  "statusCode": 404
}

Tab Not Found (404)

curl http://localhost:9867/tabs/nonexistent
Response:
{
  "error": "tab not found",
  "statusCode": 404
}

Tab Locked (423)

curl -X POST http://localhost:9867/tabs/tab_abc123/action \
  -H "X-Owner: agent-2" \
  -d '{"kind":"click","ref":"e5"}'
Response (if locked by agent-1):
{
  "error": "tab tab_abc123 is locked by agent-1",
  "code": "tab_locked",
  "statusCode": 423
}

Best Practices

Tab Lifecycle

# 1. Open tab
TAB=$(curl -s -X POST $BASE/instances/$INST/tabs/open -d '{}' | jq -r .tabId)

# 2. Do work
curl -X POST "$BASE/tabs/$TAB/navigate" -d '{"url":"https://example.com"}'

# 3. Get results
curl "$BASE/tabs/$TAB/snapshot"

# 4. Close tab
curl -X POST "$BASE/tabs/$TAB/close"

Resource Management

Always close tabs when done:
# Close all tabs in instance
for tab in $(curl -s "$BASE/tabs?instanceId=$INST" | jq -r '.[].id'); do
  curl -s -X POST "$BASE/tabs/$tab/close"
done

Use Locks for Safety

Use tab locks in multi-agent scenarios:
# Lock before operations
requests.post(f"{BASE}/tabs/{tab_id}/lock",
    json={"owner": AGENT_ID, "ttl": 300})

try:
    # Do work
    requests.post(f"{BASE}/tabs/{tab_id}/action", ...)
finally:
    # Always unlock
    requests.post(f"{BASE}/tabs/{tab_id}/unlock",
        json={"owner": AGENT_ID})

Next Steps

Navigation

Navigate tabs to URLs

Snapshot

Get page structure (accessibility tree)

Actions

Click, type, and interact with pages

Screenshots

Capture screenshots