{"openapi":"3.1.0","info":{"title":"API","version":"1.0.0","description":"Screenshots, HTML to PDF and OG images over one API key."},"servers":[{"url":"https://api.softaleo.com"}],"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"Your API key: `Authorization: Bearer sk_…`. Issued once and never shown again."}},"schemas":{},"parameters":{}},"paths":{"/v1/ping":{"get":{"summary":"Liveness ping","description":"Answers immediately and counts as one metered call. The reference route: everything /v1 does, it does.","security":[{"apiKey":[]}],"responses":{"200":{"description":"pong","content":{"application/json":{"schema":{"type":"object","properties":{"pong":{"type":"boolean","enum":[true]},"app":{"type":"string"},"version":{"type":"string"}},"required":["pong","app","version"]}}}},"401":{"description":"Missing, unknown or revoked key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":{"nullable":true}}}}},"429":{"description":"Per-minute rate limit (`rate_limited`) or monthly quota (`quota_exceeded`)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":{"nullable":true}}}}}}}},"/v1/screenshot":{"post":{"summary":"Render a URL to a PNG or JPEG","description":"Renders a public URL in a pooled Chromium and answers with the image. Every byte the browser fetches — the page, each sub-resource and every redirect hop — goes through a guard that resolves the name itself and dials the address it resolved, so a private address is unreachable however it is spelled. Identical requests inside 24 h are served from cache and are still metered.","security":[{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","minLength":1,"maxLength":2048,"description":"Absolute http(s) URL of a page on the public internet."},"width":{"type":"integer","minimum":1,"maximum":2000,"default":1280},"height":{"type":"integer","minimum":1,"maximum":2000,"default":800},"fullPage":{"type":"boolean","default":false,"description":"Capture the whole scroll height, clipped at 8000 px."},"deviceScaleFactor":{"type":"number","minimum":1,"maximum":2,"default":1},"waitUntil":{"type":"string","enum":["load","domcontentloaded","networkidle"],"default":"load"},"omitBackground":{"type":"boolean","default":false},"format":{"type":"string","enum":["png","jpeg"],"default":"png"},"quality":{"type":"integer","minimum":1,"maximum":100,"description":"JPEG only."}},"required":["url"]}}}},"responses":{"200":{"description":"The rendered image. `x-cache: hit|miss` says whether anything was rendered; `x-render-blocked` counts sub-resources the guard refused, so a screenshot with holes in it says why.","content":{"image/png":{"schema":{"type":"string","format":"binary"}},"image/jpeg":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"`invalid_request` — the body did not validate","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":{"nullable":true}}}}},"401":{"description":"Missing, unknown or revoked key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":{"nullable":true}}}}},"422":{"description":"`url_rejected` with a `reason`: `private_address`, `bad_scheme`, `credentials_in_url`, `bad_host`, `denied_host` or `dns_failure`. The URL is never echoed back.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":{"nullable":true}}}}},"429":{"description":"`rate_limited`, `quota_exceeded` or `concurrent_limit`","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":{"nullable":true}}}}},"502":{"description":"`render_failed` — the target answered, but the page could not be rendered","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":{"nullable":true}}}}},"503":{"description":"`busy` (every render slot is taken; retry) or `guard_unverified` (this instance will not render)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":{"nullable":true}}}}},"504":{"description":"`render_timeout` — the page did not settle inside the budget","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":{"nullable":true}}}}}}}}}}