Drive a browser like an agent.
Open a persistent session and steer it in plain English — navigate, act, observe, extract — or send a deterministic JSON action macro when you already know the page. Multi-step journeys across login walls and dynamic apps, without a single line of Playwright.
For single-page extraction see the scraping API; for raw headless-session control see the browser API.
Intelligent actions, persistent state, zero browser ops.
Natural-language actions
Tell the session what to do in plain English — goto, act, observe, extract. The model resolves each instruction to a concrete element and action (click, type, select, scroll), so a copy change on the target site does not break your script. No selectors to babysit.
Persistent agent sessions
Open a session once and drive it across many calls. Cookies, storage, and the logged-in context stay alive between steps, so multi-page journeys — log in, navigate, act, extract — run as one coherent flow instead of disconnected requests.
JSON action macros too
When you already know the page, skip the model and send a deterministic JSON array of click / type / wait / scroll steps to the scraping endpoint. Same hosted browser, fully reproducible, zero per-step model latency. Mix and match per task.
No Playwright fleet to run
You write instructions, not browser code. There is no headless Chrome to deploy, no Puppeteer or Playwright scripts to maintain, no stealth tuning — the hosted browser handles fingerprinting and rendering. Bring a managed model (no key required), or bring your own.
Drive it four ways.
Open a session, act in plain English, observe, extract — or fall back to deterministic macros and raw session control.
# Open a persistent, LLM-driven browser session.
# Free to open — you only pay per action (goto/act/observe/extract).
curl -X POST https://api.ollagraph.com/v1/stagehand \
-H "Authorization: Bearer $OLLAGRAPH_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
# -> { "stagehand_session_id": "sh_...", "llm_provider": "...",
# "model_name": "...", "expires_at": "..." }
# Bring your own model instead (held in memory for the session only):
# {"llm_provider": "openai", "model_name": "...", "llm_api_key": "sk-..."} # Drive the session in plain English — no selectors to maintain.
SID=sh_...
# 1) Navigate
curl -X POST https://api.ollagraph.com/v1/stagehand/$SID/goto \
-H "Authorization: Bearer $OLLAGRAPH_API_KEY" \
-d '{"url": "https://example.com/search"}'
# 2) Act — the model resolves the instruction to a real element + action
curl -X POST https://api.ollagraph.com/v1/stagehand/$SID/act \
-H "Authorization: Bearer $OLLAGRAPH_API_KEY" \
-d '{"instruction": "type the phrase wireless headphones into the search box and press Enter"}'
# -> { "ok": true, "success": true, "message": "<selector used>", "url_after": "..." } # Observe what is actionable, then extract structured data.
SID=sh_...
# List candidate actions on the current page (optionally focus with an instruction)
curl -X POST https://api.ollagraph.com/v1/stagehand/$SID/observe \
-H "Authorization: Bearer $OLLAGRAPH_API_KEY" \
-d '{"instruction": "find the add-to-cart buttons"}'
# -> { "ok": true, "candidates": [{"description": "...", "method": "click", "selector": "..."}] }
# Pull structured data, coerced to your JSON Schema
curl -X POST https://api.ollagraph.com/v1/stagehand/$SID/extract \
-H "Authorization: Bearer $OLLAGRAPH_API_KEY" \
-d '{
"instruction": "extract the product name and price",
"schema": {"type": "object", "properties": {
"name": {"type": "string"}, "price": {"type": "number"}}}
}' # Prefer deterministic JSON macros? Drive a multi-step flow in one shot.
curl -X POST https://api.ollagraph.com/v1/scrape \
-H "Authorization: Bearer $OLLAGRAPH_API_KEY" \
-d '{
"url": "https://example.com/login",
"stealth": true,
"format": "markdown",
"actions": [
{"type": "type", "selector": "#email", "text": "[email protected]"},
{"type": "type", "selector": "#password", "text": "..."},
{"type": "click", "selector": "button[type=submit]"},
{"type": "wait", "ms": 2500},
{"type": "click", "selector": ".load-more"},
{"type": "wait", "ms": 1500}
]
}' # Raw persistent session: render + run a script across calls, keeping cookies.
SID=$(curl -s -X POST https://api.ollagraph.com/v1/session \
-H "Authorization: Bearer $OLLAGRAPH_API_KEY" | jq -r .session_id)
curl -X POST https://api.ollagraph.com/v1/session/$SID/render \
-H "Authorization: Bearer $OLLAGRAPH_API_KEY" \
-d '{"url": "https://example.com/dashboard"}'
# Reuse the same authenticated context as many times as you need, then close it.
curl -X DELETE https://api.ollagraph.com/v1/session/$SID \
-H "Authorization: Bearer $OLLAGRAPH_API_KEY" Flows that ship today.
Patterns customers run in production — each is a handful of readable calls.
Search, then extract results
goto the search page, act to type a query and submit, observe the result cards, then extract a structured list — name, price, URL — coerced to your JSON Schema. One session, four readable calls.
Multi-step authenticated journey
Open a session, act through the login form, navigate to the protected page, and extract — all on one persistent context. The cookies set during login carry forward to every later step.
Deterministic macro for known pages
When the DOM is stable, send a JSON action macro to the scraping endpoint: type credentials, click submit, wait, click load-more, return markdown. No model in the loop, fully reproducible.
Walk an infinite-scroll feed
Loop act instructions like “scroll down and load more results” until the feed stops growing, then extract everything rendered so far. The session keeps the full page state between scrolls.
Discover before you act
Not sure what is on the page? Call observe to list every actionable element with a description, method, and selector — then decide which act instructions to issue next. Great for building resilient agent loops.
Raw persistent browser control
Need lower-level control? Open a session, render URLs and run scripts inside it across calls while cookies persist, then delete it when done. See the browser API for the full session surface.
Working through a login wall? See the behind-a-login recipe, browse all recipes, or wire results to your stack with webhooks.
Automation questions
1 What is the difference between this, the scraping API, and the browser API?
What is the difference between this, the scraping API, and the browser API?
2 Do I need to write CSS selectors?
Do I need to write CSS selectors?
3 Which model powers the natural-language actions?
Which model powers the natural-language actions?
4 Are sessions persistent across calls?
Are sessions persistent across calls?
5 How do I keep a session from being reaped?
How do I keep a session from being reaped?
6 Can I get reproducible, model-free automation?
Can I get reproducible, model-free automation?
7 What does observe return, and when should I use it?
What does observe return, and when should I use it?
8 Can I extract data against a fixed shape?
Can I extract data against a fixed shape?
9 How is this billed?
How is this billed?
Skip the headless-browser fleet.
1,000 free credits, one bearer token, failed calls auto-refund. Sessions are free to open — you only pay per action.