{"openapi":"3.1.0","info":{"title":"Grabbit Screenshot API","version":"1.0.0","summary":"Send a URL, get back a hosted screenshot.","description":"Grabbit renders any public web page in a real browser and returns a hosted PNG, JPEG, or WebP. Flat $0.002 per live grab; sk_test_ keys return free placeholder images so you can integrate before paying. Errors always use the envelope `{\"error\": {\"code\", \"message\"}}` with a stable machine-readable code.","contact":{"name":"Grabbit support","email":"support@grabbit.live","url":"https://www.grabbit.live/contact"},"termsOfService":"https://www.grabbit.live/terms"},"externalDocs":{"description":"API reference","url":"https://www.grabbit.live/docs"},"servers":[{"url":"https://api.grabbit.live/v1","description":"Production"},{"url":"https://www.grabbit.live/api/v1","description":"Production (same API on the web origin)"}],"tags":[{"name":"Grabs","description":"Capture and retrieve screenshots."},{"name":"Account","description":"Credits, usage, and pricing."}],"security":[{"bearerAuth":[]},{"oauth2":["grabs"]}],"paths":{"/grabs":{"post":{"operationId":"createGrab","summary":"Capture a screenshot of a URL","description":"Renders a public web page in a real Chromium browser and returns a hosted image URL. Synchronous by default (the render times out after 25 seconds). With a live key, send `Prefer: respond-async` or `?async=true` to get a 202 with a grab id, then poll GET /grabs/{id}. Live keys spend one credit per successful grab. sk_test_ keys always return a synchronous 200 placeholder, even when async is requested.","tags":["Grabs"],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Optional. Retries with the same key return the original response.","schema":{"type":"string"}},{"name":"Prefer","in":"header","required":false,"description":"Optional for live keys. `respond-async` queues the grab and returns 202. Test keys still return a synchronous 200 placeholder.","schema":{"type":"string"}},{"name":"async","in":"query","required":false,"description":"Optional for live keys. Same as `Prefer: respond-async`; test keys still return a synchronous 200 placeholder.","schema":{"type":"boolean"}}],"security":[{"bearerAuth":[]},{"oauth2":["grabs"]}],"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl https://api.grabbit.live/v1/grabs \\\n  -H \"Authorization: Bearer sk_test_...\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"url\": \"https://example.com\", \"full_page\": true}'"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGrabRequest"}}}},"responses":{"200":{"description":"Captured. image_url is ready.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Grab"}}}},"202":{"description":"Queued (async). Poll GET /grabs/{id}.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Grab"}}}},"400":{"description":"Invalid input (`bad_request`, `invalid_viewport`, `ssrf_detected`, `idempotency_mismatch`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid Bearer token (`unauthorized`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"No live credits left (`credits_exhausted`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Same Idempotency-Key still in flight (`idempotency_conflict`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The target site blocked the capture (`render_blocked`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`rate_limit_exceeded` or `queue_limit_exceeded`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"The page could not be rendered (`render_failed`, `internal_error`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"operationId":"listGrabs","summary":"List recent grabs","description":"Lists the calling key's grabs, newest first, scoped to the key's team and environment.","tags":["Grabs"],"parameters":[{"name":"limit","in":"query","required":false,"description":"1 to 100. Default 25.","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"status","in":"query","required":false,"description":"Optional status filter.","schema":{"type":"string","enum":["pending","processing","done","failed"]}}],"security":[{"bearerAuth":[]},{"oauth2":["grabs"]}],"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl \"https://api.grabbit.live/v1/grabs?limit=10\" -H \"Authorization: Bearer sk_test_...\""}],"responses":{"200":{"description":"A page of grabs, newest first.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GrabList"}}}},"400":{"description":"Unknown status filter (`bad_request`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid Bearer token (`unauthorized`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/grabs/{id}":{"get":{"operationId":"getGrab","summary":"Fetch one grab","description":"Returns a single grab. Poll this after an async create until status is done or failed.","tags":["Grabs"],"parameters":[{"name":"id","in":"path","required":true,"description":"The grab id.","schema":{"type":"string","format":"uuid"}}],"security":[{"bearerAuth":[]},{"oauth2":["grabs"]}],"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl https://api.grabbit.live/v1/grabs/GRAB_ID -H \"Authorization: Bearer sk_test_...\""}],"responses":{"200":{"description":"The grab.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Grab"}}}},"401":{"description":"Missing or invalid Bearer token (`unauthorized`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No grab with that id for this key (`not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/usage":{"get":{"operationId":"getUsage","summary":"Get credit balance and usage","description":"Returns remaining credits (subscription + prepaid), the plan, and 30-day grab counts. Check this before a large batch so you can top up first.","tags":["Account"],"security":[{"bearerAuth":[]},{"oauth2":["grabs"]}],"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl https://api.grabbit.live/v1/usage -H \"Authorization: Bearer sk_live_...\""}],"responses":{"200":{"description":"Credits and usage.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Usage"}}}},"401":{"description":"Missing or invalid Bearer token (`unauthorized`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/pricing":{"get":{"operationId":"getPricing","summary":"Get pricing and competitor comparison","description":"Public, no auth. Flat per-grab price, prepaid packages, and a dated comparison against other screenshot APIs.","tags":["Account"],"parameters":[{"name":"provider","in":"query","required":false,"description":"Optional competitor filter for a smaller comparison response.","schema":{"type":"string","enum":["urlbox","screenshotone","apiflash"]}},{"name":"detail","in":"query","required":false,"description":"Use summary for a smaller packet. REST returns full detail by default; MCP get_pricing returns summary by default.","schema":{"type":"string","enum":["summary","full"]}}],"security":[],"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl \"https://api.grabbit.live/v1/pricing?provider=apiflash&detail=full\""}],"responses":{"200":{"description":"Pricing packet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Pricing"}}}},"400":{"description":"Unknown provider or detail value (`bad_request`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key from https://grabbit.live/app/api-keys. sk_live_ keys render real screenshots and spend credits; sk_test_ keys return free placeholders."},"oauth2":{"type":"oauth2","description":"OAuth 2.1 authorization code + PKCE with dynamic client registration (RFC 7591). Used by MCP clients such as claude.ai.","flows":{"authorizationCode":{"authorizationUrl":"https://www.grabbit.live/oauth/authorize","tokenUrl":"https://www.grabbit.live/api/v1/oauth/token","refreshUrl":"https://www.grabbit.live/api/v1/oauth/token","scopes":{"grabs":"Create, list, and read screenshots and read the team's credit balance."}}}}},"schemas":{"Grab":{"type":"object","properties":{"id":{"description":"Grab id.","type":"string","format":"uuid"},"status":{"description":"Lifecycle state. Only done grabs have an image_url.","type":"string","enum":["pending","processing","done","failed"]},"target_url":{"description":"The captured URL.","type":"string","format":"uri"},"image_url":{"description":"Hosted image URL once status is done (relative for sk_test_ placeholders).","anyOf":[{"type":"string"},{"type":"null"}]},"width":{"description":"Viewport width in pixels.","anyOf":[{"type":"integer","minimum":0},{"type":"null"}]},"height":{"description":"Viewport height in pixels (3240 in the response for full_page captures).","anyOf":[{"type":"integer","minimum":0},{"type":"null"}]},"format":{"description":"Image format.","anyOf":[{"type":"string","enum":["png","jpeg","webp"]},{"type":"null"}]},"bytes":{"description":"Image size in bytes.","anyOf":[{"type":"integer","minimum":0},{"type":"null"}]},"execution_ms":{"description":"Render time in milliseconds.","anyOf":[{"type":"integer","minimum":0},{"type":"null"}]},"error_message":{"description":"Why a failed grab failed.","anyOf":[{"type":"string"},{"type":"null"}]},"created_at":{"description":"ISO 8601 creation time.","type":"string","format":"date-time"}},"required":["id","status","created_at"],"additionalProperties":{}},"GrabList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Grab"}},"has_more":{"type":"boolean"}},"required":["data","has_more"],"additionalProperties":{}},"Usage":{"type":"object","properties":{"credits":{"type":"object","properties":{"subscription":{"type":"integer"},"prepaid":{"type":"integer"},"total":{"type":"integer"}},"required":["subscription","prepaid","total"],"additionalProperties":{}},"plan":{"type":"object","properties":{"name":{"type":"string"},"status":{"type":"string"},"expires_at":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["name","status","expires_at"],"additionalProperties":{}},"usage":{"type":"object","properties":{"grabs_last_30d":{"description":"All grabs, both environments.","type":"integer"},"live_grabs_last_30d":{"type":"integer"}},"required":["grabs_last_30d","live_grabs_last_30d"],"additionalProperties":{}},"environment":{"type":"string","enum":["live","test"]},"top_up":{"description":"Where to buy more credits.","type":"string"}},"required":["credits","plan","usage","environment","top_up"],"additionalProperties":{}},"Pricing":{"type":"object","properties":{"pricing":{"type":"object","properties":{"per_grab_usd":{"type":"number"},"currency":{"type":"string"},"billing_model":{"type":"string"},"free_tier":{"type":"boolean"},"test_mode":{"type":"string"},"annual":{"type":"object","properties":{"price_usd":{"type":"number"},"credits_per_year":{"type":"integer"},"reset_policy":{"type":"string"}},"required":["price_usd","credits_per_year","reset_policy"],"additionalProperties":{}},"prepaid_packages":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"credits":{"type":"integer"},"price_usd":{"type":"number"},"reset_policy":{"type":"string"}},"required":["name","credits","price_usd","reset_policy"],"additionalProperties":{}}}},"required":["per_grab_usd","currency","billing_model","free_tier","test_mode","annual","prepaid_packages"],"additionalProperties":{}},"comparison":{"type":"object","properties":{"schema_version":{"type":"string"},"detail":{"type":"string"},"detail_hint":{"type":"string"},"last_verified":{"type":"string"},"features":{"type":"array","items":{"type":"string"}},"providers":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"plan":{"type":"string"},"per_grab":{"type":"string"},"billing":{"type":"string"},"billing_unit":{"type":"string"},"quota_note":{"type":"string"},"included":{"type":"string"},"unused_credits":{"type":"string"},"features_supported":{"type":"array","items":{"type":"string"}},"agent_install":{"type":"string"},"source_url":{"type":"string"},"verified_on":{"type":"string"},"evidence_status":{"type":"string"},"pricing_evidence":{"type":"object","properties":{"source_url":{"type":"string"},"locator":{"type":"string"},"note":{"type":"string"},"status":{"type":"string"}},"required":["source_url","locator","note","status"],"additionalProperties":{}},"quota_evidence":{"anyOf":[{"type":"object","properties":{"source_url":{"type":"string"},"locator":{"type":"string"},"note":{"type":"string"},"status":{"type":"string"}},"required":["source_url","locator","note","status"],"additionalProperties":{}},{"type":"null"}]},"capture_evidence":{"type":"object","properties":{"source_url":{"type":"string"},"locator":{"type":"string"},"note":{"type":"string"},"status":{"type":"string"}},"required":["source_url","locator","note","status"],"additionalProperties":{}},"agent_evidence":{"type":"object","properties":{"source_url":{"type":"string"},"locator":{"type":"string"},"note":{"type":"string"},"status":{"type":"string"}},"required":["source_url","locator","note","status"],"additionalProperties":{}},"is_grabbit":{"type":"boolean"}},"required":["name","plan","per_grab","billing","billing_unit","quota_note","included","unused_credits","features_supported","agent_install","source_url","verified_on","evidence_status","pricing_evidence","quota_evidence","capture_evidence","agent_evidence","is_grabbit"],"additionalProperties":{}}},"decision_pages":{"type":"array","items":{"type":"object","properties":{"competitor":{"type":"string"},"url":{"type":"string"},"verdict":{"type":"string"},"pricing_tiers":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"],"additionalProperties":{}}},"capture_capabilities":{"type":"array","items":{"type":"string"}},"best_fit":{"type":"array","items":{"type":"string"}}},"required":["competitor","url","verdict","pricing_tiers","capture_capabilities","best_fit"],"additionalProperties":{}}},"agent_surfaces":{"type":"array","items":{"type":"object","properties":{"provider":{"type":"string"},"comparison_url":{"type":"string"},"surfaces":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"availability":{"type":"string"},"grabbit_availability":{"type":"string"},"source_url":{"type":"string"},"verified_on":{"type":"string"}},"required":["name","availability","grabbit_availability","source_url","verified_on"],"additionalProperties":{}}}},"required":["provider","comparison_url","surfaces"],"additionalProperties":{}}},"sources":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"url":{"type":"string"},"locator":{"type":"string"},"claim_group":{"type":"string"},"verified_on":{"type":"string"},"note":{"type":"string"},"evidence_status":{"type":"string"}},"required":["label","url","locator","claim_group","verified_on","note","evidence_status"],"additionalProperties":{}}},"notes":{"type":"string"}},"required":["schema_version","last_verified","features","providers","decision_pages","agent_surfaces","notes"],"additionalProperties":{}},"links":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}}},"required":["pricing","comparison","links"],"additionalProperties":{}},"CreateGrabRequest":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri","description":"Absolute http(s) URL."},"width":{"type":"integer","minimum":320,"maximum":1920,"default":1280},"height":{"type":"integer","minimum":240,"maximum":1080,"default":720},"format":{"type":"string","enum":["png","jpeg","webp"],"default":"png"},"full_page":{"type":"boolean","default":false},"delay_ms":{"type":"integer","minimum":0,"maximum":10000,"default":0},"selector":{"type":["string","null"],"description":"CSS selector to capture one element."}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["unauthorized","bad_request","invalid_viewport","ssrf_detected","credits_exhausted","not_found","idempotency_conflict","idempotency_mismatch","rate_limit_exceeded","queue_limit_exceeded","render_blocked","render_failed","internal_error"],"description":"Stable machine-readable code. Branch on this, not the message."},"message":{"type":"string","description":"Human-readable explanation."}}}}}}}}