# CurlShot for AI agents

> Paste a website address and get a screenshot of the whole page as an image or PDF. Free to try, nothing to install. For developers, one simple screenshot API.

This page tells an AI agent how to use CurlShot. It is the markdown version of https://curlshot.com/.

## The one request you need

```bash
curl "https://curlshot.com/api/v1/screenshot?access_key=YOUR_ACCESS_KEY&url=https://example.com&format=jpeg" --output page.jpg
```

- Method: `GET` with query parameters, or `POST` with a JSON body (use POST for `html`, `markdown`, `styles`, `scripts`).
- Exactly one source is required: `url`, `html` or `markdown`.
- The answer is the file itself (png, jpeg, webp, pdf, mp4, webm, gif). Add `response_type=json` to get JSON with a link to the stored file instead.
- Percent-encode the `url` value when it is part of a query string.

## Authentication

The user must give you their access key. They get one, free, at https://curlshot.com/register. Send it in one of three ways:

- query parameter `access_key=YOUR_ACCESS_KEY`
- header `X-Access-Key: YOUR_ACCESS_KEY`
- header `Authorization: Bearer YOUR_ACCESS_KEY`

Never invent a key and never print the key back in your answer.

## MCP server

Endpoint: `https://curlshot.com/api/mcp` (streamable HTTP, JSON-RPC 2.0 over POST). Send the access key as `Authorization: Bearer YOUR_ACCESS_KEY`.

- `take_screenshot`: renders a page and returns the image. Uses one screenshot of the quota.
- `list_devices`: lists the values accepted by `viewport_device`. Needs no key.

## Options

- Source: `url`, `html`, `markdown`
- Output: `format`, `image_quality`, `image_width`, `image_height`, `omit_background`, `response_type`
- Viewport: `viewport_width`, `viewport_height`, `device_scale_factor`, `viewport_device`, `viewport_mobile`, `viewport_landscape`
- Capture: `full_page`, `full_page_scroll`, `full_page_max_height`, `selector`, `clip_x`, `clip_y`, `clip_width`, `clip_height`
- Waiting: `wait_until`, `delay`, `timeout`, `wait_for_selector`
- Customize: `dark_mode`, `reduced_motion`, `media_type`, `hide_selectors`, `styles`, `scripts`, `click`
- Request: `user_agent`, `headers`, `cookies`, `authorization`, `time_zone`
- Blocking: `block_ads`, `block_trackers`, `block_cookie_banners`, `block_chats`, `block_resources`, `block_requests`
- PDF: `pdf_paper_format`, `pdf_landscape`, `pdf_print_background`, `pdf_margin`, `pdf_margin_top`, `pdf_margin_right`, `pdf_margin_bottom`, `pdf_margin_left`, `pdf_fit_one_page`
- Video: `video_duration`, `video_max_duration`, `video_fps`, `video_scroll`, `video_scroll_back`, `video_scroll_easing`
- Cache: `cache`, `cache_ttl`, `cache_key`
- Async and webhooks: `async`, `webhook_url`, `webhook_sign`
- Authentication: `access_key`, `signature`, `expires`

Common choices: `full_page=true` for the whole page, `viewport_device` for a device (for example `iphone_15_pro`, `pixel_9`, `ipad`, `macbook_air_13`, `desktop_full_hd`), `block_cookie_banners=true` and `block_ads=true` for a clean capture, `format=pdf` for a document, `cache=true` when you may ask for the same page again.

Full reference: https://curlshot.com/docs/options.md

## Advice for agents

- Prefer `format=jpeg` or `format=webp` and a modest viewport. Small images cost fewer tokens to look at.
- Use `cache=true` when you look at the same page more than once. Cache hits are free.
- A misspelled option returns `invalid_options` with a hint naming the right one. Read `error_message` and fix the request.
- Private and local addresses (`localhost`, `10.x`, `192.168.x`) are refused with `host_not_allowed`.

## Errors

Errors are JSON: `{ "error_code": "...", "error_message": "...", "documentation_url": "..." }`.

- Retry after a short pause: `navigation_failed`, `timeout`, `internal_error`, `renderer_busy`, `renderer_unavailable`, `service_unavailable`.
- `rate_limited` (429): wait the number of seconds in the `Retry-After` header.
- `quota_exceeded` (402): the monthly allowance is used up. Tell the user; do not retry.
- Anything else: fix the request first. Retrying the same request will fail again.

Every code with its cause and fix: https://curlshot.com/docs/errors.md

## Limits and prices

One successful render uses one screenshot. Cache hits and failed renders are free. Each plan also limits requests per minute and how many renders run at the same time. Response headers `X-Quota-Remaining` and `X-RateLimit-Remaining` tell you what is left.

| Plan | Price per month | Screenshots per month | Requests per minute | Renders at once |
| --- | --- | --- | --- | --- |
| Free | Free | 100 | 10 | 1 |
| Starter | $19 | 3,000 | 60 | 5 |
| Growth | $79 | 15,000 | 150 | 15 |
| Scale | $249 | 60,000 | 400 | 40 |

Check usage without spending a screenshot: `GET https://curlshot.com/api/v1/usage`.

## Other endpoints

- `POST https://curlshot.com/api/v1/bulk`: queue up to 100 renders in one call.
- `GET https://curlshot.com/api/v1/jobs/{id}`: state of a background job started with `async=true` or bulk.
- `GET https://curlshot.com/api/v1/usage`: quota and limits for the current period.

## Read more

- Map of the docs: https://curlshot.com/llms.txt
- All docs in one file: https://curlshot.com/llms-full.txt
- OpenAPI 3.1: https://curlshot.com/openapi.json
- Guide for agents: https://curlshot.com/docs/guides/ai-agents.md
