Skip to content
home / kit / browser
BrowserKit Service

Chromium at a URL

Headless or visible Chromium, controllable through a flat HTTP API. Stealth on by default, CDP WebSocket returned at /start — point Puppeteer, Playwright, or any CDP client at it.

PROJECT-CONTAINER-browser-1.SERVER.containers.hoody.com
GET /start?browser_id=main&stealth=true&timezoneId=America/New_York
200 OK

# Spawn a stealth Chromium with a fingerprint

$ curl "/start?browser_id=main&stealth=true&timezoneId=America/New_York&locale=en-US"

[ "browser_id": "main",

"webSocketDebuggerUrl": "ws://.../devtools/browser/...",

"stealth": true ]

 

# Navigate — or pass the WS URL to Puppeteer

$ curl "/browse?browser_id=main&url=https://hoody.com"

200 OK

 

# Capture; already works with your existing CDP client

$ curl "/screenshot?browser_id=main&format=png" -o shot.png

1920x1080 PNG

home / kit / browser / demo
Three endpoint classes, one URL

Drive, observe, and inspect a real browser over HTTP

Every Browser instance exposes the same primitives Puppeteer and Playwright rely on — navigation, DOM eval, screenshots, DevTools Protocol — but as flat HTTP endpoints. Pick a tab below to see which endpoint runs under the hood.

01 / 05

Start an instance, point it at a URL

GET /start spawns a stealth Chromium with your fingerprint. GET /browse?url=… loads a page. One HTTP roundtrip, no driver install, no docker image to maintain.

curl /start?stealth=true → ready
02 / 05

Eval JS in the page, return structured data

POST /eval runs arbitrary JavaScript in page context. GET /html and GET /text return the rendered DOM and visible text. No selector library, no headless-browser SDK.

POST /eval → [ "Headline 1", "Headline 2", … ]
03 / 05

Screenshot or PDF the current page

GET /screenshot returns PNG, JPEG, or base64 — fullPage or viewport. GET /pdf renders to A4/Letter with landscape + margins. Binary comes back directly; no headless-Chrome flags to wrangle.

GET /screenshot?fullPage=true → PNG binary
04 / 05

Grab the CDP URLs, hand them to anything

GET /devtools-url returns three URLs: the CDP WebSocket (for Puppeteer / Playwright / any CDP client), the DevTools HTTP API, and the DevTools frontend UI. Open the frontend URL in a browser tab to watch what the headless instance sees.

GET /devtools-url → [ ws, http, frontend ]
05 / 05

Screenshot → decide → click, in a loop

The shape every Computer-Use model expects: a screenshot, a DOM snapshot, a way to click at (x, y). Browser exposes these over plain HTTP — drop it behind Claude Computer Use, OpenAI's Operator, or your own agent.

loop: screenshot → eval('click(x,y)')
Before· Traditional headless

docker run chromium + fonts + fingerprint patches

After· Hoody Browser

curl /start?stealth=true → ready

home / kit / browser / api
API

Start, drive, and tear down Chromium over HTTP

Every endpoint returns deterministic JSON or binary. No stderr scraping, no /tmp files, no race conditions with a subprocess that forgot to flush.

browser-api.sh

# Full Browser flow — start, navigate, extract, shutdown

 

URL="https://proj-dev-browser-1.hoody.com"

ID="main"

 

# 1. Spawn a stealth Chromium

curl -s "$URL/start?browser_id=$ID&stealth=true"

 

# 2. Navigate

curl -s "$URL/browse?browser_id=$ID&url=https://hoody.com"

 

# 3. Extract structured data

curl -s -X POST "$URL/eval?browser_id=$ID" \

-H 'Content-Type: application/json' \

-d '["script":"document.title"]'

# > "Example Domain"

 

# 4. Release the slot

curl -s "$URL/shutdown?browser_id=$ID"

browser-api.js

// Full Browser flow — start, navigate, extract, shutdown

const BASE = 'https://proj-dev-browser-1.hoody.com';

const id = 'main';

 

// 1. Spawn a stealth Chromium

const start = await fetch(`$[BASE]/start?browser_id=$[id]&stealth=true`);

const [ webSocketDebuggerUrl ] = await start.json();

 

// 2. Navigate

await fetch(`$[BASE]/browse?browser_id=$[id]&url=https://hoody.com`);

 

