API Reference

Base URL: https://api.renderapi.dev

Authentication

All API requests require an API key passed in the x-api-key header.

x-api-key: rapi_live_YOUR_KEY_HERE

Keys prefixed with rapi_test_ are for testing — renders won't count against your quota and won't be billed. Use rapi_live_ keys in production.

Manage your API keys in the Dashboard.

Quick Start

Take a screenshot of any URL in one request:

# Returns JSON with a URL to the rendered image
curl -X POST https://api.renderapi.dev/v1/screenshot \
  -H "Content-Type: application/json" \
  -H "x-api-key: rapi_live_YOUR_KEY" \
  -d '{"url": "https://example.com"}'

Response:

{
  "id": "render_a1b2c3d4e5f6",
  "status": "completed",
  "url": "https://cdn.renderapi.dev/renders/render_a1b2c3d4e5f6.png",
  "width": 1280,
  "height": 800,
  "file_size_bytes": 284592,
  "duration_ms": 743,
  "created_at": "2025-03-18T12:00:00.000Z",
  "expires_at": "2025-03-19T12:00:00.000Z"
}

Screenshots

POST /v1/screenshot
GET /v1/screenshot

Capture a screenshot from a URL or raw HTML. The GET endpoint accepts the same parameters as query strings for easy browser testing.

Parameters

ParameterTypeDescription
urlstringURL to capture. Required (unless html is provided)
htmlstringRaw HTML to render. Max 500KB. Required (unless url is provided)
formatstringpng | jpeg | webp. Default: png
widthintegerViewport width (100–3840). Default: 1280
heightintegerViewport height (100–2160). Default: 800
full_pagebooleanCapture the full scrollable page. Default: false
device_scale_factornumberDevice pixel ratio 1–3 (2 = retina). Default: 1
qualityintegerCompression quality 1–100 (JPEG/WebP only). Default: 80
wait_forstringload | domcontentloaded | networkidle. Default: networkidle
delay_msintegerWait N ms after page load (0–10000). Default: 0
selectorstringCSS selector — capture only this element.
dark_modebooleanEmulate prefers-color-scheme: dark. Default: false
block_adsbooleanBlock common ad/tracker domains. Default: true
inject_cssstringCustom CSS to inject after page loads. Max 50KB.
inject_jsstringCustom JavaScript to execute after page loads. Max 50KB.
cache_ttlintegerCache duration in seconds (0 = no caching, max 86400). Default: 0
webhook_urlstringURL to POST the result to when rendering completes.

GET Example

# Quick test in a browser or curl
curl "https://api.renderapi.dev/v1/screenshot?url=https://example.com&format=png" \
  -H "x-api-key: rapi_live_YOUR_KEY"

Binary Response

Add response_type=binary to the GET endpoint to receive the raw image bytes instead of JSON:

curl "https://api.renderapi.dev/v1/screenshot?url=https://example.com&response_type=binary" \
  -H "x-api-key: rapi_live_YOUR_KEY" \
  -o screenshot.png

PDFs

POST /v1/pdf

Generate a PDF from a URL or raw HTML.

Parameters

ParameterTypeDescription
urlstringURL to render. Required (unless html provided)
htmlstringRaw HTML to render. Max 500KB.
formatstringA4 | Letter | Legal | custom. Default: A4
widthstringCustom width (e.g. "210mm"). Only used when format is custom.
heightstringCustom height (e.g. "297mm").
landscapebooleanLandscape orientation. Default: false
marginobject{top, right, bottom, left} in CSS units. Default: 20mm/15mm
header_htmlstringHTML for page header. Max 10KB.
footer_htmlstringHTML for page footer. Max 10KB.
print_backgroundbooleanInclude background colors/images. Default: true
wait_forstringSame as screenshots. Default: networkidle
delay_msintegerWait N ms after load. Default: 0
webhook_urlstringURL to POST the result to when rendering completes.

Example: Invoice PDF

curl -X POST https://api.renderapi.dev/v1/pdf \
  -H "Content-Type: application/json" \
  -H "x-api-key: rapi_live_YOUR_KEY" \
  -d '{
    "html": "<h1>Invoice #1042</h1><table>...</table>",
    "format": "A4",
    "margin": {"top": "25mm", "bottom": "25mm", "left": "20mm", "right": "20mm"},
    "footer_html": "<div style=\"font-size:10px;text-align:center;width:100%\">Page <span class=\"pageNumber\"></span> of <span class=\"totalPages\"></span></div>"
  }'

Templates

GET /v1/templates
POST /v1/templates
POST /v1/template/:id/render

Create reusable HTML templates with Handlebars syntax. Pass dynamic data at render time.

Create a Template

curl -X POST https://api.renderapi.dev/v1/templates \
  -H "Content-Type: application/json" \
  -H "x-api-key: rapi_live_YOUR_KEY" \
  -d '{
    "name": "OG Image",
    "html": "<div style=\"width:1200px;height:630px;background:#1a1a2e;color:#fff;display:flex;align-items:center;justify-content:center;font-size:48px\">{{title}}</div>",
    "sample_data": {"title": "My Blog Post"},
    "default_output": "png"
  }'

Render with Data

curl -X POST https://api.renderapi.dev/v1/template/TEMPLATE_ID/render \
  -H "Content-Type: application/json" \
  -H "x-api-key: rapi_live_YOUR_KEY" \
  -d '{"data": {"title": "How to Build an API"}, "output": "png"}'

Usage

GET /v1/usage

Get your current billing period usage.

{
  "period_start": "2025-03-01T00:00:00.000Z",
  "period_end": "2025-03-31T23:59:59.999Z",
  "renders_used": 1847,
  "screenshots": 1502,
  "pdfs": 345,
  "renders_included": 5000,
  "overage_renders": 0,
  "plan": "starter"
}

Renders

GET /v1/renders/:renderId

Look up the status and details of a specific render by its ID.

Billing

POST /billing/checkout
POST /billing/portal

Use /billing/checkout with {"plan": "starter"} to get a Stripe Checkout URL. Use /billing/portal to open the Stripe Customer Portal for subscription management.

Errors

All errors return a JSON object with error and message fields.

StatusError CodeDescription
400invalid_requestMissing or invalid parameters.
401unauthorizedMissing or invalid API key.
402payment_requiredFree plan limit reached. Upgrade to continue.
404not_foundResource (render, template) not found.
408render_timeoutPage took too long to load (>30s default).
422render_failedPlaywright couldn't render the page. Check the URL or HTML.
429rate_limitedToo many requests. Slow down.
500internal_errorSomething went wrong on our end.

Rate Limits

Requests are rate-limited per API key. Current limits by plan:

PlanRequests/minConcurrent RendersMonthly Renders
Free201100
Starter6035,000
Pro120525,000
Business20010100,000

When rate limited, you'll receive a 429 response with a Retry-After header.

Webhooks

Add a webhook_url to any render request. When the render completes (or fails), we'll POST the result to your URL.

// Webhook payload
{
  "event": "render.completed",  // or "render.failed"
  "render_id": "render_a1b2c3d4e5f6",
  "data": {
    "id": "render_a1b2c3d4e5f6",
    "status": "completed",
    "url": "https://cdn.renderapi.dev/renders/render_a1b2c3d4e5f6.png",
    ...
  },
  "timestamp": "2025-03-18T12:00:00.000Z"
}
Webhooks include an X-RenderAPI-Signature header — an HMAC-SHA256 signature of the body. Verify this to ensure the payload is authentic. We retry up to 3 times with exponential backoff on failure.