Activate
1. Account setup
Start with a free account to prove the crawler path before paying or changing production traffic. Free includes 500 fresh browser renders/month for one registered domain.
- Create account and verify your email.
- Open the dashboard after sign-in.
- Keep this page open while you add the domain and first key.
Activate
2. Add the domain you want crawlers to see
Register the production hostname of your SPA, for example app.example.com. Requests for unregistered hostnames are rejected before the browser starts.
- Open Dashboard - Domains.
- Enter the hostname without protocol or path.
- Save the returned domain ID if you plan to automate sitemap warming or push refresh.
example.com
www.example.com
docs.example.comActivate
3. Create a scoped API key
Create one key per integration. For production crawler middleware, use a domain-scoped key and store it only on the server.
- Open Dashboard - API keys.
- Name the key after the integration, such as
production middleware. - Select a domain scope, then copy the key once and store it as a server-side secret.
PAGEFLASH_KEY=pk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxActivate
4. Run the first render
Use the render endpoint to confirm the key, domain scope, and first fresh render all pass before adding middleware.
curl -H "Authorization: Bearer $PAGEFLASH_KEY" \
"https://pageflash.io/render?url=https://example.com/pricing"A successful response returns the rendered HTML crawlers will see. If monthly quota is exhausted on a cache miss, PageFlash returnsMONTHLY_QUOTA_EXCEEDED before the browser starts.
Integrate
5. Choose the integration path
Choose the path closest to your goal after the first render works. Most SPA visibility work uses crawler middleware; direct API calls are best for generated outputs and internal workflows.
Integrate
6. Route only crawler traffic through PageFlash
Keep normal users on your SPA. Send crawler user-agents to PageFlash so they receive complete cached HTML. Pick the layer closest to your traffic; Cloudflare Worker is usually the fastest low-risk path.
Edge / CDN - no app code change
Reverse proxy - drop into web server
Framework - add middleware in your app
// Bind PAGEFLASH_KEY as a Cloudflare secret, then deploy.
const BOT_REGEX = /(googlebot|google-inspectiontool|googleother|bingbot|bingpreview|slurp|yandex|baiduspider|sogou|applebot|duckduckbot|duckassistbot|twitterbot|facebookexternalhit|facebookbot|facebot|meta-externalagent|rogerbot|linkedinbot|embedly|quora|showyoubot|outbrain|pinterestbot|pinterest|slackbot|discordbot|vkShare|W3C_Validator|whatsapp|telegrambot|zalobot|zalo\/|zaloapp|zaloweb|linespider|Chrome-Lighthouse|gptbot|chatgpt-user|oai-searchbot|perplexitybot|perplexity-user|claudebot|claude-user|anthropic-ai|ccbot|bytespider|phindbot|redditbot|petalbot|semrushbot|ahrefsbot|mj12bot|dotbot)/i
export default {
async fetch(request, env) {
const ua = request.headers.get('user-agent') || ''
if (!BOT_REGEX.test(ua)) return fetch(request)
const renderUrl = 'https://pageflash.io/render?url=' + encodeURIComponent(request.url)
return fetch(renderUrl, {
headers: { Authorization: `Bearer ${env.PAGEFLASH_KEY}` },
})
},
}Integrate
7. Call the API directly for non-SEO outputs
Use the same endpoint for HTML, screenshots, PDF, and Markdown. Direct API calls should come from your backend, job queue, or internal tool.
# HTML for SEO bots
curl -H "Authorization: Bearer YOUR_KEY" \
"https://pageflash.io/render?url=https://your-app.com"
# Full-page PNG screenshot
curl -H "Authorization: Bearer YOUR_KEY" \
"https://pageflash.io/render?url=https://your-app.com&renderType=png&fullpage=true" \
--output snap.png
# PDF
curl -H "Authorization: Bearer YOUR_KEY" \
"https://pageflash.io/render?url=https://your-app.com&renderType=pdf" \
--output report.pdf
# Markdown for AI agents
curl -H "Authorization: Bearer YOUR_KEY" \
-H "Accept: text/markdown" \
"https://pageflash.io/render?url=https://your-app.com"renderType=jpeg, renderType=png, or renderType=pdf for binary outputs. Add Accept: text/markdown for AI-ready Markdown.Integrate
8. Verify as a crawler before launch
Test the exact request path your middleware will use. Confirm status, title, canonical, Open Graph tags, body content, and cache headers before production bot traffic moves.
curl -A "Googlebot/2.1 (+http://www.google.com/bot.html)" \
-H "Authorization: Bearer $PAGEFLASH_KEY" \
"https://pageflash.io/render?url=https://example.com/pricing" | head- Look for the rendered
<title>, one<h1>, canonical URL, and social meta tags. - Open the dashboard Activity view to confirm the request is attributed to the expected domain.
- Repeat with a social bot user-agent if link previews are important.
Operate
9. Add sitemap warming
Sitemap warming turns crawler rendering from reactive to proactive. PageFlash reads sitemap URLs, renders them ahead of time, and refreshes cache before bots arrive.
curl -X POST "https://pageflash.io/api/sitemaps" \
-H "Authorization: Bearer YOUR_DASHBOARD_JWT" \
-H "Content-Type: application/json" \
--data '{"domainId":"YOUR_DOMAIN_ID","url":"https://example.com/sitemap.xml"}'| Plan | Sitemap warming | Default freshness |
|---|---|---|
| Free | Not included | Manual renders only |
| Starter | 3 sitemaps/domain, 5,000 sitemap URLs | 1d default freshness |
| Growth | 10 sitemaps/domain, 50,000 sitemap URLs | 6h default freshness, custom TTL down to 1h |
| Pro | Unlimited sitemaps/domain, unlimited sitemap URLs | 1h default freshness, custom TTL down to 10m |
| Enterprise | Unlimited sitemaps/domain, unlimited sitemap URLs | 30m default freshness, custom TTL down to 5m |
Operate
10. Configure push refresh
Pro and Enterprise teams can tell PageFlash exactly which paths changed. PageFlash renders the fresh version in the background, then swaps cached HTML when it is ready.
curl -X POST "https://pageflash.io/api/domains/YOUR_DOMAIN_ID/invalidate" \
-H "Authorization: Bearer YOUR_PAGEFLASH_API_KEY" \
-H "Content-Type: application/json" \
--data '{"paths":["/blog/your-post","/pricing"]}'pathsmust start with/and must not include protocol or hostname.- Use a domain-scoped API key when the CMS only publishes one site.
- The endpoint accepts up to 100 paths per request and is limited to 100 requests per minute.
await fetch(
`https://pageflash.io/api/domains/${process.env.PAGEFLASH_DOMAIN_ID}/invalidate`,
{
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.PAGEFLASH_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ paths: ['/blog/your-post'] }),
},
)Need the domain ID? It is returned by GET /api/domains and when you add a domain from the dashboard.
Operate
11. Configure SEO audit, overrides, and AI output
Use SEO audit to see what crawlers receive after rendering. Pro and Enterprise unlock override workflows for titles, descriptions, Open Graph tags, canonical URLs, JSON-LD, AI copy, and llms.txt.
- Free, Starter, and Growth can inspect SEO audit signals.
- Pro adds overrides, AI copy generation, llms.txt, webhooks, and 30d activity history.
- Enterprise adds 200 AI generations/day, unlimited patterns, SLA, SSO, DPA, and private support.
Reference
Output types
HTML
Default renderType
curl -H "Authorization: Bearer $PAGEFLASH_KEY" \
"https://pageflash.io/render?url=https://example.com"Screenshot
PNG or JPEG
curl -H "Authorization: Bearer $PAGEFLASH_KEY" \
"https://pageflash.io/render?url=https://example.com&renderType=png&fullpage=true" \
--output page.pngPrint-ready export
curl -H "Authorization: Bearer $PAGEFLASH_KEY" \
"https://pageflash.io/render?url=https://example.com/report&renderType=pdf" \
--output report.pdfMarkdown
AI-ready text
curl -H "Authorization: Bearer $PAGEFLASH_KEY" \
-H "Accept: text/markdown" \
"https://pageflash.io/render?url=https://example.com/docs"Reference
Caching and freshness
HTML and Markdown renders use the cache when possible. A cache hit does not consume monthly render quota. Cold renders and forced refreshes count as fresh browser renders.
- Starter uses 1d default freshness.
- Growth uses 6h default freshness, custom TTL down to 1h.
- Pro uses 1h default freshness, custom TTL down to 10m.
- Enterprise uses 30m default freshness, custom TTL down to 5m.
Reference
Rate limits and monthly quota
PageFlash enforces the monthly render quota before a fresh browser render starts. Cache hits stay free. When a plan runs out on a cache miss, the response code is MONTHLY_QUOTA_EXCEEDED.
| Plan | Fresh renders/month | Requests/minute | Upgrade trigger |
|---|---|---|---|
| Free | 500 | 10 | One real production domain or sitemap warming |
| Starter | 15,000 | 60 | Multiple sites, more URLs, or sub-24h freshness |
| Growth | 150,000 | 200 | SEO overrides, push refresh, webhooks, or many domains |
| Pro | 600,000 | 500 | Dedicated capacity, compliance, SSO, or custom retention |
Reference
Render parameters
| Parameter | Default | Description |
|---|---|---|
| url | required | Absolute URL to render. Must match a registered domain. |
| renderType | html | html, png, jpeg, or pdf. Markdown uses Accept: text/markdown. |
| width | 1280 | Viewport width for screenshots and page layout. |
| height | 720 | Viewport height for screenshots and page layout. |
| fullpage | false | Capture the full document for PNG/JPEG screenshots. |
| waitForSelector | none | Wait until a CSS selector is visible before snapshot. |
| waitForFunction | none | Wait until a JS expression returns truthy. |
| waitForTimeout | 500 | Extra wait in milliseconds after readiness signals. |
| blockResources | true | Block heavy media for HTML renders. Disabled for screenshots. |
Stuck or have a question? Email [email protected].