{"openapi":"3.1.0","info":{"title":"Datacrawl API","version":"1.0.0","description":"Search, fetch, and extract for AI agents. Credit-metered: every metered response reports X-Credits-Remaining."},"servers":[{"url":"https://datacrawl.dev"}],"paths":{"/v1/search":{"post":{"operationId":"search","summary":"Web or news search","description":"Commercially licensed web/news search. Costs 1 credit; counts against the plan's monthly search sub-cap.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchRequest"},"example":{"q":"latest EU AI act obligations","kind":"news","count":5}}}},"responses":{"200":{"description":"Success envelope (check `error`/`blocked` fields — unreachable targets still answer 200 with an honest envelope).","headers":{"X-Credits-Remaining":{"description":"Credit balance after this request (metered keys).","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResponse"}}}},"400":{"description":"Invalid input (non-public URL, disallowed tier). Not charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Invalid or missing API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Request body failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (detail: 'rate limit exceeded', with Retry-After: 1) OR credit exhaustion (detail: 'insufficient credits' or 'search credit cap reached', with X-Credits-Remaining). This API never uses HTTP 402.","headers":{"X-Credits-Remaining":{"description":"Credit balance after this request (metered keys).","schema":{"type":"string"}},"Retry-After":{"description":"Present on rps-cap breaches.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"A dependency is unavailable; retry with backoff.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/fetch":{"post":{"operationId":"fetch","summary":"Block-aware page fetch","description":"Fetches a public URL; `render: true` uses a real browser (5 credits vs 1). Private/internal addresses answer 400.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FetchRequest"},"example":{"url":"https://example.com/","render":false}}}},"responses":{"200":{"description":"Success envelope (check `error`/`blocked` fields — unreachable targets still answer 200 with an honest envelope).","headers":{"X-Credits-Remaining":{"description":"Credit balance after this request (metered keys).","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FetchResponse"}}}},"400":{"description":"Invalid input (non-public URL, disallowed tier). Not charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Invalid or missing API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Request body failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (detail: 'rate limit exceeded', with Retry-After: 1) OR credit exhaustion (detail: 'insufficient credits' or 'search credit cap reached', with X-Credits-Remaining). This API never uses HTTP 402.","headers":{"X-Credits-Remaining":{"description":"Credit balance after this request (metered keys).","schema":{"type":"string"}},"Retry-After":{"description":"Present on rps-cap breaches.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"A dependency is unavailable; retry with backoff.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/extract":{"post":{"operationId":"extract","summary":"Structured extraction","description":"Extracts readable text, JSON-LD, or rule-based fields from a URL (fetched for you) or supplied HTML. Costs fetch cost + 1.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExtractRequest"},"example":{"url":"https://example.com/article","mode":"readability"}}}},"responses":{"200":{"description":"Success envelope (check `error`/`blocked` fields — unreachable targets still answer 200 with an honest envelope).","headers":{"X-Credits-Remaining":{"description":"Credit balance after this request (metered keys).","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExtractResponse"}}}},"400":{"description":"Invalid input (non-public URL, disallowed tier). Not charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Invalid or missing API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Request body failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (detail: 'rate limit exceeded', with Retry-After: 1) OR credit exhaustion (detail: 'insufficient credits' or 'search credit cap reached', with X-Credits-Remaining). This API never uses HTTP 402.","headers":{"X-Credits-Remaining":{"description":"Credit balance after this request (metered keys).","schema":{"type":"string"}},"Retry-After":{"description":"Present on rps-cap breaches.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"A dependency is unavailable; retry with backoff.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"schemas":{"SearchRequest":{"properties":{"q":{"title":"Q","type":"string"},"kind":{"default":"web","enum":["web","news"],"title":"Kind","type":"string"},"count":{"default":5,"maximum":50,"minimum":1,"title":"Count","type":"integer"},"freshness":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Freshness"},"site":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Site"},"country":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Country"},"purpose":{"default":"general","title":"Purpose","type":"string"},"cache_ttl":{"anyOf":[{"maximum":604800,"minimum":0,"type":"integer"},{"type":"null"}],"default":null,"title":"Cache Ttl"}},"required":["q"],"title":"SearchRequest","type":"object","description":"Search request. `kind` selects the web or news index."},"SearchResult":{"properties":{"platform":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Platform"},"target_ref":{"title":"Target Ref","type":"string"},"target_url":{"title":"Target Url","type":"string"},"title":{"title":"Title","type":"string"},"excerpt":{"title":"Excerpt","type":"string"},"source":{"title":"Source","type":"string"}},"required":["target_ref","target_url","title","excerpt"],"title":"SearchResult","type":"object"},"Timing":{"properties":{"total_ms":{"default":0.0,"title":"Total Ms","type":"number"},"per_tier_ms":{"additionalProperties":{"type":"number"},"default":{},"title":"Per Tier Ms","type":"object"}},"title":"Timing","type":"object"},"SearchResponse":{"properties":{"results":{"default":[],"items":{"$ref":"#/components/schemas/SearchResult"},"title":"Results","type":"array"},"timing":{"$ref":"#/components/schemas/Timing","default":{"total_ms":0.0,"per_tier_ms":{}}},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Error"},"served_by":{"default":"none","title":"Served By","type":"string"},"from_cache":{"default":false,"title":"From Cache","type":"boolean"}},"title":"SearchResponse","type":"object","description":"Search results with per-result target URLs."},"FetchRequest":{"properties":{"url":{"title":"Url","type":"string"},"render":{"default":false,"title":"Render","type":"boolean"},"country":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Country"},"geo":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Geo"},"force_tier":{"anyOf":[{"enum":["direct","playwright"],"type":"string"},{"type":"null"}],"default":null,"title":"Force Tier"},"max_tier":{"anyOf":[{"enum":["direct","playwright"],"type":"string"},{"type":"null"}],"default":null,"title":"Max Tier"},"cache_ttl":{"anyOf":[{"minimum":0,"type":"integer"},{"type":"null"}],"default":null,"title":"Cache Ttl"},"cache_read":{"default":true,"title":"Cache Read","type":"boolean"},"timeout":{"anyOf":[{"exclusiveMinimum":0,"type":"number"},{"type":"null"}],"default":null,"title":"Timeout"},"headers":{"additionalProperties":{"type":"string"},"default":{},"title":"Headers","type":"object"},"settle":{"default":false,"title":"Settle","type":"boolean"},"capture_xhr":{"default":[],"items":{"type":"string"},"title":"Capture Xhr","type":"array"},"warm_up_url":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Warm Up Url"}},"required":["url"],"title":"FetchRequest","type":"object","description":"Fetch request. force_tier/max_tier accept only the customer tiers listed in their enums; other values answer 400 without charging."},"AttemptRecord":{"properties":{"tier":{"enum":["direct","playwright"],"title":"Tier","type":"string"},"status":{"anyOf":[{"type":"integer"},{"type":"null"}],"default":null,"title":"Status"},"blocked":{"default":false,"title":"Blocked","type":"boolean"},"ok":{"default":false,"title":"Ok","type":"boolean"},"skipped":{"default":false,"title":"Skipped","type":"boolean"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Error"},"ms":{"default":0.0,"title":"Ms","type":"number"}},"required":["tier"],"title":"AttemptRecord","type":"object"},"FetchResponse":{"properties":{"final_url":{"default":"","title":"Final Url","type":"string"},"status":{"default":0,"title":"Status","type":"integer"},"html":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Html"},"which_tier_succeeded":{"anyOf":[{"enum":["direct","playwright"],"type":"string"},{"type":"null"}],"default":null,"title":"Which Tier Succeeded"},"blocked":{"default":false,"title":"Blocked","type":"boolean"},"from_cache":{"default":false,"title":"From Cache","type":"boolean"},"attempts":{"default":[],"items":{"$ref":"#/components/schemas/AttemptRecord"},"title":"Attempts","type":"array"},"timing":{"$ref":"#/components/schemas/Timing","default":{"total_ms":0.0,"per_tier_ms":{}}},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Error"},"captured":{"default":[],"items":{"additionalProperties":true,"type":"object"},"title":"Captured","type":"array"}},"title":"FetchResponse","type":"object","description":"Fetched page envelope (check `error`/`blocked`)."},"DataPointRule":{"properties":{"name":{"title":"Name","type":"string"},"selector":{"title":"Selector","type":"string"},"selector_type":{"default":"css","enum":["css","xpath"],"title":"Selector Type","type":"string"},"regex":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Regex"},"split_by":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Split By"},"replacements":{"additionalProperties":{"type":"string"},"default":{},"title":"Replacements","type":"object"},"single":{"default":true,"title":"Single","type":"boolean"}},"required":["name","selector"],"title":"DataPointRule","type":"object"},"ExtractRequest":{"properties":{"url":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Url"},"html":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Html"},"mode":{"default":"readability","enum":["readability","structured","rules"],"title":"Mode","type":"string"},"render":{"default":false,"title":"Render","type":"boolean"},"country":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Country"},"rules":{"default":[],"items":{"$ref":"#/components/schemas/DataPointRule"},"title":"Rules","type":"array"}},"title":"ExtractRequest","type":"object","description":"Extract request. Provide `url` or inline `html`."},"ExtractResponse":{"properties":{"final_url":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Final Url"},"content":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Content"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Title"},"excerpt":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Excerpt"},"lang":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Lang"},"jsonld":{"default":[],"items":{"additionalProperties":true,"type":"object"},"title":"Jsonld","type":"array"},"jsonld_types":{"default":[],"items":{"type":"string"},"title":"Jsonld Types","type":"array"},"data_points":{"additionalProperties":true,"default":{},"title":"Data Points","type":"object"},"blocked":{"default":false,"title":"Blocked","type":"boolean"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Error"}},"title":"ExtractResponse","type":"object","description":"Extraction results for the selected `mode`."},"Error":{"type":"object","properties":{"detail":{"type":"string"}},"required":["detail"],"description":"Error envelope for 4xx/5xx responses."}},"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Your API key: Authorization: Bearer ak_YOUR_KEY"}}}}