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
The Navigation API allows you to:
- Navigate tabs to URLs
- Wait for page load states
- Block resources (images, media, ads)
- Control navigation timeouts
- Wait for specific selectors
Navigate Tab
Navigate an existing tab to a URL.
curl -X POST http://localhost:9867/tabs/tab_abc123/navigate \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com"}'
Request Body
URL to navigate to. Can include protocol or be a bare hostname (e.g., example.com → https://example.com)
Navigation timeout in seconds (1-120)
Wait condition: none, dom, selector, networkidle
CSS selector to wait for (required if waitFor=selector)
Wait for title change (seconds, max 30)
Block media resources (video, audio)
Response (200 OK)
{
"tabId": "tab_abc123",
"url": "https://example.com",
"title": "Example Domain"
}
Response Fields
Tab ID that was navigated
Final URL (may differ from requested URL due to redirects)
Wait Conditions
Control when navigation completes using waitFor:
none (default)
Returns as soon as navigation starts. Fastest but may not wait for content.
{
"url": "https://example.com",
"waitFor": "none"
}
dom
Waits for document.readyState === "complete". Good for most pages.
{
"url": "https://example.com",
"waitFor": "dom"
}
selector
Waits for a specific CSS selector to be visible. Use for dynamic content.
{
"url": "https://example.com",
"waitFor": "selector",
"waitSelector": "#content"
}
networkidle
Waits for network activity to settle (no requests for ~500ms). Best for SPAs.
{
"url": "https://example.com",
"waitFor": "networkidle"
}
Network idle waits up to ~3 seconds for stability. Use timeouts to prevent hanging.
Resource Blocking
Block resources to speed up navigation and reduce bandwidth:
Block Images
curl -X POST http://localhost:9867/tabs/tab_abc123/navigate \
-d '{
"url": "https://example.com",
"blockImages": true
}'
Blocks: *.jpg, *.png, *.gif, *.webp, *.svg
curl -X POST http://localhost:9867/tabs/tab_abc123/navigate \
-d '{
"url": "https://example.com",
"blockMedia": true
}'
Blocks: *.mp4, *.webm, *.ogg, *.mp3, *.wav, images
Block Ads
curl -X POST http://localhost:9867/tabs/tab_abc123/navigate \
-d '{
"url": "https://example.com",
"blockAds": true
}'
Blocks known ad domains and trackers.
Combine blocking options for maximum speed:
{
"url": "https://example.com",
"blockImages": true,
"blockMedia": true,
"blockAds": true
}
Examples
Basic Navigation
import requests
BASE = "http://localhost:9867"
# Start instance and open tab
inst = requests.post(f"{BASE}/instances/start",
json={"mode": "headed"}).json()
tab = requests.post(f"{BASE}/instances/{inst['id']}/tabs/open",
json={}).json()
tab_id = tab["tabId"]
# Navigate
resp = requests.post(f"{BASE}/tabs/{tab_id}/navigate",
json={"url": "https://example.com"})
result = resp.json()
print(f"URL: {result['url']}")
print(f"Title: {result['title']}")
Wait for Selector
curl -X POST http://localhost:9867/tabs/tab_abc123/navigate \
-H "Content-Type: application/json" \
-d '{
"url": "https://github.com",
"waitFor": "selector",
"waitSelector": ".dashboard",
"timeout": 30
}'
Navigate with Resource Blocking
const resp = await fetch(
"http://localhost:9867/tabs/tab_abc123/navigate",
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
url: "https://news.ycombinator.com",
blockImages: true,
blockMedia: true,
blockAds: true,
waitFor: "dom"
})
}
);
const result = await resp.json();
console.log(`Loaded: ${result.title}`);
Sequential Navigation
import requests
import time
BASE = "http://localhost:9867"
tab_id = "tab_abc123"
sites = [
"https://example.com",
"https://google.com",
"https://github.com"
]
for site in sites:
print(f"Navigating to {site}...")
resp = requests.post(f"{BASE}/tabs/{tab_id}/navigate",
json={"url": site, "waitFor": "dom"})
result = resp.json()
print(f" Title: {result['title']}")
time.sleep(2) # Wait before next navigation
Error Handling
Invalid URL (400)
curl -X POST http://localhost:9867/tabs/tab_abc123/navigate \
-d '{"url":"javascript:alert(1)"}'
Response:
{
"error": "invalid URL scheme: javascript",
"statusCode": 400
}
Blocked schemes: javascript:, vbscript:, data:
Navigation Timeout (500)
curl -X POST http://localhost:9867/tabs/tab_abc123/navigate \
-d '{"url":"https://example.com","timeout":1}'
Response:
{
"error": "navigate: context deadline exceeded",
"statusCode": 500
}
Selector Not Found (400)
curl -X POST http://localhost:9867/tabs/tab_abc123/navigate \
-d '{
"url":"https://example.com",
"waitFor":"selector",
"waitSelector":"#nonexistent"
}'
Response:
{
"error": "selector #nonexistent not found",
"code": "bad_wait_for",
"statusCode": 400
}
Tab Not Found (404)
curl -X POST http://localhost:9867/tabs/nonexistent/navigate \
-d '{"url":"https://example.com"}'
Response:
{
"error": "tab not found",
"statusCode": 404
}
Complete Workflow
#!/bin/bash
BASE="http://localhost:9867"
# 1. Start instance
INST=$(curl -s -X POST $BASE/instances/start \
-d '{"mode":"headed"}' | jq -r '.id')
# 2. Open tab
TAB=$(curl -s -X POST "$BASE/instances/$INST/tabs/open" \
-d '{}' | jq -r '.tabId')
echo "Tab: $TAB"
# 3. Navigate to login page
echo "Navigating to login..."
curl -s -X POST "$BASE/tabs/$TAB/navigate" \
-d '{
"url":"https://example.com/login",
"waitFor":"selector",
"waitSelector":"#email",
"timeout":30
}' | jq '{url, title}'
# 4. Get page structure
echo -e "\nGetting page structure..."
curl -s "$BASE/tabs/$TAB/snapshot?filter=interactive" \
| jq '.nodes[] | {ref, role, name}' | head -10
# 5. Navigate to another page
echo -e "\nNavigating to dashboard..."
curl -s -X POST "$BASE/tabs/$TAB/navigate" \
-d '{
"url":"https://example.com/dashboard",
"waitFor":"networkidle",
"blockImages":true
}' | jq '{url, title}'
# 6. Cleanup
curl -s -X POST "$BASE/instances/$INST/stop"
Best Practices
Use Appropriate Wait Conditions
- Static pages:
waitFor: "dom"
- SPAs (React, Vue):
waitFor: "networkidle"
- Specific content:
waitFor: "selector" with waitSelector
- Fast navigation:
waitFor: "none" (but check status manually)
Set Reasonable Timeouts
{
"url": "https://example.com",
"timeout": 30, // 30 seconds is usually enough
"waitFor": "dom"
}
Default timeout is 30 seconds. Increase for slow pages, decrease for fast pages.
Block Resources for Speed
{
"url": "https://example.com",
"blockImages": true, // Faster page load
"blockMedia": true, // Save bandwidth
"blockAds": true // Cleaner content
}
Handle Redirects
The response url field contains the final URL after redirects:
resp = requests.post(f"{BASE}/tabs/{tab_id}/navigate",
json={"url": "http://example.com"})
result = resp.json()
print(f"Requested: http://example.com")
print(f"Final URL: {result['url']}") # May be https://example.com
GET Method Support
Navigation also supports GET requests for convenience:
curl "http://localhost:9867/navigate?url=https://example.com&tabId=tab_abc123"
This is equivalent to the POST method but uses query parameters.
Next Steps
Snapshot API
Get page structure after navigation
Actions API
Interact with page elements
Screenshots
Capture page screenshots
Evaluation
Execute JavaScript in pages