// 3. Extract structured data

const r = await fetch(`$[BASE]/eval?browser_id=$[id]`, [

method: 'POST',

headers: [ 'Content-Type': 'application/json' ],

body: JSON.stringify([ script: 'document.title' ])

]);

const title = await r.json();

// => "Example Domain"

 

// 4. Release the slot

await fetch(`$[BASE]/shutdown?browser_id=$[id]`);

browser_api.py

# Full Browser flow — start, navigate, extract, shutdown

import requests

 

BASE = 'https://proj-dev-browser-1.hoody.com'

id = 'main'

 

# 1. Spawn a stealth Chromium

start = requests.get(f'[BASE]/start', params=['browser_id': id, 'stealth': 'true'])

ws = start.json()['webSocketDebuggerUrl']

 

# 2. Navigate

requests.get(f'[BASE]/browse', params=['browser_id': id, 'url': 'https://hoody.com'])

 

# 3. Extract structured data

r = requests.post(f'[BASE]/eval',

params=['browser_id': id],

json=['script': 'document.title'])

title = r.json()

# => "Example Domain"

 

# 4. Release the slot

requests.get(f'[BASE]/shutdown', params=['browser_id': id])

home / kit / browser / used-for
Used for

Where teams deploy Browser

A flat HTTP layer over Chromium opens up integration points that a locally-installed headless browser can't cover. Six deployment shapes we see most often.

{01}

Data pipelines

Ingest rendered HTML and JSON into your warehouse. Cron the /eval calls, pipe results into Snowflake, BigQuery, or Postgres. No per-worker Chromium install, no version drift across your cluster.

{02}

Agent frameworks

Plug into Claude Computer Use, OpenAI Operator, or LangChain browser tools. Screenshot + eval is the shape they already expect — Browser is a drop-in HTTP endpoint for whatever agent runtime you use.

{03}

Authenticated workflows

Drive logged-in dashboards — SaaS admin panels, bank portals, internal tools. POST /cookies persists the session, so subsequent calls keep the identity without re-authenticating on every run.

{04}

Review apps

Per-PR browser previews. Your CI spawns a Browser instance against the staged build, returns the /devtools-url frontend link in the PR comment, reviewers click once and watch the app live.

{05}

Scheduled monitoring

Cron-triggered /screenshot and /network captures into uptime, SLO, and perf dashboards. Ring-buffer the last 500 console and network entries for each probe — surface regressions before users do.

{06}

Compliance snapshots

Timestamped, fingerprint-locked captures of a third-party page for legal, audit, or evidence workflows. Pin the Chromium channel, the viewport, the geolocation — reproduce the exact render months later.

home / kit / browser / endpoints
API

23 operations, 4 endpoint groups

Every Browser capability is a flat HTTP call. Method variants on the same path are listed separately because they behave differently — GET /eval runs a one-shot script, POST /eval accepts a full body.

Interaction

