{"openapi":"3.1.0","info":{"title":"Shotkiln API","version":"0.1.0","description":"Screenshots, PDFs and OG images from any public URL or HTML. Plans: Free 100/mo, Starter 2000/mo, Pro 10000/mo, Scale 50000/mo.","contact":{"name":"Shotkiln support","email":"support@shotkiln.com"}},"servers":[{"url":"https://shotkiln.com"}],"security":[{"ApiKeyHeader":[]},{"Bearer":[]},{}],"paths":{"/v1/screenshot":{"get":{"operationId":"screenshotGet","summary":"Screenshot a web page (query parameters; embeddable in <img src> with api_key)","parameters":[{"name":"url","in":"query","required":true,"schema":{"type":"string","format":"uri","description":"Public http(s) URL (ports 80/443/8080/8443)"}},{"name":"width","in":"query","required":false,"schema":{"type":"integer","minimum":320,"maximum":3840,"default":1280}},{"name":"height","in":"query","required":false,"schema":{"type":"integer","minimum":200,"maximum":3840,"default":800}},{"name":"full_page","in":"query","required":false,"schema":{"type":"boolean","default":false,"description":"Capture the full scrollable page (max 16384 px tall)"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","enum":["png","jpeg","webp"],"default":"png"}},{"name":"quality","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":80,"description":"jpeg/webp only"}},{"name":"delay","in":"query","required":false,"schema":{"type":"integer","minimum":0,"maximum":10000,"default":0,"description":"Extra wait after load (ms)"}},{"name":"device_scale_factor","in":"query","required":false,"schema":{"type":"number","minimum":1,"maximum":3,"default":1}},{"name":"dark_mode","in":"query","required":false,"schema":{"type":"boolean","default":false,"description":"Emulate prefers-color-scheme: dark"}},{"name":"cache_ttl","in":"query","required":false,"schema":{"type":"integer","minimum":0,"maximum":2592000,"default":3600,"description":"Seconds to cache; 0 = always render fresh. Cache hits do not use quota."}}],"responses":{"200":{"description":"Rendered file","content":{"image/png":{},"image/jpeg":{},"image/webp":{}},"headers":{"X-Cache":{"schema":{"type":"string","enum":["HIT","MISS","BYPASS"]}},"X-Quota-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}}}},"400":{"description":"Invalid parameter or blocked URL (code: invalid_parameter, invalid_url, url_blocked, blocked_url)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Invalid or revoked API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Target page too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit, daily limit or monthly quota exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Target page failed to load","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Browser capacity temporarily unavailable (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"Render timed out","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"screenshot","summary":"Screenshot a web page","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"Public http(s) URL (ports 80/443/8080/8443)"},"width":{"type":"integer","minimum":320,"maximum":3840,"default":1280},"height":{"type":"integer","minimum":200,"maximum":3840,"default":800},"full_page":{"type":"boolean","default":false,"description":"Capture the full scrollable page (max 16384 px tall)"},"format":{"type":"string","enum":["png","jpeg","webp"],"default":"png"},"quality":{"type":"integer","minimum":1,"maximum":100,"default":80,"description":"jpeg/webp only"},"delay":{"type":"integer","minimum":0,"maximum":10000,"default":0,"description":"Extra wait after load (ms)"},"device_scale_factor":{"type":"number","minimum":1,"maximum":3,"default":1},"dark_mode":{"type":"boolean","default":false,"description":"Emulate prefers-color-scheme: dark"},"cache_ttl":{"type":"integer","minimum":0,"maximum":2592000,"default":3600,"description":"Seconds to cache; 0 = always render fresh. Cache hits do not use quota."}},"required":["url"]}}}},"responses":{"200":{"description":"Rendered file","content":{"image/png":{},"image/jpeg":{},"image/webp":{}},"headers":{"X-Cache":{"schema":{"type":"string","enum":["HIT","MISS","BYPASS"]}},"X-Quota-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}}}},"400":{"description":"Invalid parameter or blocked URL (code: invalid_parameter, invalid_url, url_blocked, blocked_url)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Invalid or revoked API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Target page too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit, daily limit or monthly quota exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Target page failed to load","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Browser capacity temporarily unavailable (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"Render timed out","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/pdf":{"get":{"operationId":"pdfGet","summary":"Render a URL or HTML to PDF (query parameters; embeddable in <img src> with api_key)","parameters":[{"name":"url","in":"query","required":false,"schema":{"type":"string","format":"uri"}},{"name":"html","in":"query","required":false,"schema":{"type":"string","maxLength":1000000,"description":"Raw HTML; use instead of url"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","enum":["A3","A4","A5","Letter","Legal","Tabloid"],"default":"A4"}},{"name":"landscape","in":"query","required":false,"schema":{"type":"boolean","default":false}},{"name":"print_background","in":"query","required":false,"schema":{"type":"boolean","default":true}},{"name":"margin","in":"query","required":false,"schema":{"type":"string","default":"10mm","description":"All sides; or margin_top/right/bottom/left"}},{"name":"margin_top","in":"query","required":false,"schema":{"type":"string"}},{"name":"margin_right","in":"query","required":false,"schema":{"type":"string"}},{"name":"margin_bottom","in":"query","required":false,"schema":{"type":"string"}},{"name":"margin_left","in":"query","required":false,"schema":{"type":"string"}},{"name":"delay","in":"query","required":false,"schema":{"type":"integer","minimum":0,"maximum":10000,"default":0}},{"name":"cache_ttl","in":"query","required":false,"schema":{"type":"integer","minimum":0,"maximum":2592000,"default":3600}}],"responses":{"200":{"description":"Rendered file","content":{"application/pdf":{}},"headers":{"X-Cache":{"schema":{"type":"string","enum":["HIT","MISS","BYPASS"]}},"X-Quota-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}}}},"400":{"description":"Invalid parameter or blocked URL (code: invalid_parameter, invalid_url, url_blocked, blocked_url)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Invalid or revoked API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Target page too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit, daily limit or monthly quota exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Target page failed to load","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Browser capacity temporarily unavailable (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"Render timed out","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"pdf","summary":"Render a URL or HTML to PDF","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"html":{"type":"string","maxLength":1000000,"description":"Raw HTML; use instead of url"},"format":{"type":"string","enum":["A3","A4","A5","Letter","Legal","Tabloid"],"default":"A4"},"landscape":{"type":"boolean","default":false},"print_background":{"type":"boolean","default":true},"margin":{"type":"string","default":"10mm","description":"All sides; or margin_top/right/bottom/left"},"margin_top":{"type":"string"},"margin_right":{"type":"string"},"margin_bottom":{"type":"string"},"margin_left":{"type":"string"},"delay":{"type":"integer","minimum":0,"maximum":10000,"default":0},"cache_ttl":{"type":"integer","minimum":0,"maximum":2592000,"default":3600}},"required":[]}}}},"responses":{"200":{"description":"Rendered file","content":{"application/pdf":{}},"headers":{"X-Cache":{"schema":{"type":"string","enum":["HIT","MISS","BYPASS"]}},"X-Quota-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}}}},"400":{"description":"Invalid parameter or blocked URL (code: invalid_parameter, invalid_url, url_blocked, blocked_url)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Invalid or revoked API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Target page too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit, daily limit or monthly quota exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Target page failed to load","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Browser capacity temporarily unavailable (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"Render timed out","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/og":{"get":{"operationId":"ogImageGet","summary":"Generate a 1200x630 Open Graph PNG (query parameters; for og:image tags use a signed URL: kid + sig, no API key)","parameters":[{"name":"title","in":"query","required":true,"schema":{"type":"string","maxLength":200}},{"name":"subtitle","in":"query","required":false,"schema":{"type":"string","maxLength":300}},{"name":"template","in":"query","required":false,"schema":{"type":"string","enum":["default","gradient","split"],"default":"default"}},{"name":"theme","in":"query","required":false,"schema":{"type":"string","enum":["light","dark"],"default":"dark"}},{"name":"accent","in":"query","required":false,"schema":{"type":"string","pattern":"^#[0-9a-fA-F]{3}([0-9a-fA-F]{3})?$","default":"#ff5a1f"}},{"name":"site","in":"query","required":false,"schema":{"type":"string","maxLength":60}},{"name":"cache_ttl","in":"query","required":false,"schema":{"type":"integer","minimum":0,"maximum":2592000,"default":604800}},{"name":"kid","in":"query","required":false,"schema":{"type":"string","pattern":"^kid_[0-9A-Za-z]{16}$"},"description":"Signed URLs: the key id from POST /v1/keys/signing-secret"},{"name":"exp","in":"query","required":false,"schema":{"type":"integer"},"description":"Signed URLs: optional expiry, Unix seconds"},{"name":"sig","in":"query","required":false,"schema":{"type":"string","pattern":"^[0-9a-f]{64}$"},"description":"Signed URLs: hex HMAC-SHA256 of \"/v1/og?\" + the other parameters sorted and percent-encoded, keyed with the signing secret"}],"responses":{"200":{"description":"Rendered file","content":{"image/png":{}},"headers":{"X-Cache":{"schema":{"type":"string","enum":["HIT","MISS","BYPASS"]}},"X-Quota-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}}}},"400":{"description":"Invalid parameter or blocked URL (code: invalid_parameter, invalid_url, url_blocked, blocked_url)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Invalid or revoked API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"invalid_signature or signature_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Target page too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit, daily limit or monthly quota exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Target page failed to load","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Browser capacity temporarily unavailable (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"Render timed out","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"ogImage","summary":"Generate a 1200x630 Open Graph PNG","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","maxLength":200},"subtitle":{"type":"string","maxLength":300},"template":{"type":"string","enum":["default","gradient","split"],"default":"default"},"theme":{"type":"string","enum":["light","dark"],"default":"dark"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{3}([0-9a-fA-F]{3})?$","default":"#ff5a1f"},"site":{"type":"string","maxLength":60},"cache_ttl":{"type":"integer","minimum":0,"maximum":2592000,"default":604800}},"required":["title"]}}}},"responses":{"200":{"description":"Rendered file","content":{"image/png":{}},"headers":{"X-Cache":{"schema":{"type":"string","enum":["HIT","MISS","BYPASS"]}},"X-Quota-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}}}},"400":{"description":"Invalid parameter or blocked URL (code: invalid_parameter, invalid_url, url_blocked, blocked_url)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Invalid or revoked API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Target page too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit, daily limit or monthly quota exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Target page failed to load","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Browser capacity temporarily unavailable (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"Render timed out","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/og/sign":{"post":{"operationId":"signOgUrl","summary":"Return a signed /v1/og URL for the given card parameters (optional exp: Unix seconds), safe to publish in og:image","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","maxLength":200},"subtitle":{"type":"string","maxLength":300},"template":{"type":"string","enum":["default","gradient","split"],"default":"default"},"theme":{"type":"string","enum":["light","dark"],"default":"dark"},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{3}([0-9a-fA-F]{3})?$","default":"#ff5a1f"},"site":{"type":"string","maxLength":60},"cache_ttl":{"type":"integer","minimum":0,"maximum":2592000,"default":604800},"exp":{"type":"integer"}},"required":["title"]}}}},"responses":{"200":{"description":"{ url, kid, watermark }","content":{"application/json":{}}},"400":{"description":"Invalid parameter or blocked URL (code: invalid_parameter, invalid_url, url_blocked, blocked_url)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Invalid or revoked API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/keys/signing-secret":{"post":{"operationId":"getSigningSecret","summary":"Return the calling key's kid and signing_secret for signed OG URLs (created on first call)","responses":{"200":{"description":"{ kid, signing_secret }","content":{"application/json":{}}},"401":{"description":"Invalid or revoked API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/keys/signing-secret/rotate":{"post":{"operationId":"rotateSigningSecret","summary":"Replace the signing secret; URLs signed with the old one stop working","responses":{"200":{"description":"{ kid, signing_secret }","content":{"application/json":{}}},"401":{"description":"Invalid or revoked API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/usage":{"get":{"operationId":"usage","summary":"Plan, quota and usage for the calling key","responses":{"200":{"description":"Usage","content":{"application/json":{"schema":{"type":"object","properties":{"plan":{"type":"string"},"plan_name":{"type":"string"},"authenticated":{"type":"boolean"},"month":{"type":"object","properties":{"used":{"type":"integer"},"limit":{"type":"integer"}}},"day":{"type":"object","properties":{"used":{"type":"integer"},"limit":{"type":["integer","null"]}}},"per_minute":{"type":"integer"},"watermark":{"type":"boolean"},"billing":{"type":"boolean","description":"true when the key is linked to a Stripe customer (POST /v1/billing/portal works)"},"resets_at":{"type":"string","format":"date-time","description":"when the monthly quota resets (UTC)"}}}}}},"401":{"description":"Invalid or revoked API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/keys":{"post":{"operationId":"createFreeKey","summary":"Create a free-plan API key (no email; limited per network per day)","responses":{"201":{"description":"Key (shown once)","content":{"application/json":{}}},"429":{"description":"Rate limit, daily limit or monthly quota exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/keys/rotate":{"post":{"operationId":"rotateKey","summary":"Revoke the calling key and return a replacement on the same plan","responses":{"200":{"description":"New key (shown once)","content":{"application/json":{}}},"401":{"description":"Invalid or revoked API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/checkout":{"post":{"operationId":"checkout","summary":"Start a Stripe Checkout session for a paid plan","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"plan":{"type":"string","enum":["starter","pro","scale"]}},"required":["plan"]}}}},"responses":{"200":{"description":"Checkout URL","content":{"application/json":{}}}}}},"/mcp":{"post":{"operationId":"mcp","summary":"Remote MCP endpoint (Streamable HTTP, JSON-RPC 2.0): tools take_screenshot, render_pdf, generate_og_image","responses":{"200":{"description":"JSON-RPC response"}}}}},"components":{"securitySchemes":{"ApiKeyHeader":{"type":"apiKey","in":"header","name":"x-api-key"},"Bearer":{"type":"http","scheme":"bearer"}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}}}}}}