Signed URLs

Every render endpoint has a GET variant authenticated by an HMAC signature instead of your API key. That means a render can live directly in an <img src>, a Notion embed, or an email — no backend in the request path, and your API key never leaves the server.

<!-- Embed a live screenshot straight into HTML or an email -->
<img src="https://rasterkit.com/v1/screenshot?url=https%3A%2F%2Fexample.com&viewport_width=800&key_id=YOUR_KEY_ID&signature=..." width="800" alt="Latest screenshot">

<!-- Signatures are HMAC-SHA256 over the sorted query string with your
     per-key signing secret. Generate them from the dashboard or your backend. -->

How signatures work

  1. Take every query parameter except signature (including key_id and optional expires).
  2. Sort pairs and form key=value&key=value… with URL-encoding.
  3. Compute HMAC-SHA256(signing_secret, "/v1/screenshot?" + canonical_query), hex-encoded.
  4. Append as &signature=….
// Node.js
import { createHmac } from 'node:crypto'

function signedScreenshotUrl(params, keyId, signingSecret) {
  const qs = new URLSearchParams({ ...params, key_id: keyId })
  const sorted = [...qs.entries()].sort(([a], [b]) => a.localeCompare(b))
  const canonical = sorted.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`).join('&')
  const signature = createHmac('sha256', signingSecret)
    .update(`/v1/screenshot?${canonical}`)
    .digest('hex')
  return `https://rasterkit.com/v1/screenshot?${canonical}&signature=${signature}`
}

Notes