Prerequisites
Before starting, ensure you have:
- Node.js 18+ installed
- ~500MB disk space for Camoufox browser download (happens on first run)
- curl or any HTTP client for testing
Camoufox downloads automatically on first launch (~300MB). This is a one-time download that’s cached locally.
Start the server
Clone and install
Clone the repository and install dependencies:git clone https://github.com/jo-inc/camofox-browser
cd camofox-browser
npm install
Launch the server
Start the Camofox server:You’ll see output like:{"ts":"2026-02-28T10:15:30.123Z","level":"info","msg":"server listening","port":9377}
The server runs on port 9377 by default. Change with CAMOFOX_PORT=8080 npm start.On first run, Camoufox will download the browser engine (~300MB). This takes 1-2 minutes depending on your connection.
Verify it's running
Check the health endpoint:curl http://localhost:9377/health
Response:{
"ok": true,
"engine": "camoufox",
"browserConnected": false,
"browserRunning": false,
"activeTabs": 0,
"consecutiveFailures": 0
}
browserRunning: false is normal - the browser launches lazily on first tab creation to save resources.
Your first automation
Let’s navigate to a website, get its content, and interact with an element.
Create a tab
Create a new browser tab:curl -X POST http://localhost:9377/tabs \
-H 'Content-Type: application/json' \
-d '{
"userId": "agent1",
"sessionKey": "task1",
"url": "https://example.com"
}'
Response:{
"tabId": "3f8a9b2c-1d4e-4f5a-8b9c-2d3e4f5a6b7c",
"url": "https://example.com/"
}
Save the tabId - you’ll need it for subsequent requests.
userId: Isolates cookies/storage between users (multi-tenant support)
sessionKey: Groups tabs by conversation or task
Get page snapshot
Get an accessibility snapshot with element refs:curl "http://localhost:9377/tabs/3f8a9b2c-1d4e-4f5a-8b9c-2d3e4f5a6b7c/snapshot?userId=agent1"
Response:{
"url": "https://example.com/",
"snapshot": "- heading \"Example Domain\"\n - paragraph \"This domain is for use in illustrative examples in documents.\"\n - link \"More information...\" [e1]\n",
"refsCount": 1,
"truncated": false,
"totalChars": 156,
"hasMore": false,
"nextOffset": null
}
The snapshot field contains the accessibility tree with element refs (e1, e2, etc.).Accessibility snapshots are ~90% smaller than raw HTML, saving context window tokens.
Interact with an element
Click the link using its ref e1:curl -X POST http://localhost:9377/tabs/3f8a9b2c-1d4e-4f5a-8b9c-2d3e4f5a6b7c/click \
-H 'Content-Type: application/json' \
-d '{
"userId": "agent1",
"ref": "e1"
}'
Response:{
"ok": true,
"url": "https://www.iana.org/domains/reserved",
"refsAvailable": true
}
The browser navigated to the link’s target! Notice refsAvailable: true - refs are automatically rebuilt after navigation. Try a search macro
Navigate using a search macro:curl -X POST http://localhost:9377/tabs/3f8a9b2c-1d4e-4f5a-8b9c-2d3e4f5a6b7c/navigate \
-H 'Content-Type: application/json' \
-d '{
"userId": "agent1",
"macro": "@google_search",
"query": "best coffee beans 2026"
}'
Response:{
"ok": true,
"tabId": "3f8a9b2c-1d4e-4f5a-8b9c-2d3e4f5a6b7c",
"url": "https://www.google.com/search?q=best+coffee+beans+2026",
"refsAvailable": true
}
Search macros expand to full URLs automatically. Available macros:
@google_search
@youtube_search
@amazon_search
@reddit_search
@wikipedia_search
@twitter_search
- And 8 more!
Let’s search Google by typing into the search box:
curl -X POST http://localhost:9377/tabs/YOUR_TAB_ID/navigate \
-H 'Content-Type: application/json' \
-d '{
"userId": "agent1",
"url": "https://www.google.com"
}'
Element refs reset after navigation. Always get a fresh snapshot after clicking links or submitting forms.
Scroll and get more content
For long pages, scroll down to load more content:
curl -X POST http://localhost:9377/tabs/YOUR_TAB_ID/scroll \
-H 'Content-Type: application/json' \
-d '{
"userId": "agent1",
"direction": "down",
"amount": 1000
}'
Then get a fresh snapshot:
curl "http://localhost:9377/tabs/YOUR_TAB_ID/snapshot?userId=agent1"
Close the tab
When done, close the tab:
curl -X DELETE "http://localhost:9377/tabs/YOUR_TAB_ID?userId=agent1"
Response:
Next steps
Installation
Learn about Docker, Fly.io deployment, and OpenClaw plugin setup
API reference
Explore all available endpoints and parameters
Search macros
See all 14 built-in search shortcuts
Cookie import
Import cookies for authenticated browsing (LinkedIn, Amazon, etc.)
Common workflows
curl "http://localhost:9377/tabs/YOUR_TAB_ID/links?userId=agent1&limit=50"
Returns an array of {url, text} objects.
curl "http://localhost:9377/tabs/YOUR_TAB_ID/screenshot?userId=agent1" \
-o screenshot.png
Returns a PNG image.Navigate with browser buttons
Close all tabs for a user
curl -X DELETE http://localhost:9377/sessions/agent1
Closes all tabs and deletes all cookies/storage for agent1.