curlshot
Skill0 starsChanged 30 days agoMITView on GitHub
Take screenshots of web pages with the CurlShot API. Use when the user wants a screenshot, full-page capture, mobile or tablet view, PDF, or scrolling video of a URL, or wants their own HTML or Markdown rendered to an image or PDF. Needs a CurlShot access key in the CURLSHOT_API_KEY environment variable.
- Reads credentials
- Sends data out
1 other project uses a version of this, 1 of them edited.
Adopted by
Most recently taken up by
- ishandutta2007/Awesome-Agent-Skillsedited, first seen Nov 8, 2026
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 1
- ishandutta2007/Awesome-Agent-Skills★ 2121% same
Wrote their own version · 0
None found.
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
The file
We split this skill into the rules it gives an agent
9 rules. About 0 are common, 5 are distinctive, and 4 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈5
Distinctive · estimate
This author's own choices. Worth a look.
4
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 28
Never print the key, paste it into a file in the repository, or put it in a link you show the user.
- Distinctive: line 29
Only public pages work out of the box.
- Very specific: line 33
Check that CURLSHOT_API_KEY is set (test -n "$CURLSHOT_API_KEY") without echoing its value.
- Very specific: line 46
Add options as one more -d name=value each (GET) or as fields in a POST JSON body:
- Very specific: line 72
Use "markdown": "..." instead of html to render Markdown as a styled page, and "format": "pdf" for a PDF.
- Distinctive: line 73
Check the result before you use it (see Output), then tell the user where the file is.
- Distinctive: line 106
Every code with its cause and fix: https://curlshot.com/docs/errors.md
- Distinctive: line 140
Check the status before trusting the file:
- Distinctive: line 154
All options: https://curlshot.com/docs/options.md
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
CurlShot screenshots
Overview
CurlShot renders a web page in a real browser and returns it as an image (PNG, JPEG, WebP), a PDF, or a video of the page scrolling (MP4, WebM, GIF). One HTTP request does it: GET https://curlshot.com/api/v1/screenshot?url=…, or a POST with a JSON body for your own HTML or Markdown.
Prerequisites
curlon the machine and network access tohttps://curlshot.com.- A CurlShot access key in
CURLSHOT_API_KEY. If it is not set, ask the user for it. A free key comes from https://curlshot.com/register: 100 screenshots a month, no card needed. Paid plans start at $19 a month (https://curlshot.com/pricing). - Never print the key, paste it into a file in the repository, or put it in a link you show the user. Send it in the
X-Access-Keyheader (anAuthorization: Bearer <key>header or anaccess_keyquery parameter also work). - Only public pages work out of the box. Local and private network addresses (localhost, 192.168.x.x, ...) are refused: for a local page, send its HTML instead (see step 4).
Instructions
- Check that
CURLSHOT_API_KEYis set (test -n "$CURLSHOT_API_KEY") without echoing its value. Take the screenshot with a GET request:
curl -sS -G "https://curlshot.com/api/v1/screenshot" \ -H "X-Access-Key: $CURLSHOT_API_KEY" \ --data-urlencode "url=https://example.com" \ -d format=png \ -D headers.txt \ --output screenshot.png-Gwith--data-urlencodekeeps the page address correctly encoded.Add options as one more
-d name=valueeach (GET) or as fields in a POST JSON body:Want Option Whole page, top to bottom full_page=truePhone or tablet view viewport_device=<preset>(list: https://curlshot.com/docs/devices.md)Window size viewport_width=1440,viewport_height=900Retina sharpness device_scale_factor=2Dark theme dark_mode=trueOne element only selector=<css selector>Output format format=png/jpeg/webp/pdf/mp4/webm/gifHide cookie banners and ads block_cookie_banners=true,block_ads=trueWait for content wait_until=networkidle,delay=2,wait_for_selector=<css selector>Reuse a stored copy for free cache=trueA misspelled option is rejected with
invalid_optionsand a hint, never ignored. Every option: https://curlshot.com/docs/options.mdTo render your own HTML or Markdown (or a local page), POST JSON:
curl -sS -X POST "https://curlshot.com/api/v1/screenshot" \ -H "X-Access-Key: $CURLSHOT_API_KEY" \ -H "Content-Type: application/json" \ -d '{"html": "<h1>Hello</h1>", "format": "png", "viewport_width": 1200, "viewport_height": 630}' \ --output card.pngUse
"markdown": "..."instead ofhtmlto render Markdown as a styled page, and"format": "pdf"for a PDF.- Check the result before you use it (see Output), then tell the user where the file is.
Output
- Success: HTTP
200with aContent-Typeofimage/*,video/*orapplication/pdf. The body is the file, saved by--output. - Failure: HTTP
400or higher withContent-Type: application/json. Do not keep that file as an image; read it as an error (see Error Handling). - Useful response headers:
X-Quota-RemainingandX-Quota-Reset(screenshots left this period),X-RateLimit-Remaining,X-Concurrency-Remaining,X-Cache(cache hit or miss), andX-Reference-Id(quote it when contacting support). - Billing: one successful render counts as one screenshot, whatever its size. Failed renders and cache hits are free.
Error Handling
An error body looks like this:
{
"error_code": "invalid_options",
"error_message": "fullpage: is not a known option; did you mean `full_page`?",
"documentation_url": "https://curlshot.com/docs/errors#invalid_options",
"errors": [{ "field": "fullpage", "message": "is not a known option; did you mean `full_page`?" }]
}Branch on error_code, never on error_message.
| Status | Codes | What to do |
400, 413, 422 | invalid_options, invalid_url, invalid_request, content_too_large, selector_not_found, page_blocked | Do not retry. Fix the request using errors and the hint. |
401 | access_key_required, access_key_invalid | Do not retry. Ask the user to check CURLSHOT_API_KEY. |
402 | quota_exceeded | Do not retry. Tell the user the quota is used up and show upgrade_url. |
403 | host_not_allowed, feature_not_available, email_not_verified | Do not retry. For a private or local address, send the HTML instead. For a plan feature, show upgrade_url. |
429 | rate_limited, concurrency_limit, queue_limit, failure_limit | Wait the seconds in Retry-After, then retry once. |
500, 502, 503, 504 | internal_error, navigation_failed, timeout, renderer_busy, renderer_unavailable, service_unavailable | Retry once after a short pause. For timeout, drop wait_until=networkidle (the default is load) or lower delay. |
Every code with its cause and fix: https://curlshot.com/docs/errors.md
Examples
Full-page screenshot of a site on an iPhone, cookie banners hidden:
curl -sS -G "https://curlshot.com/api/v1/screenshot" \
-H "X-Access-Key: $CURLSHOT_API_KEY" \
--data-urlencode "url=https://example.com" \
-d viewport_device=iphone_15_pro -d full_page=true -d block_cookie_banners=true \
--output mobile.pngA4 PDF of a page:
curl -sS -G "https://curlshot.com/api/v1/screenshot" \
-H "X-Access-Key: $CURLSHOT_API_KEY" \
--data-urlencode "url=https://example.com/invoice" \
-d format=pdf -d pdf_paper_format=a4 \
--output page.pdfMarkdown rendered to a PDF:
curl -sS -X POST "https://curlshot.com/api/v1/screenshot" \
-H "X-Access-Key: $CURLSHOT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"markdown": "# Release notes\n\n- Faster renders", "format": "pdf"}' \
--output notes.pdfCheck the status before trusting the file:
status=$(curl -sS -G "https://curlshot.com/api/v1/screenshot" \
-H "X-Access-Key: $CURLSHOT_API_KEY" \
--data-urlencode "url=https://example.com" \
-o shot.png -w '%{http_code}')
[ "$status" = 200 ] || { cat shot.png; rm shot.png; }Resources
- Docs: https://curlshot.com/docs
- Getting started: https://curlshot.com/docs/getting-started.md
- All options: https://curlshot.com/docs/options.md
- Device presets: https://curlshot.com/docs/devices.md
- Errors: https://curlshot.com/docs/errors.md
- OpenAPI description: https://curlshot.com/openapi.json
- Everything in one file: https://curlshot.com/llms-full.txt
- Pricing: https://curlshot.com/pricing
- MCP alternative: agents with MCP support can use the hosted server
https://curlshot.com/api/mcp(streamable HTTP,Authorization: Bearer <key>) with the toolstake_screenshotandlist_devices. Setup per client is in this repository's README.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

