Ghost Gateway
Pricing
from $30.00 / 1,000 browser minutes
Ghost Gateway
Pricing
from $30.00 / 1,000 browser minutes
Rating
0.0
(0)
Developer
Yann Feunteun
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
2 days ago
Last modified
Categories
Share
One URL that hands you an isolated, stealth Chromium over the Chrome DevTools Protocol.
Ghost Gateway is a standby Actor: it is always addressable at a single HTTPS endpoint, and each client connection gets its own browser. The gateway itself runs no browser — it allocates one in a separate Actor run, fetches that browser's real CDP endpoint, and splices the websocket through to you. You drive it with any CDP client: Playwright, Puppeteer, chrome-remote-interface, or raw websocket.
Browsers are billed per session and per minute held, so an idle integration costs nothing.
Quick start
Every request needs your Apify API token.
GATEWAY=https://<username>--ghost-gateway.apify.actor# 1. mint a sessioncurl -X POST "$GATEWAY/v1/sessions" \-H "authorization: Bearer $APIFY_TOKEN" \-H 'content-type: application/json' -d '{}'# -> {"session":"7bd58f05-…","rev":0}# 2. get a browser and its CDP websocketcurl "$GATEWAY/json/version" -H "authorization: Bearer $APIFY_TOKEN"# -> {"Browser":"Chrome/149…","webSocketDebuggerUrl":"wss://…/devtools/browser/…"}
Then connect with your CDP client of choice:
import { chromium } from 'playwright';const browser = await chromium.connectOverCDP(webSocketDebuggerUrl);const page = await browser.newPage();await page.goto('https://example.com');console.log(await page.title());await browser.close(); // releasing the connection releases the browser
Closing the websocket releases the browser and stops the per-minute charge.
Sessions
A session is durable identity — cookies, storage, and a pinned proxy exit — that outlives any one browser. Allocate a browser against a session, drive it, release it, and allocate another later: the second browser resumes the first one's identity. A session is not itself a billing entity; only live browsers are.
| Route | Method | Purpose |
|---|---|---|
/v1/sessions | POST | Mint a session. Returns {session, rev}. |
/v1/sessions/:session | GET | Snapshot of the session's stored state. |
/v1/sessions/:session/commit | POST | Commit cookies/storage back into the session. |
/v1/sessions/:session/browser | POST | Allocate a live browser for the session. |
/v1/sessions/:session/proxy | GET | Read the session's current proxy lease. |
/v1/sessions/:session/proxy/acquire | POST | Take a proxy lease. |
/v1/sessions/:session/proxy/rotate | POST | Rotate to a new exit IP. |
/v1/sessions/:session/mutation-lease | POST | Take a write lease, so concurrent writers don't clobber each other. |
/v1/sessions/:session/mutation-lease/renew | POST | Renew a held write lease. |
/v1/sessions/:session/mutation-lease/release | POST | Release a write lease. |
/json/version, /json/list | GET | CDP discovery. webSocketDebuggerUrl points back at the gateway. |
Session ids are scoped to the caller — you only ever see your own.
Geography
Browsers egress through residential proxies. A session's exit country is pinned when its proxy lease
is taken, and the browser's persona is made to agree with it: Accept-Language, the page's language
list, Intl locale, and timezone all match the exit rather than contradicting it.
Not every country is available; an unsupported one is refused at allocation rather than silently served from somewhere else.
Notes
- Cold starts. With no warm pool configured, the first browser of a session waits for a fresh browser Actor to start. Expect tens of seconds. Subsequent allocations against a warm gateway are much faster.
- Timeouts. Idle sessions and unclaimed browsers are reaped automatically, so a client that disappears does not leave a browser billing.
- Errors.
401means no or invalid token.404 no_sessionmeans the session id was never minted, or not by you.402means a browser was allocated but could not be charged, and was released rather than handed over.