# PageBolt — Complete API Reference > PageBolt is a web capture and browser automation API for developers. One API key gives you access to 11 endpoints: screenshot capture, PDF generation, OG image creation, multi-step browser automation (sequences), video recording, agent page observation, page inspection, content extraction, accessibility audits, ARIA tree capture, and visual diffing — plus an MCP server for AI coding assistants. Base URL: https://pagebolt.dev/api/v1 Authentication: x-api-key header (get your key at https://pagebolt.dev/dashboard) --- ## Authentication All requests require an API key via the `x-api-key` header. Query parameter authentication is not supported. ``` curl -H "x-api-key: pf_live_your_key_here" https://pagebolt.dev/api/v1/screenshot ``` ## Error Responses | Status | Meaning | |--------|---------| | 400 | Bad request — check your parameters | | 401 | Invalid or missing API key | | 402 | Monthly quota exceeded — upgrade plan | | 429 | Rate limit exceeded — slow down | | 500 | Server error — try again or contact support | ## Rate Limit Headers | Header | Description | |--------|-------------| | X-RateLimit-Limit | Requests per minute allowed | | X-RateLimit-Remaining | Requests remaining this window | | X-Usage-Current | Requests used this month | | X-Usage-Limit | Monthly request limit | ## Pricing | Plan | Price | Monthly Requests | Rate Limit | |------|-------|-----------------|------------| | Free | $0/mo | 100 | 10 req/min | | Hobby | $9/mo | 500 | 30 req/min | | Starter | $29/mo | 5,000 | 60 req/min | | Growth | $79/mo | 25,000 | 120 req/min | | Scale | $199/mo | 100,000 | 300 req/min | | Pay As You Go | usage-based | unlimited (prepaid balance) | 60 req/min | Annual billing (2 months free) is available on Hobby/Starter/Growth/Scale. Pay As You Go has no monthly commitment — enroll from Settings and top up a prepaid balance (from $0.005/request; e.g. screenshot $0.01, video $0.05). Hobby, Starter, and Growth include a 14-day free trial (card required at checkout; no charge until the trial ends). --- ## POST /v1/screenshot Capture a screenshot of a URL, raw HTML, or Markdown content. Returns binary image data (or base64 JSON with metadata). Costs 1 API request. ### Input Source (one required) | Parameter | Type | Description | |-----------|------|-------------| | url | string | URL to capture | | html | string | Raw HTML to render | | markdown | string | Markdown to render | ### Viewport | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | width | integer | 1280 | Viewport width (max 3840) | | height | integer | 720 | Viewport height (max 2160) | | deviceScaleFactor | number | 1 | Pixel ratio, 2 for retina (max 3) | | viewportDevice | string | — | Device preset, e.g. "iphone_14_pro". Overrides width/height/DPR. | | viewportMobile | boolean | false | Enable mobile meta viewport | | viewportHasTouch | boolean | false | Enable touch events | | viewportLandscape | boolean | false | Enable landscape mode | ### Output Format | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | format | string | png | png, jpeg, or webp | | quality | integer | 80 | JPEG/WebP quality 1–100 | | omitBackground | boolean | false | Transparent background (PNG/WebP only) | ### Capture Region | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | fullPage | boolean | false | Capture the full scrollable page | | selector | string | — | CSS selector for element capture | | clip | object | — | Crop region {x, y, width, height} in pixels | ### Full Page Controls | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | fullPageScroll | boolean | auto | Auto-scroll to trigger lazy-loaded images | | fullPageScrollDelay | integer | 400 | Milliseconds between scroll steps | | fullPageScrollBy | integer | viewport height | Pixels per scroll step | | fullPageMaxHeight | integer | — | Maximum screenshot height cap | ### Timing | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | delay | integer | 0 | Wait ms before capture (max 10000) | | waitUntil | string | networkidle2 | load, domcontentloaded, networkidle0, networkidle2 | | waitForSelector | string | — | Wait for CSS selector to appear before capturing | | navigationTimeout | integer | 25000 | Navigation timeout in milliseconds | ### Emulation | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | darkMode | boolean | false | Emulate dark color scheme (prefers-color-scheme: dark) | | reducedMotion | boolean | false | Reduce animations (prefers-reduced-motion) | | mediaType | string | — | "screen" or "print" | | timeZone | string | — | Timezone ID, e.g. "America/New_York" | | geolocation | object | — | {latitude, longitude, accuracy?} | ### Customization | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | userAgent | string | — | Custom User-Agent string | | cookies | array | — | Array of "name=value" strings or {name, value, domain?} objects | | headers | object | — | Extra HTTP headers for the page request | | authorization | string | — | Authorization header, e.g. "Bearer " | | bypassCSP | boolean | false | Bypass Content-Security-Policy | | hideSelectors | array | — | CSS selectors to hide before capture | | click | string | — | Click a CSS selector before capture | | injectCss | string | — | Custom CSS to inject into the page | | injectJs | string | — | Custom JavaScript to execute before capture | ### Blocking | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | blockBanners | boolean | false | Hide cookie consent banners (GDPR popups, OneTrust, CookieBot, etc.) | | blockAds | boolean | false | Block advertisements | | blockChats | boolean | false | Block live chat widgets (Intercom, Crisp, Drift, etc.) | | blockTrackers | boolean | false | Block analytics trackers (GA, Hotjar, Segment, etc.) | | blockRequests | array | — | URL patterns to block (substring match) | | blockResources | array | — | Resource types to block: document, stylesheet, image, media, font, script, xhr, fetch, etc. | ### Metadata | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | extractMetadata | boolean | false | Extract page metadata (title, description, OG tags, favicon, HTTP status, canonical, lang) | ### Response Format | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | response_type | string | binary | Set to "json" for base64-encoded response with metadata | When response_type is "json" and extractMetadata is true, the response includes: ```json { "data": "iVBORw0KGgo...", "format": "png", "content_type": "image/png", "size_bytes": 284512, "duration_ms": 1243, "metadata": { "title": "Page Title", "description": "Meta description", "ogTitle": "OG Title", "ogDescription": "OG Description", "ogImage": "https://example.com/og.png", "ogType": "website", "favicon": "/favicon.ico", "httpStatusCode": 200, "canonical": "https://example.com", "lang": "en" } } ``` Default response: Binary image data with Content-Type header (image/png, image/jpeg, or image/webp). --- ## GET /v1/screenshot Same parameters as POST but passed via query string. The url parameter is required. Booleans are "true"/"false" strings. Array params can be repeated (e.g. hideSelectors=.ad&hideSelectors=.banner). Ideal for embedding in tags or opening directly in a browser. --- ## POST /v1/style Apply styling to an existing screenshot image. Does NOT count toward monthly quota. **Parameters:** | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | image | string | Yes | Base64-encoded image (PNG/JPEG/WebP, max 10MB) | | format | string | No | Output format: png, jpeg, webp. Default: png | | style | object | Yes | Style config — use theme or individual properties | | style.theme | string | No | Preset: notion, paper, vercel, glass, ocean, sunset, linear, arc, glassDark, neonBlue, neonPurple, neonGreen, spotlight, lavender, ember, dots, grid | | style.frame | string | No | macos, windows, minimal, none | | style.background | string | No | ocean, sunset, forest, midnight, aurora, lavender, peach, arctic, ember, slate, neon, glass, solid, spotlight, dots, grid, noise, none | | style.shadow | string | No | none, xs, sm, md, lg, xl, 2xl | | style.padding | integer | No | 0–120 pixels. Default: 40 | | style.borderRadius | integer | No | 0–40 pixels. Default: 12 | | style.bgColor | string | No | Hex color for solid background | | response_type | string | No | "json" for base64 JSON. Default: binary image | --- ## POST /v1/pdf Generate a PDF from a URL or HTML content. Returns PDF as binary data. Costs 1 API request. ### Parameters | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | url | string | — | URL to render (required if no html) | | html | string | — | Raw HTML to render (required if no url) | | format | string | A4 | Paper format: A4, Letter, Legal, Tabloid | | landscape | boolean | false | Landscape orientation | | printBackground | boolean | true | Include CSS backgrounds | | margin | string | — | CSS margin for all sides (e.g. "1cm") | | margins | object | — | {top, right, bottom, left} in CSS units | | displayHeaderFooter | boolean | false | Show header and footer | | headerTemplate | string | — | HTML template for header | | footerTemplate | string | — | HTML template for footer | | scale | number | 1 | Rendering scale (0.1–2) | | pageRanges | string | — | e.g. "1-5, 8" | | width | integer | — | Viewport width for rendering | | delay | integer | 0 | Wait ms before rendering (max 10000) | | response_type | string | binary | Set to "json" for base64 response | --- ## POST /v1/og-image Generate dynamic Open Graph / social card images. Use built-in templates or custom HTML. Costs 1 API request. ### Parameters | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | template | string | default | default, minimal, or gradient | | html | string | — | Custom HTML template (overrides template) | | title | string | — | Main title text | | subtitle | string | — | Subtitle text | | logo | string | — | Logo image URL | | bgColor | string | #0f172a | Background color (hex) | | textColor | string | #f8fafc | Text color (hex) | | accentColor | string | #6366f1 | Accent color (hex) | | bgImage | string | — | Background image URL | | width | integer | 1200 | Image width (max 2400) | | height | integer | 630 | Image height (max 1260) | | format | string | png | png, jpeg, or webp | | response_type | string | binary | Set to "json" for base64 response | --- ## POST /v1/sequence Execute a multi-step browser automation sequence. Navigate pages, interact with elements, and capture multiple screenshots and PDFs in a single browser session. Each output (screenshot/pdf) costs 1 API request. ### Top-Level Parameters | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | steps | array | — | Required. Array of step objects (max 20) | | viewport | object | — | {width, height} — default 1280×720 | | darkMode | boolean | false | Emulate dark color scheme | | blockBanners | boolean | false | Auto-hide cookie consent banners | | deviceScaleFactor | number | 1 | Pixel ratio (max 3, use 2 for retina) | ### Available Actions | Action | Required Fields | Description | |--------|----------------|-------------| | navigate | url | Go to a URL (http/https only) | | click | selector | Click an element by CSS selector | | fill | selector, value | Clear and type into an input field | | select | selector, value | Select a dropdown option by value | | hover | selector | Hover over an element (reveals tooltips, dropdowns) | | scroll | selector or x, y | Scroll to element or absolute position | | wait | ms | Wait fixed milliseconds (max 10000) | | wait_for | selector | Wait for element to appear and become visible (optional timeout, max 15s) | | evaluate | script | Run JavaScript in page context (max 5000 chars, max 2 per sequence) | | screenshot | name | Capture current state. Optional: format, fullPage, quality, selector, style (same style options as Screenshot API) | | pdf | name | Generate PDF. Optional: format (A4/Letter/Legal/Tabloid/A3/A5), landscape, margin, scale | ### Limits - Max 20 steps - Max 5 outputs (screenshot + pdf combined) - Max 2 evaluate steps - 60s total timeout - 15s per-step timeout ### Response ```json { "outputs": [ { "name": "login-page", "type": "screenshot", "format": "png", "content_type": "image/png", "data": "base64...", "size_bytes": 145832, "step_index": 1, "duration_ms": 342 } ], "step_results": [ {"step_index": 0, "action": "navigate", "status": "ok", "duration_ms": 2341} ], "steps_completed": 7, "total_steps": 7, "total_duration_ms": 5251, "usage": { "outputs_charged": 2, "remaining": 4998 } } ``` --- ## POST /v1/video Record a professional demo video of multi-step browser automation with cursor highlighting and click effects. Costs 3 API requests per video. ### Top-Level Parameters | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | steps | array | — | Required. Array of step objects (same as sequence, but NO screenshot/pdf steps) | | async | boolean | false | Return 202 + job_id immediately instead of blocking. Delivered as a hosted video URL; poll GET /api/v1/jobs/:id or register a webhook (POST /api/v1/webhooks) for job.completed / job.failed. Quota charged only on success; max 5 pending jobs/account. | | viewport | object | — | {width, height} — default 1280×720 | | format | string | mp4 | mp4, webm, or gif | | framerate | number | 30 | Frames per second: 24, 30, or 60 | | darkMode | boolean | false | Emulate dark color scheme | | blockBanners | boolean | true | Auto-hide cookie consent banners | | deviceScaleFactor | number | 1 | Pixel ratio 1–3 (use 2 for retina) | | pace | number or string | 1.0 | Video speed. Number 0.25–6.0 (higher = slower). Presets: "fast" (0.5×), "normal" (1×), "slow" (2×), "dramatic" (3×), "cinematic" (4.5×). Scales cursor movement, pauses, typing speed, and all cosmetic delays. | | response_type | string | binary | Set to "json" for base64-encoded response | | host | boolean or string | false | Host the video at a shareable pagebolt.dev/v/:id URL. true = private (owner-only); "public" = anyone with the link. Forces a JSON response containing url, embed_url, file_url, visibility, and expires_at. | | public | boolean | false | Shorthand for host:"public". | | title | string | — | Optional title shown on the hosted watch page and in link previews. | ### Hosted videos (pagebolt.dev/v/:id) Set `host: true` to store the rendered video and get back a shareable URL instead of a raw blob: ``` POST /v1/video { "host": "public", "title": "Checkout demo", "steps": [ ... ] } → { "id": "a1B2c3...", "url": "https://pagebolt.dev/v/a1B2c3...", // branded watch page "embed_url": "https://pagebolt.dev/embed/v/a1B2c3...", // iframe player "file_url": "https://pagebolt.dev/v/a1B2c3.../file", // raw MP4 (range-aware) "visibility": "public", "expires_at": "2026-07-07 12:00:00", "format": "mp4", "size_bytes": 1234567, "duration_ms": 18000 } ``` Visibility defaults to **private** (only the owner, via dashboard session, can view). Use `host:"public"` for a link anyone can open or embed. Hosted videos are auto-deleted after a retention window that depends on your plan: Free 7 days, Hobby 30 days, Starter/Growth/Scale 90 days. ### Cursor Options | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | cursor.visible | boolean | true | Show animated cursor | | cursor.style | string | highlight | highlight, circle, spotlight, or dot | | cursor.color | string | #3B82F6 | Cursor color (hex) | | cursor.size | number | 20 | Cursor size in pixels (8–60) | | cursor.smoothing | boolean | true | Smooth cursor movement | ### Click Effect Options | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | clickEffect.enabled | boolean | true | Show visual feedback on clicks | | clickEffect.style | string | ripple | ripple, pulse, or ring | | clickEffect.color | string | cursor color | Click effect color (hex) | ### Zoom Options | Parameter | Type | Default | Description | |-----------|------|---------|-------------| Per-step zoom: add `zoom: { enabled: true, level: 1.5 }` to individual click/dblclick steps to zoom into that specific action. | zoom.easing | string | ease-in-out | ease-in-out, linear, or ease | | zoom.trigger | string | click | Zoom on clicks only | ### Frame Options | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | frame.enabled | boolean | false | Add browser window frame chrome overlay | | frame.style | string | macos | macos, windows, or minimal | | frame.theme | string | auto | light, dark, or auto (matches darkMode) | | frame.showUrl | boolean | true | Show URL in the frame's address bar | ### Background Options | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | background.enabled | boolean | false | Add decorative background behind viewport | | background.type | string | gradient | gradient or solid | | background.gradient | string | ocean | Preset: ocean, sunset, forest, midnight, aurora, or custom | | background.color | string | #1e3a5f | Background color for solid type (hex) | | background.colors | array | — | Array of 2 hex colors for custom gradient | | background.padding | number | 40 | Padding around viewport (0–120 px) | | background.borderRadius | number | 12 | Border radius of viewport (0–40 px) | ### Audio Guide Options Optional voice narration for each step. Paid plans only (Starter+). GIF format not supported. | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | audioGuide.enabled | boolean | false | Enable Audio Guide narration | | audioGuide.provider | string | azure | TTS provider: azure or openai | | audioGuide.voice | string | — | Voice preset. Azure: ava, andrew, emma, brian, aria, guy, jenny, davis, christopher, michelle. OpenAI: alloy, echo, fable, nova, onyx, shimmer | | audioGuide.speed | number | 1.0 | Speech rate 0.5–2.0 | | audioGuide.pitch | string | — | Pitch (Azure only) | | audioGuide.volume | string | — | Volume (Azure only) | | audioGuide.style | string | — | Speaking style (Azure only) | | audioGuide.styleDegree | number | — | Style intensity 0.01–2.0 (Azure only) | | audioGuide.model | string | tts-1 | OpenAI model: tts-1 or tts-1-hd | ### Available Actions | Action | Required Fields | Description | |--------|----------------|-------------| | navigate | url | Go to a URL | | click | selector | Click an element | | fill | selector, value | Clear and type into an input | | select | selector, value | Select dropdown option | | hover | selector | Hover over an element | | scroll | selector or x, y | Scroll to element or position | | wait | ms | Wait fixed ms (max 10000) | | wait_for | selector | Wait for element to be visible (max 15s) | | evaluate | script | Run JS (max 5000 chars, max 2 per video) | Note: screenshot and pdf actions are NOT allowed in video steps. The entire recording IS the output. ### Step Notes (Guided Tour Annotations) Add a `note` string (max 500 chars) to any step to display a text overlay in the video before the action executes. Great for guided product tours. Available on: navigate, click, dblclick, fill, hover, scroll. Example: `{ "action": "click", "selector": "#signup", "note": "Click here to create your account" }` ### Per-Step Narration (Audio Guide) When `audioGuide.enabled` is true, add a `narration` string to any step to speak that text aloud during the video. Available on: navigate, click, dblclick, fill, hover, scroll. Use alongside or instead of `note`. Max 500 chars per step. Example: `{ "action": "click", "selector": "#signup", "narration": "Click here to create your account" }` Auto-scroll: If a click/fill/hover target is outside the viewport, the engine automatically scrolls it into view first — so notes, cursor, and click effects are always visible. ### Plan Limits Duration scales with steps: timeout = base + (steps × per-step budget × pace). | Plan | Base + Per-Step Budget | Max Steps | Formats | |------|----------------------|-----------|---------| | Free | 20s + 5s/step | 10 | mp4 | | Starter | 30s + 5s/step | 20 | mp4, webm | | Growth | 45s + 6s/step | 30 | mp4, webm, gif | | Scale | 60s + 6s/step | 50 | mp4, webm, gif | ### Response (when response_type=json) ```json { "data": "base64...", "format": "mp4", "content_type": "video/mp4", "size_bytes": 2457600, "duration_ms": 12400, "frames": 372, "steps_completed": 5, "total_steps": 5, "step_results": [...], "usage": { "video_cost": 3, "remaining": 4847 } } ``` Default response: Binary video data with Content-Type (video/mp4, video/webm, or image/gif). --- ## POST /v1/observe The agent perception endpoint. In a single page load, returns a compact, token-budgeted observation of any page for AI agents: id-indexed interactive elements (role, name, CSS selector, state), a heuristic pageType classification (login, signup, search, article, form, generic), and grouped suggested actions (login flow, search, primary buttons, navigation). Costs 1 API request. Available on all plans. Optional flags bundle more in the same request: `includeContent` (main readable content as Markdown), `includeAriaTree` (interesting-only ARIA tree), `includeScreenshot` (base64 screenshot, with `screenshotFormat` jpeg/png/webp), `includeConsole` (browser console output + uncaught page errors during load, returned under `console`). Accepts the same page-setup params as /inspect (url/html, viewport, cookies, headers, blocking, darkMode, etc.). `maxElements` (default 40, max 150) caps elements; `includeRects` adds bounding boxes. FlatDomTree interop (browser-use / page-agent): pass `format: "flatdomtree"` to get `dom_text` — the indexed plain-text DOM (`[1]`) used by browser-use and Alibaba's page-agent — plus a `selectors` map (`{"1": "#signin"}`) instead of the JSON `elements` array. Import an agent's action trace back with `POST /api/v1/sequences/import` (`{ trace, selectors, name, save }`) to get a saved, re-runnable sequence. The `pagebolt-page-agent` npm package records a client-side page-agent run and posts it there automatically. This is the headless, server-side perception layer for the agentic web. Unlike in-browser standards like WebMCP — which require a visible browser tab and only work for sites that instrument themselves — /observe turns any un-instrumented URL into agent-ready structure, far more token-efficient than a raw screenshot or full DOM dump (a simple login page is just a few hundred tokens). Feed the returned selectors straight into /v1/sequence to act. ``` POST https://pagebolt.dev/api/v1/observe Headers: x-api-key: YOUR_API_KEY, Content-Type: application/json Body: { "url": "https://example.com/login", "blockBanners": true } ``` Response (abridged): ``` { "url": "https://example.com/login", "title": "Sign in", "pageType": "login", "elements": [ { "id": "e1", "role": "textbox", "type": "email", "name": "Email", "selector": "#email", "state": ["required"] }, { "id": "e2", "role": "textbox", "type": "password", "name": "Password", "selector": "#pw", "state": ["required"] }, { "id": "e3", "role": "button", "type": "submit", "name": "Sign in", "selector": "button[type='submit']" } ], "forms": [ { "selector": "form", "action": "/login", "method": "POST", "fieldIds": ["e1","e2","e3"] } ], "actions": [ { "intent": "login", "elementIds": ["e1","e2","e3"] } ], "stats": { "elementCount": 3, "estimatedTokens": 281 }, "duration_ms": 1180 } ``` --- ## POST /v1/act The goal-driven automation endpoint. Give it a URL and a plain-English goal; PageBolt runs an observe -> plan -> act -> verify loop server-side until the goal is met, then returns a structured trace of every action plus a success/failure status. This is the "hands" on top of /v1/observe (the "eyes") — you don't author selectors or a step list yourself. Available on Starter and above. When to use which: use /v1/sequence when you already know the exact steps and selectors (deterministic, cheapest). Use /v1/act when you only know the outcome you want (e.g. "log in and go to billing"). Parameters: - `url` (string, required): the page to start on. - `goal` (string, required, min 3 chars): plain-English outcome you want. - `maxSteps` (integer, default 8): cap on planning iterations; clamped to your plan ceiling (Starter 10, Growth 15, Scale 20). - `allowedDomains` (array, default = start host only): hosts the agent may navigate to. Navigation elsewhere is rejected. - `credentials` (object): `{ username, password }`. Referenced as {{username}}/{{password}} and substituted only at execution time. Never logged, never sent to the planner LLM; appears in the trace as . - `session_id` (string): run inside an existing session (reuses cookies/login). Otherwise an ephemeral browser is used and discarded. Cost is metered: 2 requests base + 1 request per step taken (a 4-step run costs 6 requests). The agent stops at maxSteps, a 90s wall-clock limit, or when it repeats an action without progress. Safety: navigation is locked to allowedDomains and internal/private URLs are blocked (SSRF-safe). Page text is treated as untrusted data — the planner pursues only your goal and never follows instructions embedded in page content. ``` POST https://pagebolt.dev/api/v1/act Headers: x-api-key: YOUR_API_KEY, Content-Type: application/json Body: { "url": "https://app.example.com/login", "goal": "Log in and open the billing page", "credentials": { "username": "me@example.com", "password": "..." }, "allowedDomains": ["app.example.com"], "maxSteps": 10 } ``` Response (abridged): ``` { "status": "succeeded", "goal": "Log in and open the billing page", "steps_taken": 4, "final_url": "https://app.example.com/billing", "summary": "Logged in and navigated to billing.", "trace": [ { "step": 1, "action": "fill", "target": "#email", "value": "", "result": "ok" }, { "step": 2, "action": "fill", "target": "#pw", "value": "", "result": "ok" }, { "step": 3, "action": "click", "target": "button[type='submit']", "result": "ok" }, { "step": 4, "action": "click", "target": "a[href='/billing']", "result": "ok" } ], "usage": { "inputTokens": 5100, "outputTokens": 720, "plannerCalls": 5, "act_cost": 6, "remaining": 4994 } } ``` `status` is one of: succeeded, failed, max_steps, timeout. --- ## POST /v1/inspect Inspect a web page and get a structured map of all interactive elements, headings, forms, links, and images — each with a unique CSS selector. Returns JSON optimized for AI agents. Costs 1 API request. **Best practice:** Call inspect BEFORE sequence or video to get reliable CSS selectors. For agent workflows, prefer /v1/observe — it returns a more compact, action-oriented observation in one call. ### Parameters | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | url | string | — | Required (if no html). URL to inspect. | | html | string | — | Raw HTML to inspect (alternative to url). | | width | integer | 1280 | Viewport width (1–3840) | | height | integer | 720 | Viewport height (1–2160) | | viewportDevice | string | — | Device preset, e.g. "iphone_14_pro" | | darkMode | boolean | false | Emulate dark color scheme | | waitUntil | string | networkidle2 | load, domcontentloaded, networkidle0, networkidle2 | | waitForSelector | string | — | Wait for CSS selector before inspecting | | cookies | array | — | Array of "name=value" or {name, value, domain?} | | headers | object | — | Extra HTTP headers | | authorization | string | — | Authorization header value | | userAgent | string | — | Override User-Agent | | blockBanners | boolean | false | Hide cookie consent banners | | blockAds | boolean | false | Block advertisements | | blockChats | boolean | false | Block live chat widgets | | blockTrackers | boolean | false | Block tracking scripts | | bypassCSP | boolean | false | Bypass Content-Security-Policy | | hideSelectors | array | — | CSS selectors to hide | | injectCss | string | — | Custom CSS | | injectJs | string | — | Custom JavaScript | | includeConsole | boolean | false | Also capture browser console output (log/info/warn/error) + uncaught page errors during load, returned under `console`. Useful for debugging a page's runtime, not just its DOM. | ### Response ```json { "url": "https://example.com", "title": "Example Page", "metadata": { "description": "Page description", "ogTitle": "OG Title", "lang": "en", "httpStatusCode": 200 }, "elements": [ { "tag": "button", "role": "button", "text": "Sign Up", "selector": "#signup-btn", "attributes": { "id": "signup-btn", "type": "submit" }, "rect": { "x": 120, "y": 340, "width": 160, "height": 40 } } ], "headings": [ { "level": 1, "text": "Welcome", "selector": "h1" } ], "forms": [ { "selector": "form#signup", "action": "/signup", "method": "POST", "fields": ["input[name='email']", "input[name='password']"] } ], "links": [ { "text": "About", "href": "/about", "selector": "nav a[href='/about']" } ], "images": [ { "alt": "Logo", "src": "/logo.png", "selector": "img[alt='Logo']", "rect": { "x": 10, "y": 10, "width": 120, "height": 40 } } ], "duration_ms": 1234 } ``` --- ## POST /v1/extract Load a URL in a real browser, strip navigation/ads/boilerplate using Mozilla Readability, and return the main article content as clean Markdown — with title, word count, byline, and excerpt. Renders JavaScript first, so it works on SPAs. Costs 1 API request. Available on all plans. Feed the Markdown straight into LLM context — far cheaper than raw HTML. ### Parameters | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | url | string | — | Required. URL to load and extract content from. | | width | integer | 1280 | Viewport width in pixels | | waitUntil | string | networkidle2 | load, domcontentloaded, networkidle0, networkidle2 | | waitForSelector | string | — | Wait for a CSS selector before extracting | | cookies | array | — | Array of "name=value" strings (for authenticated pages) | | headers | object | — | Extra HTTP headers | | authorization | string | — | Authorization header value | | userAgent | string | — | Override browser User-Agent | | blockBanners | boolean | false | Hide cookie consent banners before extracting | | blockAds | boolean | false | Block advertisements | | blockTrackers | boolean | false | Block tracking scripts | ### Response ```json { "url": "https://example.com/article", "title": "Example Article Title", "markdown": "# Example Article Title\n\nThe main article content...", "wordCount": 842, "excerpt": "A short summary of the article content.", "byline": "Jane Smith", "siteName": "Example Blog", "lang": "en", "duration_ms": 1840 } ``` A 422 is returned when no readable main-content area can be extracted (e.g. an app shell with no article). --- ## POST /v1/audit Load a URL in a real browser and run a full WCAG 2.1 A/AA accessibility audit using axe-core (Deque). Returns violations with impact level, affected nodes, and fix guidance, plus passes and incomplete items. Costs 1 API request. Available on all plans. Wire into CI to catch WCAG regressions before deploy. ### Parameters | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | url | string | — | Required. URL to audit. | | width | integer | 1280 | Viewport width (affects responsive layout) | | viewportDevice | string | — | Device preset for mobile auditing, e.g. "iphone_14_pro" | | waitUntil | string | networkidle2 | load, domcontentloaded, networkidle0, networkidle2 | | waitForSelector | string | — | Wait for a CSS selector before auditing (SPAs) | | cookies | array | — | Authenticate before auditing (audit logged-in views) | | headers | object | — | Extra HTTP headers | | userAgent | string | — | Override browser User-Agent | | blockBanners | boolean | false | Hide cookie banners before auditing | ### Response ```json { "url": "https://example.com", "summary": { "violations": 4, "passes": 38, "incomplete": 2, "critical": 1, "serious": 2, "moderate": 1, "minor": 0 }, "violations": [ { "id": "color-contrast", "impact": "serious", "description": "Elements must have sufficient color contrast", "helpUrl": "https://dequeuniversity.com/rules/axe/4.10/color-contrast", "nodes": [ { "html": "About", "target": [".nav-link"], "failureSummary": "Fix any of: Element has insufficient color contrast of 2.5:1 (required: 4.5:1)" } ] } ], "passes": [ { "id": "document-title", "description": "Documents must have element" } ], "incomplete": [], "duration_ms": 2310 } ``` --- ## POST /v1/aria Capture the ARIA accessibility tree of a page — the semantic structure (roles, names, nesting) that screen readers and AI agents perceive. Accepts a url or raw html. Costs 1 API request. Available on all plans. A compact, semantic view that is far cheaper than raw HTML for LLM reasoning. ### Parameters | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | url | string | — | Required unless html is provided. URL to capture. | | html | string | — | Raw HTML to render instead of a URL | | width | integer | 1280 | Viewport width in pixels | | viewportDevice | string | — | Device preset, e.g. "iphone_14_pro" | | waitUntil | string | networkidle2 | load, domcontentloaded, networkidle0, networkidle2 | | waitForSelector | string | — | Wait for a CSS selector before capturing (SPAs) | | darkMode | boolean | false | Emulate dark color scheme | | blockBanners | boolean | false | Hide cookie consent banners before capturing | ### Response ```json { "url": "https://example.com", "title": "Example Domain", "tree": { "role": "RootWebArea", "name": "Example Domain", "children": [ { "role": "heading", "name": "Example Domain", "level": 1 }, { "role": "link", "name": "More information..." } ] }, "duration_ms": 1320 } ``` For an agent-optimized, action-oriented observation, prefer /v1/observe — it bundles a compact element map, page-type classification, and suggested actions in one call. --- ## POST /v1/diff Render two pages and pixel-compare them. Returns the percentage of pixels changed, the changed-pixel count, and a base64 diff image highlighting exactly what moved. Compare two URLs (e.g. production vs staging) or two HTML snapshots. Costs 1 API request. Available on all plans. Built for visual regression testing in CI. ### Parameters | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | url_a | string | — | Required unless html_a is provided. First page to compare. | | url_b | string | — | Required unless html_b is provided. Second page to compare. | | html_a / html_b | string | — | Raw HTML alternatives to url_a / url_b | | threshold | number | 0.1 | Per-pixel matching sensitivity, 0–1. Lower = stricter. | | width | integer | 1280 | Viewport width in pixels | | height | integer | — | Viewport height in pixels | | viewportDevice | string | — | Device preset, e.g. "iphone_14_pro" | | fullPage | boolean | false | Compare the full scrollable page for both sides | | blockBanners | boolean | false | Hide cookie consent banners on both pages | ### Response ```json { "url_a": "https://example.com", "url_b": "https://staging.example.com", "changed_pct": 2.43, "changed_pixels": 19847, "total_pixels": 816000, "diff_image": "data:image/png;base64,iVBORw0KGgo...", "duration_ms": 3210 } ``` --- ## GET /v1/usage Check your current usage and plan limits. No parameters needed. Free (no API request cost). ### Response ```json { "plan": "starter", "usage": { "current": 1247, "limit": 5000, "remaining": 3753 } } ``` --- ## GET /v1/devices Returns available device presets for the viewportDevice parameter. No parameters needed. Free (no API request cost). ### Response (excerpt) ```json { "devices": [ {"id": "iphone_se", "name": "iPhone SE", "width": 375, "height": 667, "deviceScaleFactor": 2, "mobile": true}, {"id": "iphone_14_pro", "name": "iPhone 14 Pro", "width": 393, "height": 852, "deviceScaleFactor": 3, "mobile": true}, {"id": "iphone_15_pro_max", "name": "iPhone 15 Pro Max", "width": 430, "height": 932, "deviceScaleFactor": 3, "mobile": true}, {"id": "ipad_pro_12", "name": "iPad Pro 12.9\"", "width": 1024, "height": 1366, "deviceScaleFactor": 2, "mobile": true}, {"id": "pixel_8_pro", "name": "Google Pixel 8 Pro", "width": 412, "height": 915, "deviceScaleFactor": 3.5, "mobile": true}, {"id": "galaxy_s24_ultra", "name": "Galaxy S24 Ultra", "width": 412, "height": 915, "deviceScaleFactor": 3.5, "mobile": true}, {"id": "macbook_pro_14", "name": "MacBook Pro 14\"", "width": 1512, "height": 982, "deviceScaleFactor": 2, "mobile": false}, {"id": "desktop_4k", "name": "Desktop 4K", "width": 3840, "height": 2160, "deviceScaleFactor": 1, "mobile": false} ] } ``` 25+ presets available including iPhones (SE through 15 Pro Max), iPads, Pixel, Galaxy, MacBooks, and desktop resolutions. --- ## Common Patterns & Tips ### Clean captures (block everything distracting) ```json { "url": "https://example.com", "blockBanners": true, "blockAds": true, "blockChats": true, "blockTrackers": true } ``` ### Authenticated page screenshots Use cookies, headers, or authorization to access pages behind login: ```json { "url": "https://myapp.com/dashboard", "cookies": [{"name": "session", "value": "abc123", "domain": "myapp.com"}], "authorization": "Bearer eyJhbG...", "waitForSelector": ".dashboard-loaded" } ``` ### Inspect → Sequence workflow 1. POST /v1/inspect with url + blockBanners to get reliable CSS selectors 2. Use those selectors in your /v1/sequence or /v1/video steps 3. Never guess selectors — always inspect first ### Video recording tips - Use blockBanners: true (default for video) - Use pace: "normal" or "slow" for demo videos - cursor.style: "spotlight" looks best for product demos - clickEffect.style: "ripple" gives satisfying click feedback - Keep to 15 steps or fewer for reliability - Each video costs 3 API requests ### Cost summary | Action | Cost | |--------|------| | Screenshot (POST or GET) | 1 request | | PDF generation | 1 request | | OG image | 1 request | | Page inspection | 1 request | | Sequence | 1 request per output (screenshot/pdf) | | Video recording | 3 requests flat | | List devices | Free | | Check usage | Free | --- ## MCP Server (AI Agent Integration) PageBolt includes a Model Context Protocol server for AI coding assistants. Install: `npx pagebolt-mcp` ### Configuration ```json { "mcpServers": { "pagebolt": { "command": "npx", "args": ["-y", "pagebolt-mcp"], "env": { "PAGEBOLT_API_KEY": "pf_live_your_key_here" } } } } ``` ### MCP Tools | Tool | Description | Cost | |------|-------------|------| | take_screenshot | Capture URL/HTML/Markdown as PNG/JPEG/WebP | 1 req | | generate_pdf | Convert URL/HTML to PDF, saves to disk | 1 req | | create_og_image | Generate social card images | 1 req | | run_sequence | Multi-step automation with multiple outputs | 1 req/output | | record_video | Record browser automation as MP4/WebM/GIF | 3 req | | observe_page | Agent-optimized observation: id-indexed elements, page-type, suggested actions (+ optional content/ARIA/screenshot) | 1 req | | visual_diff | Pixel-level visual comparison of two pages | 1 req | | inspect_page | Structured map of page elements with selectors | 1 req | | list_devices | List 25+ device presets | Free | | check_usage | Check API usage and limits | Free | ### MCP Prompts | Prompt | Description | |--------|-------------| | capture-page | Capture a clean screenshot with sensible defaults | | record-demo | Record a professional demo video from a URL + description | | audit-page | Inspect and analyze a page's structure and elements | ### Environment Variables | Variable | Required | Default | Description | |----------|----------|---------|-------------| | PAGEBOLT_API_KEY | Yes | — | Your API key | | PAGEBOLT_BASE_URL | No | https://pagebolt.dev | API base URL | --- ## Links - Homepage: https://pagebolt.dev - API Playground: https://pagebolt.dev/dashboard (test all APIs interactively, no code required) - API Documentation: https://pagebolt.dev/docs - Changelog: https://pagebolt.dev/changelog - Sign Up: https://pagebolt.dev/signup - Dashboard: https://pagebolt.dev/dashboard - Terms: https://pagebolt.dev/terms - Privacy: https://pagebolt.dev/privacy - Support: support@pagebolt.dev - MCP Server: https://www.npmjs.com/package/pagebolt-mcp - Summary (llms.txt): https://pagebolt.dev/llms.txt - Full Reference (this file): https://pagebolt.dev/llms-full.txt --- Generated from https://pagebolt.dev/docs