[count, plural, one [# endpoint] other [# endpoints]]'

curl -X POST /eval -d '["script":"document.title"]' → "Example"

POST
/browseNavigate with a JSON body — waitUntil, timeout, referer, headers.
GET
/browse?url=Shorthand navigation for curl-from-shell ergonomics.
POST
/evalExecute JavaScript (plain or base64) in page context, return the result.
GET
/eval?script=Inline-script eval for one-shot reads like document.title.
GET
/htmlReturn document.documentElement.outerHTML — rendered, not raw.
GET
/textReturn document.body.innerText — what a human reads.
GET
/screenshotPNG / JPEG / base64 — fullPage supported, JPEG quality 0-100.
GET
/pdfRender to PDF — A4/Letter, landscape, margins, printBackground.

Session state

[count, plural, one [# endpoint] other [# endpoints]]'

curl -X POST /cookies -d '[[name,value,domain,...]]' → [ added: 4 ]

GET
/cookiesList cookies, optionally filtered by URL.
POST
/cookiesAdd cookies — name, value, domain, path, httpOnly, secure, sameSite.
DELETE
/cookiesClear all cookies for the instance.
GET
/metadataFull instance metadata — session, viewport, DevTools URLs, tab list.
GET
/tabsList open tabs with id, url, title, isActive.
POST
/tab/closeClose a tab by id — or the active tab if none specified.

Introspection

[count, plural, one [# endpoint] other [# endpoints]]'

curl /devtools-url?browser_id=main → [ ws, http, frontend ]

GET
/devtools-urlReturn CDP WebSocket + DevTools HTTP + frontend UI URLs.
GET
/consoleLast 500 console entries — log, error, warn, info.
GET
/networkLast 500 network entries — method, URL, status, resourceType.
GET
/historyPaginated persistent browsing history with domain + time filters.
DELETE
/historyDelete history entries matching the filter.

Lifecycle

[count, plural, one [# endpoint] other [# endpoints]]'

curl /start?browser_id=main&stealth=true → [ ws, stealth: true ]

GET
/startCreate or resume an instance with browser_id, fingerprint, stealth, proxy, viewport.
GET
/stopPause an instance — state persists. Use /restart to resume.
GET
/restartStop and re-spawn with optionally-updated config.
GET
/shutdownTerminate the instance and free the slot. ?force=true kills stuck instances.

Plus platform-inherited GET /health and GET /metrics on every Hoody Kit service.

home / kit / browser / capabilities
Capabilities

Stealth, fingerprinting, and CDP — without the setup tax

Browser is a thin layer over Chromium — everything you'd install, patch, and babysit is a query parameter away. Six capabilities that matter when you actually ship.

Fingerprint spoofing
Patchright stealth
CDP WebSocket
Proxy (SOCKS5/HTTP)
DNS-over-HTTPS
Chromium channels
Firefox backend
500-entry console ring
500-entry network ring
Persistent history
Fingerprint spoofing
Patchright stealth
CDP WebSocket
Proxy (SOCKS5/HTTP)
DNS-over-HTTPS
Chromium channels
Firefox backend
500-entry console ring
500-entry network ring
Persistent history
Fingerprint spoofing
Patchright stealth
CDP WebSocket
Proxy (SOCKS5/HTTP)
DNS-over-HTTPS
Chromium channels
Firefox backend
500-entry console ring
500-entry network ring
Persistent history
Fingerprint spoofing
Patchright stealth
CDP WebSocket
Proxy (SOCKS5/HTTP)
DNS-over-HTTPS
Chromium channels
Firefox backend
500-entry console ring
500-entry network ring
Persistent history
POST /cookies auth
JS eval in page
PNG / JPEG / PDF capture
Mobile fingerprints
Tablet viewports
Custom UA strings
Geolocation override
QUIC / HTTP3 opt-in
Persistent browser_id
POST /cookies auth
JS eval in page
PNG / JPEG / PDF capture
Mobile fingerprints
Tablet viewports
Custom UA strings
Geolocation override
QUIC / HTTP3 opt-in
Persistent browser_id
POST /cookies auth
JS eval in page
PNG / JPEG / PDF capture
Mobile fingerprints
Tablet viewports
Custom UA strings
Geolocation override
QUIC / HTTP3 opt-in
Persistent browser_id
POST /cookies auth
JS eval in page
PNG / JPEG / PDF capture
Mobile fingerprints
Tablet viewports
Custom UA strings
Geolocation override
QUIC / HTTP3 opt-in
Persistent browser_id

Fingerprint spoofing

Configure UA, viewport, timezone, locale, and geolocation on /start — or point at a fingerprintId to load a preset JSON. Canvas and WebGL follow the profile automatically.

Stealth mode

Patchright anti-detection is on by default for Chromium. Not bulletproof against every detection vendor — pair with a CAPTCHA-solving provider for adversarial sites.

CDP pass-through

GET /devtools-url returns the WebSocket URL, DevTools HTTP API, and frontend UI. Existing Puppeteer or Playwright code keeps working — connect, don't rewrite.

Proxy & DoH

SOCKS5, SOCKS5h, HTTP, HTTPS proxies with auth and bypass lists. DNS-over-HTTPS via Cloudflare is default on. QUIC/HTTP3 opt-in per instance.

Chromium channels

Pin any Chromium build — full version string, major version, or channel (stable / beta / dev / canary). Firefox also supported via browser=firefox.

Debug ring buffers

Last 500 console entries and 500 network entries per instance, plus persistent browsing history with query and delete endpoints. No need to wire an external logging layer.

home / kit / browser / start

Add a real browser to your stack

Browser is one of the Hoody Kit services bundled with every container. No driver install, no Puppeteer scaffolding, no fingerprint patching. Start with a URL.

Read the Docs