Clioos logoclioos.Shot

Website screenshots, one POST away.

Shot renders any public URL to a PNG, JPEG or WebP — full page, a single element, ads blocked. No SDK, no browser to manage. Free 20 renders a day, no credit card.

Get a free API key
Screenshot of clioos.com rendered live by Shot
Rendered live by Shot — this is a real screenshot of clioos.com, captured with POST /v1/screenshot.

Shot at a glance: POST a URL, get a screenshot back. Free 20 renders a day per key, no credit card. PNG, JPEG or WebP; full page or one element; ads blocked; results cached for 1 hour.

Full-page capture

Scrolls the page step by step to trigger lazy loading, then captures the whole document — not just the viewport.

Element screenshots

Pass a CSS selector and get only that element — a chart, a card, a hero section.

Ads blocked

Trackers and ad networks are blocked by default, so captures are clean and faster.

Fast, cached

Repeat renders of the same URL are served from a 1-hour cache. Typical render: under 2 seconds.

Safe by default

Private IPs, localhost, cloud metadata endpoints and redirect tricks are all blocked. No anonymous endpoint.

Simple API

One endpoint, one Bearer key, image bytes back. JSON metadata mode with Accept: application/json.

API docs

POST /v1/screenshot — synchronous, 30 s hard timeout.

curl -X POST https://clioos.com/shot/v1/screenshot \
  -H "Authorization: Bearer YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com", "full_page": true}' \
  --output shot.png

Python

import requests

r = requests.post(
    "https://clioos.com/shot/v1/screenshot",
    headers={"Authorization": "Bearer YOUR_KEY"},
    json={"url": "https://example.com", "full_page": True},
    timeout=60,
)
r.raise_for_status()
open("shot.png", "wb").write(r.content)

JavaScript (Node 18+)

const res = await fetch("https://clioos.com/shot/v1/screenshot", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ url: "https://example.com", full_page: true }),
});
if (!res.ok) throw new Error(`Shot failed: ${res.status}`);
const { writeFileSync } = await import("node:fs");
writeFileSync("shot.png", Buffer.from(await res.arrayBuffer()));

Go

package main

import (
	"bytes"
	"encoding/json"
	"net/http"
	"os"
)

func main() {
	body, _ := json.Marshal(map[string]any{
		"url": "https://example.com", "full_page": true,
	})
	req, _ := http.NewRequest("POST",
		"https://clioos.com/shot/v1/screenshot", bytes.NewReader(body))
	req.Header.Set("Authorization", "Bearer YOUR_KEY")
	req.Header.Set("Content-Type", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	if res.StatusCode != http.StatusOK {
		panic("Shot failed: " + res.Status)
	}
	f, _ := os.Create("shot.png")
	defer f.Close()
	buf := new(bytes.Buffer)
	buf.ReadFrom(res.Body)
	f.Write(buf.Bytes())
}
ParameterDefaultNotes
url—Required. http/https only.
width / height1280 / 800width 320–2000, height 200–4000.
full_pagetrueCapture the whole page.
formatpngpng / jpeg / webp. jpeg & webp take quality 10–100.
device_scale_factor11–2 (retina).
selector—CSS selector: capture only that element.
delay1sExtra wait after load, 0–5s.
block_adstrueBlock ad/tracker requests.
dark_modefalsePrefer dark color scheme.

Responses carry X-Render-Ms, X-Cache: HIT/MISS and X-RateLimit-Remaining. Errors are JSON: 400 bad parameter · 401 bad key · 402 daily limit reached · 422 unsafe URL · 429 rate limited (with Retry-After) · 504 render timeout · 502 target unreachable (upstream status included).

Limits: free key 20 renders/day + 5 requests/minute; 50 renders/day per IP. Images are cached for 1 hour. We do not run JavaScript you send us, and we do not accept custom headers or cookies.

Pricing

Probe period: free. Every key gets 20 renders/day, no credit card, no expiry while the probe runs. Paid packs are not on sale yet — the probe is measuring what people actually need before we set prices.

If you would pay for a larger pack, tell us below. It only registers interest — no payment, no commitment.

Get a free API key

Interested in a paid pack?

Register interest only — no payment is taken, and paid packs do not exist yet.

Frequently asked questions

How many screenshots can I take for free?
Every free key gets 20 renders per day, plus a 50 renders per day limit per IP. No credit card is required while the probe runs.

What image formats does Shot support?
PNG, JPEG and WebP. JPEG and WebP take a quality setting from 10 to 100. You can capture the full page or a single element with a CSS selector.

Are repeat screenshots cached?
Yes. The same URL and parameters are served from a 1-hour cache, and cached renders do not consume your daily quota.

Is there a rate limit?
Yes: 5 requests per minute per key, 20 renders per day per key, and 50 renders per day per IP. Over the limit you get a 429 or 402 response with a Retry-After header.

Can Shot screenshot private or internal URLs?
No. Private IPs, localhost, cloud metadata endpoints and redirect tricks are blocked. Only public http/https URLs are rendered.

Privacy & data retention

Your email is used only to send your verification code and API key, and to tell you when paid packs launch. It is never sold or shared.

Render logs (the URL you asked for, when, and whether it succeeded) are kept for quota enforcement and statistics while the probe runs. Cached screenshots expire after 1 hour. Expired unused verification codes are deleted automatically.

To delete your account, API key and render history, email contact@clioos.com from the same address and we will remove them.