API Reference

The cwick.us API lets you capture website screenshots and extract Open Graph metadata with simple HTTP requests. No SDK required.

Base URL

https://cwick.us
POST /v1/screenshot

Capture a website screenshot

GET /v1/screenshot/:id

Retrieve a cached screenshot

GET /v1/og

Extract Open Graph metadata

GET /health

API status (no auth required)

Authentication

All API requests (except /health) require an API key sent via the X-API-Key header.

request header
X-API-Key: cw_live_your_api_key_here

Keep your API key secret

Never expose your API key in client-side code, public repositories, or browser requests. Use it only from your backend server.

Rate Limits

Each plan includes a monthly request allowance. Both screenshot and OG requests count toward your limit. Usage resets on the 1st of each month.

Plan Monthly Limit Price
Free100$0/mo
Starter5,000$19/mo
Pro25,000$49/mo
Business100,000$149/mo

Response Headers

Every authenticated response includes rate limit information:

X-RateLimit-Limit: 5000
X-RateLimit-Remaining: 4998

When you exceed your limit, the API responds with 429 Too Many Requests and a JSON body with your usage details.

Error Handling

All errors return JSON with an error code and human-readable message.

error response
{
  "error": "validation_error",
  "details": [
    { "field": "url", "message": "Invalid url" }
  ]
}
Status Error Code Description
400 validation_error Invalid or missing request parameters
401 unauthorized Missing or invalid API key
403 forbidden API key is deactivated
404 element_not_found Specified CSS selector not found on page
404 not_found Cached screenshot expired or missing
429 rate_limit_exceeded Monthly request limit reached
500 capture_failed Screenshot capture error
500 extraction_failed OG metadata extraction error
504 timeout Page took too long to load
POST

/v1/screenshot

Capture a screenshot of any public URL. Returns the image as binary data, base64, or a JSON reference to a cached file.

Request Body

JSON body with the following parameters:

Parameter Type Default Description
url * string URL to capture. Must be http:// or https://
width integer 1280 Viewport width. 320–3840
height integer 720 Viewport height. 240–2160
format string "png" png or jpeg
quality integer 80 Image quality. 1–100. Applies to JPEG only
full_page boolean false Capture the entire scrollable page
dark_mode boolean false Use prefers-color-scheme: dark
delay integer 0 Wait time in ms after page load. 0–10000
selector string CSS selector to screenshot a specific element
device_scale_factor number 1 Pixel density. 1–3. Use 2 for Retina
response_type string "binary" binary, json, or base64

Response Types

Returns raw image bytes. The Content-Type header indicates the format.

Headers:

Content-Type: image/png
X-Render-Time-Ms: 1423

Body: <raw image bytes>

Returns a JSON reference to the cached screenshot. Retrieve it via GET /v1/screenshot/:id. Screenshots are cached for 24 hours.

{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "url": "/v1/screenshot/a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "format": "png",
  "width": 1280,
  "height": 720,
  "size": 245891,
  "mime_type": "image/png",
  "render_time_ms": 1423
}

Returns the screenshot as a base64-encoded string inside JSON. Useful for embedding directly in HTML or storing in databases.

{
  "data": "iVBORw0KGgoAAAANSUhEUg...",
  "format": "png",
  "width": 1280,
  "height": 720,
  "size": 245891,
  "render_time_ms": 1423
}

Example

curl
curl -X POST https://cwick.us/v1/screenshot \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com",
    "width": 1920,
    "height": 1080,
    "format": "jpeg",
    "quality": 90,
    "dark_mode": true,
    "full_page": false
  }' \
  --output screenshot.jpg
GET

/v1/screenshot/:id

Retrieve a previously captured screenshot by its ID. Screenshots are cached for 24 hours after creation. The response is the raw image with appropriate Content-Type header.

Path Parameters

Parameter Type Description
id * string (UUID) The screenshot ID returned from a response_type: "json" request

Example

curl
curl https://cwick.us/v1/screenshot/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
  -H "X-API-Key: YOUR_API_KEY" \
  --output screenshot.png
GET

/v1/og

Extract Open Graph metadata from any public URL. Returns structured JSON with title, description, images, favicons, and Twitter Card data.

Query Parameters

Parameter Type Description
url * string URL to extract metadata from. Must be http:// or https://

Response

200 OK
{
  "data": {
    "title": "GitHub: Let's build from here",
    "description": "GitHub is where over 100 million developers...",
    "image": "https://github.githubassets.com/assets/hero-lg.webp",
    "favicon": "https://github.githubassets.com/favicons/favicon.svg",
    "site_name": "GitHub",
    "type": "website",
    "locale": "en_US",
    "twitter_card": "summary_large_image",
    "twitter_site": "@github",
    "twitter_title": "GitHub: Let's build from here",
    "twitter_description": "GitHub is where over 100 million developers...",
    "twitter_image": "https://github.githubassets.com/assets/hero-lg.webp",
    "theme_color": "#1e2327"
  },
  "source_url": "https://github.com",
  "extract_time_ms": 892
}

Example

curl
curl "https://cwick.us/v1/og?url=https://github.com" \
  -H "X-API-Key: YOUR_API_KEY"
GET

/health

Check API status. This endpoint does not require authentication and is suitable for uptime monitoring.

Response

200 OK
{
  "status": "ok",
  "browser": "running",
  "active_renders": 1,
  "queued": 0,
  "uptime": 86420
}

Code Examples

