API Reference
The Screenmint base URL is https://api.screenmint.dev. Every endpoint accepts and returns JSON. Render a page in one call: you get back a hosted image URL, ready to drop into an <img> tag or a meta tag.
curl -X POST https://api.screenmint.dev/v1/screenshot \
-H "X-API-Key: sk_live_..." \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com"}'{
"url": "https://cdn.example/screenshots/9f2c….jpeg",
"width": 1280,
"height": 720,
"cached": false,
"render_ms": 1240
}Authentication
Authenticate every request with an X-API-Key header. Keys are created and revoked in the dashboard; the plaintext key is shown exactly once at creation, so store it somewhere safe.
X-API-Key: sk_live_...
Rate limits & caching
Two limits apply: a per-minute request rate (per API key, fixed one-minute windows) and a monthly render quota (per account, resets on the 1st, UTC).
| Plan | Requests / min | Renders / month |
|---|---|---|
| Free | 10 | 100 |
| Starter | 60 | 2,000 |
| Pro | 300 | 20,000 |
Identical requests are cached — screenshots for 1 hour, OG cards for 24 hours. Cache hits return in milliseconds with "cached": true and do not consume monthly renders (they still count toward the per-minute rate).
Errors
Errors return a JSON envelope with a stable error code, an optional human-readable message, and reset_at on 429s.
{
"error": "rate_limit_exceeded",
"reset_at": "2026-07-22T18:04:00.000Z"
}| Status | Code | When |
|---|---|---|
| 400 | invalid_params | A body field failed validation — the message field says which one and why. |
| 400 | invalid_url | The URL is not valid http(s), or it resolves to a private / internal address. |
| 401 | invalid_api_key | The X-API-Key header is missing or not recognized. |
| 422 | unrenderable_url | The host does not resolve, or the page failed to load within 15 seconds. |
| 429 | rate_limit_exceeded | Per-minute request limit reached. reset_at is when the window resets. |
| 429 | monthly_quota_exceeded | Monthly render quota used up. reset_at is the 1st of next month (UTC). |
| 503 | service_unavailable | All renderers are busy. Retry with exponential backoff. |
POST/v1/screenshot
Capture a screenshot of any public URL. The page gets a fresh, isolated browser context, waits for the load event (up to 15 seconds), then captures, optimizes, and hosts the image for you.
| Parameter | Type | Default | Description |
|---|---|---|---|
| url required | string | — | Page to capture. http(s) only; private and internal hosts are rejected. |
| width | integer | 1280 | Viewport width in pixels, 1–2560. |
| height | integer | 720 | Viewport height in pixels, 1–1440. |
| full_page | boolean | false | Capture the full scroll height instead of just the viewport. |
| format | string | "jpeg" | Output format: "jpeg" or "png". |
| quality | integer | 85 | JPEG quality, 1–100. Ignored for PNG. |
| delay | integer | 0 | Extra wait after page load, 0–3000 ms — useful for animations and late JS. |
| dark_mode | boolean | false | Emulate prefers-color-scheme: dark. |
curl -X POST https://api.screenmint.dev/v1/screenshot \
-H "X-API-Key: sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"width": 1280,
"height": 720,
"full_page": false,
"format": "jpeg",
"quality": 85,
"delay": 0,
"dark_mode": false
}'{
"url": "https://cdn.example/screenshots/9f2c….jpeg",
"width": 1280,
"height": 720,
"cached": false,
"render_ms": 1240
}POST/v1/og
Generate a branded 1200×630 Open Graph card from text and colors — no design tools, no templates to host. Output is an optimized JPEG, cached for 24 hours.
| Parameter | Type | Default | Description |
|---|---|---|---|
| title required | string | — | Card headline, up to 80 characters. Clamped to 2 lines. |
| description | string | — | Supporting text, up to 160 characters. Clamped to 2 lines. |
| site_name | string | — | Small accent-colored label under the text, up to 40 characters. |
| logo_url | string | — | Publicly reachable image shown above the title at 40 px tall. |
| bg_color | string | "#ffffff" | Background color, hex. |
| accent_color | string | "#000000" | Top bar and site_name color, hex. |
| text_color | string | "#000000" | Title and description color, hex. |
curl -X POST https://api.screenmint.dev/v1/og \
-H "X-API-Key: sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"title": "How we scaled to 1M renders",
"description": "Lessons from running headless Chromium in production.",
"site_name": "Engineering Blog",
"bg_color": "#0F0F11",
"accent_color": "#8B5CF6",
"text_color": "#ffffff"
}'{
"url": "https://cdn.example/og/def4….jpeg",
"cached": false,
"render_ms": 380
}GET/v1/usage
Check your current billing period programmatically — handy for alerting before you hit the quota.
curl https://api.screenmint.dev/v1/usage \
-H "X-API-Key: sk_live_..."{
"plan": "starter",
"renders_used": 487,
"renders_limit": 2000,
"period_start": "2026-07-01T00:00:00.000Z",
"period_end": "2026-08-01T00:00:00.000Z"
}