{"openapi":"3.1.1","info":{"title":"Plainport REST API","version":"0.1.1","description":"Deterministic remote MCP and REST utilities for public-web intake: fetch readable Markdown, inspect URLs, extract metadata and links, parse feeds and sitemaps, inspect robots rules, convert HTML, diff text, and validate JSON Schema. Stateless Streamable HTTP; no login or model calls. Anonymous V1 requests are processed and discarded; no payload storage or paid AI provider is used.","license":{"name":"MIT","identifier":"MIT"}},"servers":[{"url":"https://plainport.exportitnow.workers.dev","description":"Current Plainport deployment"}],"tags":[{"name":"Web intake","description":"Bounded fetch-and-parse operations for public web resources."},{"name":"Local transformation","description":"Stateless operations that do not access the network."}],"paths":{"/api/v1/tools":{"get":{"operationId":"listTools","summary":"List the Plainport utility catalog","description":"Returns the same stable tool names, descriptions, input schemas, output schemas, and limits exposed through MCP.","responses":{"200":{"description":"Tool catalog","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/health":{"get":{"operationId":"health","summary":"Check service health","responses":{"200":{"description":"Healthy service","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/fetch-markdown":{"post":{"operationId":"fetch_markdown","summary":"Fetch readable Markdown","description":"Fetches one public HTTP/HTTPS page and returns its primary readable content as Markdown. Use this for article or documentation body text without page chrome. It does not run JavaScript; use a browser tool for client-rendered pages. Native text/markdown responses are preserved. Limit: 8 s, 5 redirects, 768 KiB remote body, 150k output characters.","tags":["Web intake"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"url":{"type":"string","minLength":8,"maxLength":2048,"description":"Absolute public HTTP or HTTPS URL without embedded credentials."},"max_chars":{"default":100000,"type":"integer","minimum":1000,"maximum":150000}},"required":["url","max_chars"],"additionalProperties":false},"examples":{"basic":{"value":{"url":"https://example.com","max_chars":50000}}}}}},"responses":{"200":{"description":"Successful deterministic result","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"ok":{"const":true},"data":{"type":"object","properties":{"requested_url":{"type":"string"},"final_url":{"type":"string"},"status":{"type":"integer"},"title":{"type":["string","null"]},"markdown":{"type":"string"},"content_type":{"type":"string"},"source_format":{"enum":["html","markdown","plain_text"]},"redirects":{"type":"array","items":{"type":"object"}},"bytes_read":{"type":"integer"},"truncated":{"type":"boolean"}},"required":["requested_url","final_url","status","title","markdown","content_type","source_format","redirects","bytes_read","truncated"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"},"limits":{"type":"object"}},"required":["request_id","duration_ms"]}},"required":["ok","data","meta"],"additionalProperties":false}}}},"400":{"description":"Invalid input or blocked URL","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"413":{"description":"Request or remote body exceeds a documented limit","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"415":{"description":"Unsupported remote content type","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"422":{"description":"Content could not be parsed or computation was bounded","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"429":{"description":"Rate limit exceeded","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"502":{"description":"Upstream fetch failed","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"504":{"description":"Upstream fetch timed out","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}}}}},"/api/v1/inspect-url":{"post":{"operationId":"inspect_url","summary":"Inspect URL response","description":"Resolves a public URL through bounded redirects and returns status plus a safe allowlist of HTTP headers. Use HEAD for cheap reachability/type checks and GET when a server mishandles HEAD. Use extract_metadata for HTML semantic metadata. Limit: 8 s, 5 redirects, 768 KiB only for GET.","tags":["Web intake"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"url":{"type":"string","minLength":8,"maxLength":2048,"description":"Absolute public HTTP or HTTPS URL without embedded credentials."},"method":{"default":"HEAD","type":"string","enum":["GET","HEAD"]}},"required":["url","method"],"additionalProperties":false},"examples":{"head":{"value":{"url":"https://example.com","method":"HEAD"}}}}}},"responses":{"200":{"description":"Successful deterministic result","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"ok":{"const":true},"data":{"type":"object","properties":{"requested_url":{"type":"string"},"final_url":{"type":"string"},"method":{"enum":["GET","HEAD"]},"status":{"type":"integer"},"status_text":{"type":"string"},"content_type":{"type":"string"},"headers":{"type":"object","additionalProperties":{"type":"string"}},"redirects":{"type":"array"},"bytes_read":{"type":"integer"}},"required":["requested_url","final_url","method","status","headers","redirects","bytes_read"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"},"limits":{"type":"object"}},"required":["request_id","duration_ms"]}},"required":["ok","data","meta"],"additionalProperties":false}}}},"400":{"description":"Invalid input or blocked URL","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"413":{"description":"Request or remote body exceeds a documented limit","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"415":{"description":"Unsupported remote content type","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"422":{"description":"Content could not be parsed or computation was bounded","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"429":{"description":"Rate limit exceeded","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"502":{"description":"Upstream fetch failed","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"504":{"description":"Upstream fetch timed out","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}}}}},"/api/v1/extract-metadata":{"post":{"operationId":"extract_metadata","summary":"Extract page metadata","description":"Fetches one public HTML page and extracts title, description, canonical URL, robots directives, Open Graph, Twitter Card, advertised feeds, and parsed JSON-LD. Use this when an agent needs page identity or structured data rather than body text. Limit: 8 s, 5 redirects, 768 KiB, 50 JSON-LD blocks.","tags":["Web intake"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"url":{"type":"string","minLength":8,"maxLength":2048,"description":"Absolute public HTTP or HTTPS URL without embedded credentials."}},"required":["url"],"additionalProperties":false},"examples":{"basic":{"value":{"url":"https://example.com"}}}}}},"responses":{"200":{"description":"Successful deterministic result","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"ok":{"const":true},"data":{"type":"object","properties":{"requested_url":{"type":"string"},"final_url":{"type":"string"},"title":{"type":["string","null"]},"description":{"type":["string","null"]},"canonical_url":{"type":["string","null"]},"language":{"type":["string","null"]},"robots":{"type":["string","null"]},"author":{"type":["string","null"]},"open_graph":{"type":"object"},"twitter":{"type":"object"},"feeds":{"type":"array"},"json_ld":{"type":"array"},"invalid_json_ld_count":{"type":"integer"}},"required":["requested_url","final_url","title","description","canonical_url","open_graph","twitter","feeds","json_ld","invalid_json_ld_count"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"},"limits":{"type":"object"}},"required":["request_id","duration_ms"]}},"required":["ok","data","meta"],"additionalProperties":false}}}},"400":{"description":"Invalid input or blocked URL","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"413":{"description":"Request or remote body exceeds a documented limit","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"415":{"description":"Unsupported remote content type","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"422":{"description":"Content could not be parsed or computation was bounded","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"429":{"description":"Rate limit exceeded","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"502":{"description":"Upstream fetch failed","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"504":{"description":"Upstream fetch timed out","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}}}}},"/api/v1/extract-links":{"post":{"operationId":"extract_links","summary":"Extract page links","description":"Fetches one public HTML page and returns unique normalized HTTP/HTTPS links with anchor text, rel values, and same-origin classification. Use this for bounded navigation discovery; it does not crawl the returned links. Limit: 8 s, 5 redirects, 768 KiB, 500 links.","tags":["Web intake"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"url":{"type":"string","minLength":8,"maxLength":2048,"description":"Absolute public HTTP or HTTPS URL without embedded credentials."},"include_external":{"default":true,"type":"boolean"},"max_links":{"default":100,"type":"integer","minimum":1,"maximum":500}},"required":["url","include_external","max_links"],"additionalProperties":false},"examples":{"internal":{"value":{"url":"https://example.com","include_external":false,"max_links":100}}}}}},"responses":{"200":{"description":"Successful deterministic result","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"ok":{"const":true},"data":{"type":"object","properties":{"requested_url":{"type":"string"},"final_url":{"type":"string"},"links":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string"},"text":{"type":["string","null"]},"rel":{"type":"array","items":{"type":"string"}},"external":{"type":"boolean"}},"required":["url","text","rel","external"]}},"truncated":{"type":"boolean"},"max_links":{"type":"integer"}},"required":["requested_url","final_url","links","truncated","max_links"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"},"limits":{"type":"object"}},"required":["request_id","duration_ms"]}},"required":["ok","data","meta"],"additionalProperties":false}}}},"400":{"description":"Invalid input or blocked URL","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"413":{"description":"Request or remote body exceeds a documented limit","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"415":{"description":"Unsupported remote content type","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"422":{"description":"Content could not be parsed or computation was bounded","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"429":{"description":"Rate limit exceeded","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"502":{"description":"Upstream fetch failed","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"504":{"description":"Upstream fetch timed out","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}}}}},"/api/v1/parse-feed":{"post":{"operationId":"parse_feed","summary":"Parse web feed","description":"Fetches and normalizes RSS 2.0, Atom 1.0, or JSON Feed into a stable item list. Use this when consuming update feeds without format-specific parsing. It does not fetch linked articles. Limit: 8 s, 5 redirects, 768 KiB, 100 items.","tags":["Web intake"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"url":{"type":"string","minLength":8,"maxLength":2048,"description":"Absolute public HTTP or HTTPS URL without embedded credentials."},"max_items":{"default":50,"type":"integer","minimum":1,"maximum":100}},"required":["url","max_items"],"additionalProperties":false},"examples":{"rss":{"value":{"url":"https://example.com/feed.xml","max_items":25}}}}}},"responses":{"200":{"description":"Successful deterministic result","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"ok":{"const":true},"data":{"type":"object","properties":{"format":{"enum":["rss","atom","json_feed"]},"version":{"type":["string","null"]},"title":{"type":["string","null"]},"home_page_url":{"type":["string","null"]},"feed_url":{"type":"string"},"items":{"type":"array","items":{"type":"object"}},"truncated":{"type":"boolean"}},"required":["format","version","title","home_page_url","feed_url","items","truncated"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"},"limits":{"type":"object"}},"required":["request_id","duration_ms"]}},"required":["ok","data","meta"],"additionalProperties":false}}}},"400":{"description":"Invalid input or blocked URL","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"413":{"description":"Request or remote body exceeds a documented limit","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"415":{"description":"Unsupported remote content type","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"422":{"description":"Content could not be parsed or computation was bounded","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"429":{"description":"Rate limit exceeded","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"502":{"description":"Upstream fetch failed","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"504":{"description":"Upstream fetch timed out","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}}}}},"/api/v1/parse-sitemap":{"post":{"operationId":"parse_sitemap","summary":"Parse sitemap","description":"Fetches one uncompressed XML sitemap and returns either URL entries or child sitemap references. Use this for site structure discovery. Sitemap indexes are not recursively expanded; call this tool on each child explicitly. Limit: 8 s, 5 redirects, 768 KiB, 1,000 entries.","tags":["Web intake"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"url":{"type":"string","minLength":8,"maxLength":2048,"description":"Absolute public HTTP or HTTPS URL without embedded credentials."},"max_entries":{"default":250,"type":"integer","minimum":1,"maximum":1000}},"required":["url","max_entries"],"additionalProperties":false},"examples":{"basic":{"value":{"url":"https://example.com/sitemap.xml","max_entries":250}}}}}},"responses":{"200":{"description":"Successful deterministic result","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"ok":{"const":true},"data":{"type":"object","properties":{"kind":{"enum":["urlset","index"]},"sitemap_url":{"type":"string"},"entries":{"type":"array","items":{"type":"object"}},"truncated":{"type":"boolean"}},"required":["kind","sitemap_url","entries","truncated"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"},"limits":{"type":"object"}},"required":["request_id","duration_ms"]}},"required":["ok","data","meta"],"additionalProperties":false}}}},"400":{"description":"Invalid input or blocked URL","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"413":{"description":"Request or remote body exceeds a documented limit","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"415":{"description":"Unsupported remote content type","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"422":{"description":"Content could not be parsed or computation was bounded","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"429":{"description":"Rate limit exceeded","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"502":{"description":"Upstream fetch failed","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"504":{"description":"Upstream fetch timed out","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}}}}},"/api/v1/inspect-robots":{"post":{"operationId":"inspect_robots","summary":"Inspect robots policy","description":"Fetches an origin's robots.txt and evaluates one path for a named user agent using longest-match allow/disallow precedence. Also returns crawl delay and declared sitemaps. Use this before automated retrieval; the result is policy guidance, not authorization. Limit: 8 s, 5 redirects, 768 KiB, 50 sitemap declarations.","tags":["Web intake"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"url":{"type":"string","minLength":8,"maxLength":2048,"description":"Absolute public HTTP or HTTPS URL without embedded credentials."},"user_agent":{"default":"*","type":"string","minLength":1,"maxLength":200},"path":{"default":"/","type":"string","maxLength":2048,"pattern":"^\\/.*"}},"required":["url","user_agent","path"],"additionalProperties":false},"examples":{"crawler":{"value":{"url":"https://example.com/docs","user_agent":"Plainport","path":"/docs"}}}}}},"responses":{"200":{"description":"Successful deterministic result","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"ok":{"const":true},"data":{"type":"object","properties":{"robots_url":{"type":"string"},"status":{"type":"integer"},"allowed":{"type":"boolean"},"matched_rule":{"type":["object","null"]},"crawl_delay":{"type":["number","null"]},"sitemaps":{"type":"array","items":{"type":"string"}},"groups":{"type":"integer"}},"required":["robots_url","status","allowed","matched_rule","crawl_delay","sitemaps","groups"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"},"limits":{"type":"object"}},"required":["request_id","duration_ms"]}},"required":["ok","data","meta"],"additionalProperties":false}}}},"400":{"description":"Invalid input or blocked URL","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"413":{"description":"Request or remote body exceeds a documented limit","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"415":{"description":"Unsupported remote content type","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"422":{"description":"Content could not be parsed or computation was bounded","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"429":{"description":"Rate limit exceeded","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"502":{"description":"Upstream fetch failed","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"504":{"description":"Upstream fetch timed out","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}}}}},"/api/v1/html-to-markdown":{"post":{"operationId":"html_to_markdown","summary":"Convert HTML to Markdown","description":"Converts supplied HTML into readable Markdown without fetching a URL. Use this when the agent already has HTML. Provide base_url only to resolve relative links; use fetch_markdown when Plainport should retrieve the page. Limit: 200k input characters, 150k output characters.","tags":["Local transformation"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"html":{"type":"string","minLength":1,"maxLength":200000},"base_url":{"type":"string","maxLength":2048},"max_chars":{"default":100000,"type":"integer","minimum":1000,"maximum":150000}},"required":["html","max_chars"],"additionalProperties":false},"examples":{"basic":{"value":{"html":"<main><h1>Hello</h1><p>World</p></main>","max_chars":50000}}}}}},"responses":{"200":{"description":"Successful deterministic result","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"ok":{"const":true},"data":{"type":"object","properties":{"title":{"type":["string","null"]},"markdown":{"type":"string"},"truncated":{"type":"boolean"},"input_chars":{"type":"integer"},"max_chars":{"type":"integer"}},"required":["title","markdown","truncated","input_chars","max_chars"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"},"limits":{"type":"object"}},"required":["request_id","duration_ms"]}},"required":["ok","data","meta"],"additionalProperties":false}}}},"400":{"description":"Invalid input or blocked URL","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"413":{"description":"Request or remote body exceeds a documented limit","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"415":{"description":"Unsupported remote content type","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"422":{"description":"Content could not be parsed or computation was bounded","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"429":{"description":"Rate limit exceeded","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"502":{"description":"Upstream fetch failed","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"504":{"description":"Upstream fetch timed out","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}}}}},"/api/v1/diff-text":{"post":{"operationId":"diff_text","summary":"Diff text","description":"Computes a deterministic line- or word-level diff and returns typed add/remove/equal parts. Use this when an agent needs structured change data. Split highly divergent large documents if the computation limit is reached. Limit: 200k combined characters, 2,000 result parts, 8 ms diff budget.","tags":["Local transformation"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"before":{"type":"string","maxLength":200000},"after":{"type":"string","maxLength":200000},"granularity":{"default":"lines","type":"string","enum":["lines","words"]},"ignore_whitespace":{"default":false,"type":"boolean"}},"required":["before","after","granularity","ignore_whitespace"],"additionalProperties":false},"examples":{"lines":{"value":{"before":"one\ntwo","after":"one\nthree","granularity":"lines","ignore_whitespace":false}}}}}},"responses":{"200":{"description":"Successful deterministic result","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"ok":{"const":true},"data":{"type":"object","properties":{"equal":{"type":"boolean"},"granularity":{"enum":["lines","words"]},"parts":{"type":"array","items":{"type":"object","properties":{"operation":{"enum":["add","remove","equal"]},"value":{"type":"string"},"count":{"type":"integer"}},"required":["operation","value","count"]}},"truncated":{"type":"boolean"},"before_chars":{"type":"integer"},"after_chars":{"type":"integer"}},"required":["equal","granularity","parts","truncated","before_chars","after_chars"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"},"limits":{"type":"object"}},"required":["request_id","duration_ms"]}},"required":["ok","data","meta"],"additionalProperties":false}}}},"400":{"description":"Invalid input or blocked URL","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"413":{"description":"Request or remote body exceeds a documented limit","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"415":{"description":"Unsupported remote content type","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"422":{"description":"Content could not be parsed or computation was bounded","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"429":{"description":"Rate limit exceeded","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"502":{"description":"Upstream fetch failed","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"504":{"description":"Upstream fetch timed out","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}}}}},"/api/v1/validate-json-schema":{"post":{"operationId":"validate_json_schema","summary":"Validate JSON Schema","description":"Validates a JSON value against a supplied JSON Schema using draft 4, 7, 2019-09, or 2020-12. Use this to verify generated or extracted structured data. It performs validation only and does not mutate the instance. Limit: 512 KiB request, 40 nesting levels, 100 returned errors.","tags":["Local transformation"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"schema":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"boolean"}]},"instance":{},"draft":{"default":"2020-12","type":"string","enum":["4","7","2019-09","2020-12"]}},"required":["schema","instance","draft"],"additionalProperties":false},"examples":{"basic":{"value":{"schema":{"type":"object","required":["id"],"properties":{"id":{"type":"integer"}}},"instance":{"id":7},"draft":"2020-12"}}}}}},"responses":{"200":{"description":"Successful deterministic result","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"ok":{"const":true},"data":{"type":"object","properties":{"valid":{"type":"boolean"},"draft":{"enum":["4","7","2019-09","2020-12"]},"errors":{"type":"array","items":{"type":"object"}},"errors_truncated":{"type":"boolean"}},"required":["valid","draft","errors","errors_truncated"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"},"limits":{"type":"object"}},"required":["request_id","duration_ms"]}},"required":["ok","data","meta"],"additionalProperties":false}}}},"400":{"description":"Invalid input or blocked URL","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"413":{"description":"Request or remote body exceeds a documented limit","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"415":{"description":"Unsupported remote content type","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"422":{"description":"Content could not be parsed or computation was bounded","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"429":{"description":"Rate limit exceeded","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"502":{"description":"Upstream fetch failed","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}},"504":{"description":"Upstream fetch timed out","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}}}}}}},"components":{"schemas":{"Error":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}},"required":["code","message","retryable"]},"meta":{"type":"object","properties":{"request_id":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["request_id","duration_ms"]}},"required":["ok","error","meta"]}}},"x-plainport-limits":{"urlLength":2048,"requestBodyBytes":524288,"remoteBodyBytes":786432,"transformTextChars":200000,"outputTextChars":150000,"fetchTimeoutMs":8000,"redirects":5,"links":500,"feedItems":100,"sitemapEntries":1000,"jsonDepth":40},"externalDocs":{"description":"Plainport documentation","url":"https://plainport.exportitnow.workers.dev/docs"}}