Complete examples in popular languages. No SDK needed — just HTTP requests.

Screenshot to file

curl -X POST https://cwick.us/v1/screenshot \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com", "width": 1920, "height": 1080}' \
  --output screenshot.png

Full-page dark mode screenshot

curl -X POST https://cwick.us/v1/screenshot \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://github.com", "full_page": true, "dark_mode": true, "format": "jpeg", "quality": 90}' \
  --output github-dark.jpg

Extract OG metadata

curl "https://cwick.us/v1/og?url=https://github.com" \
  -H "X-API-Key: YOUR_API_KEY"

Screenshot with fetch (Node.js)

import { writeFile } from 'fs/promises';

const response = await fetch('https://cwick.us/v1/screenshot', {
  method: 'POST',
  headers: {
    'X-API-Key': process.env.CWICKUS_API_KEY,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    url: 'https://example.com',
    width: 1920,
    height: 1080,
    format: 'jpeg',
    quality: 90,
  }),
});

const buffer = Buffer.from(await response.arrayBuffer());
await writeFile('screenshot.jpg', buffer);

console.log('Render time:', response.headers.get('X-Render-Time-Ms'), 'ms');
console.log('Remaining:', response.headers.get('X-RateLimit-Remaining'));

OG metadata extraction

const response = await fetch(
  'https://cwick.us/v1/og?url=https://github.com',
  { headers: { 'X-API-Key': process.env.CWICKUS_API_KEY } }
);

const { data } = await response.json();
console.log(data.title);       // "GitHub: Let's build from here"
console.log(data.description);  // "GitHub is where over 100 million..."
console.log(data.image);        // "https://github.githubassets.com/..."

Base64 response (for embedding)

const response = await fetch('https://cwick.us/v1/screenshot', {
  method: 'POST',
  headers: {
    'X-API-Key': process.env.CWICKUS_API_KEY,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    url: 'https://example.com',
    response_type: 'base64',
    format: 'jpeg',
    quality: 70,
  }),
});

const { data, format } = await response.json();
const imgSrc = `data:image/${format};base64,${data}`;
// Use imgSrc in an <img> tag or store in database

Screenshot with requests

import requests
import os

response = requests.post(
    'https://cwick.us/v1/screenshot',
    headers={'X-API-Key': os.environ['CWICKUS_API_KEY']},
    json={
        'url': 'https://example.com',
        'width': 1920,
        'height': 1080,
        'format': 'jpeg',
        'quality': 90,
        'dark_mode': True,
    },
)

response.raise_for_status()

with open('screenshot.jpg', 'wb') as f:
    f.write(response.content)

print(f"Render time: {response.headers['X-Render-Time-Ms']}ms")
print(f"Remaining: {response.headers['X-RateLimit-Remaining']}")

OG metadata extraction

import requests
import os

response = requests.get(
    'https://cwick.us/v1/og',
    params={'url': 'https://github.com'},
    headers={'X-API-Key': os.environ['CWICKUS_API_KEY']},
)

data = response.json()['data']
print(f"Title: {data['title']}")
print(f"Image: {data['image']}")
print(f"Favicon: {data['favicon']}")

Screenshot with Laravel HTTP

use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Storage;

$response = Http::withHeaders([
    'X-API-Key' => config('services.cwickus.key'),
])->post('https://cwick.us/v1/screenshot', [
    'url' => 'https://example.com',
    'width' => 1920,
    'height' => 1080,
    'format' => 'jpeg',
    'quality' => 90,
]);

Storage::put('screenshots/example.jpg', $response->body());

$renderTime = $response->header('X-Render-Time-Ms');
$remaining = $response->header('X-RateLimit-Remaining');

OG metadata with Guzzle

$client = new \GuzzleHttp\Client();

$response = $client->get('https://cwick.us/v1/og', [
    'headers' => ['X-API-Key' => $apiKey],
    'query' => ['url' => 'https://github.com'],
]);

$data = json_decode($response->getBody(), true)['data'];
echo $data['title'];  // "GitHub: Let's build from here"

Screenshot with net/http

require 'net/http'
require 'json'
require 'uri'

uri = URI('https://cwick.us/v1/screenshot')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

request = Net::HTTP::Post.new(uri)
request['X-API-Key'] = ENV['CWICKUS_API_KEY']
request['Content-Type'] = 'application/json'
request.body = {
  url: 'https://example.com',
  width: 1920,
  height: 1080,
  format: 'jpeg'
}.to_json

response = http.request(request)

File.open('screenshot.jpg', 'wb') { |f| f.write(response.body) }
puts "Render time: #{response['X-Render-Time-Ms']}ms"

Screenshot with net/http

package main

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

func main() {
    payload, _ := json.Marshal(map[string]interface{}{
        "url":    "https://example.com",
        "width":  1920,
        "height": 1080,
        "format": "jpeg",
    })

    req, _ := http.NewRequest("POST",
        "https://cwick.us/v1/screenshot",
        bytes.NewBuffer(payload))
    req.Header.Set("X-API-Key", os.Getenv("CWICKUS_API_KEY"))
    req.Header.Set("Content-Type", "application/json")

    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    out, _ := os.Create("screenshot.jpg")
    defer out.Close()
    io.Copy(out, resp.Body)

    fmt.Println("Render time:", resp.Header.Get("X-Render-Time-Ms"), "ms")
}

Ready to start capturing?

Get your API key in seconds. 100 free screenshots every month.

Get Your API Key