Docs
Quickstart
Pageteer is a Browser API and a Search API behind one key. Requests are JSON over HTTPS, and every response says how many credits it used and how many you have left. This page takes you from no account to a rendered page and a search in about two minutes.
1. Get an API key
Create an account (every account gets 1,000 free credits a month), open API keys in the dashboard and create a key. The full key (pk_live_ followed by 40 letters and digits) is shown once. Keep it server-side, in an environment variable:
export PAGETEER_API_KEY="pk_live_…"Building or running CI? Create a test key (pk_test_…) instead: it is free and returns realistic fake responses without fetching real sites.
Check that it works with the free usage endpoint (0 credits):
curl https://api.104-236-84-15.sslip.io/v1/usage -H "Authorization: Bearer $PAGETEER_API_KEY"{
"period": "2026-10",
"plan": "free",
"granted": 1000,
"used": 0,
"remaining": 1000,
"overage_cap": 0,
"billable": 0,
"spend_limit_cents": 0,
"estimated_cost_cents": 0,
"resets_at": "2026-11-01T00:00:00.000Z"
}2. Render a page
POST /v1/render fetches a page and returns the formats you ask for. This request uses a plain HTTP fetch (mode: "http", 1 credit) and asks for Markdown and the page's links:
curl -X POST https://api.104-236-84-15.sslip.io/v1/render \
-H "Authorization: Bearer $PAGETEER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://www.iana.org/help/example-domains","mode":"http","formats":["markdown","links"]}'const res = await fetch('https://api.104-236-84-15.sslip.io/v1/render', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.PAGETEER_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"url": "https://www.iana.org/help/example-domains",
"mode": "http",
"formats": [
"markdown",
"links"
]
}),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error.message);
console.log(data, res.headers.get('x-credits-remaining'));import os
import requests
headers = {"Authorization": f"Bearer {os.environ['PAGETEER_API_KEY']}"}
res = requests.post(
"https://api.104-236-84-15.sslip.io/v1/render",
headers=headers,
json={
"url": "https://www.iana.org/help/example-domains",
"mode": "http",
"formats": ["markdown", "links"],
},
timeout=120,
)
res.raise_for_status()
print(res.json(), res.headers["x-credits-remaining"])x-request-id: req_cb52637b80354f88977b5c7628e1ea8e
x-credits-used: 1
x-credits-remaining: 966
{
"url": "https://www.iana.org/help/example-domains",
"final_url": "https://www.iana.org/help/example-domains",
"status": 200,
"title": "Example Domains",
"markdown": "# Example Domains\n\nA number of domains such as `example.com` and `example.org` are maintained\nfor documentation purposes. …\n\n## Further Reading\n\n- [IANA-managed Reserved Domains](https://www.iana.org/domains/reserved)\n…",
"links": [
"https://www.iana.org/",
"https://www.iana.org/domains",
"https://www.iana.org/domains/reserved",
"…"
],
"tier_used": "none",
"mode_used": "http",
"attempts": [{ "tier": "none", "status": 200, "ms": 210 }],
"cached": false,
"credits": 1
}statusis the target site's HTTP status. A 404 page is still a successful render (and is charged), so check it.- Pages that need JavaScript: send
mode: "browser"(5 credits). Leavemodeout (auto) and the engine decides; you pay for the mode it used. - Sites that block bots: add
unblock: "auto". See Unblocking tiers.
3. Search the web
GET /v1/search returns web results as JSON (2 credits; answers served from the shared 6-hour search cache cost 0).
curl "https://api.104-236-84-15.sslip.io/v1/search?q=headless+browser+api&n=3" \
-H "Authorization: Bearer $PAGETEER_API_KEY"const res = await fetch(`https://api.104-236-84-15.sslip.io/v1/search?${new URLSearchParams({"q":"headless browser api","n":"3"})}`, {
headers: { Authorization: `Bearer ${process.env.PAGETEER_API_KEY}` },
});
const data = await res.json();
if (!res.ok) throw new Error(data.error.message);
console.log(data, res.headers.get('x-credits-remaining'));import os
import requests
headers = {"Authorization": f"Bearer {os.environ['PAGETEER_API_KEY']}"}
res = requests.get(
"https://api.104-236-84-15.sslip.io/v1/search",
headers=headers,
params={
"q": "headless browser api",
"n": 3,
},
timeout=120,
)
res.raise_for_status()
print(res.json(), res.headers["x-credits-remaining"])x-cache: MISS
x-credits-used: 2
{
"query": "headless browser api",
"results": [
{
"title": "BrowserCat | Headless Browser API",
"url": "https://www.browsercat.com/",
"snippet": "You connect to a single endpoint. BrowserCat picks the backend best suited to each job …",
"engine": "metacrawler",
"engines": ["swisscows", "metacrawler", "yandex"],
"published_date": null,
"position": 1
},
{
"title": "Headless Browser API - HeadlessBrowserAPI",
"url": "https://headlessbrowserapi.com/",
"snippet": "HeadlessBrowserAPI handles JavaScript rendering using headless browsers …",
"engine": "metacrawler",
"engines": ["swisscows", "metacrawler", "yandex"],
"published_date": null,
"position": 2
}
],
"unresponsive_engines": [],
"cached": false,
"credits": 2
}4. Or use the JavaScript client
@pageteer/client wraps every endpoint with types, retries on 429/5xx, job polling and typed errors:
import { Pageteer } from '@pageteer/client';
const pageteer = new Pageteer(); // reads PAGETEER_API_KEY
const page = await pageteer.render('https://www.iana.org/help/example-domains', { mode: 'http', formats: ['markdown'] });
const hits = await pageteer.search('headless browser api', { n: 3 });
console.log(page.title, hits.results[0]?.url, hits.meta.creditsRemaining);Using an AI coding agent or assistant? The MCP server gives it web search and page fetching as tools.
5. Handle errors
Errors are JSON with a stable error.code. Only successful responses are charged: every error is free.
{
"error": {
"code": "forbidden_target",
"message": "Private, loopback and reserved network targets are not allowed"
}
}Retry 429 (after Retry-After) and 5xx with backoff; fix the request for other 4xx. The errors reference lists every code and what to do.
Next steps
- Authentication & headers: the headers every response carries.
- Endpoints: render, screenshot, pdf, extract, crawl, map, batch, monitors, search, usage.
- Scroll, click "Load more" or wait before a capture: page actions.
- Many URLs at once: async jobs & polling and webhooks.
- How credits work, unblocking tiers and rate limits.
- Clients: SDKs & integrations (JavaScript, Python, LangChain, n8n, MCP).
- Machine-readable: the OpenAPI 3.1 spec at
https://api.104-236-84-15.sslip.io/openapi.json.
Base URL: https://api.104-236-84-15.sslip.io (all endpoints are under /v1). Please read the Acceptable Use Policy before you start: no logins, checkouts or form submissions, and no personal-data harvesting.