{"openapi":"3.1.0","info":{"title":"structura","version":"1.0.0","summary":"Messy input to JSON that provably conforms to your JSON Schema.","description":"Turn a URL, raw HTML, plain text or a PDF-ish blob of text into structured JSON\nthat **provably validates against a JSON Schema you supply**.\n\nThe output of every successful `/extract` has been validated against your exact\nschema, locally, before it was returned. When the model's first output does not\nconform, the precise per-pointer validation errors are fed back and it repairs;\nif it still does not conform after the attempt cap the request returns 5xx and\n**you are not charged**. Non-conforming data is never returned as a success.\n\nThe model is instructed never to fabricate: a value absent from the source comes\nback as `null` (which is why you should make your fields nullable), and every\nresponse carries per-field confidence plus an `absent[]` list.\n\nPaid per call with x402 v2 (USDC on Base). No account, no API key.","license":{"name":"LicenseRef-Proprietary","identifier":"LicenseRef-Proprietary"}},"servers":[{"url":"https://structura.x.c00l.site"}],"tags":[{"name":"extraction","description":"Schema-conformant structured extraction."},{"name":"tables","description":"Tabular extraction."},{"name":"classification","description":"Text classification."},{"name":"meta","description":"Free routes."}],"paths":{"/":{"get":{"tags":["meta"],"summary":"Landing page (free)","operationId":"landing","security":[],"responses":{"200":{"description":"HTML documentation.","content":{"text/html":{"schema":{"type":"string"}}}},"405":{"description":"Wrong method; use GET.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/health":{"get":{"tags":["meta"],"summary":"Liveness (free)","operationId":"health","security":[],"responses":{"200":{"description":"Service is up.","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"const":true},"service":{"type":"string"},"model":{"type":"string"}}},"example":{"ok":true,"service":"structura","model":"claude-sonnet-4-5"}}}},"404":{"description":"No such route.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/limits":{"get":{"tags":["meta"],"summary":"Machine-readable limits and prices (free)","operationId":"limits","security":[],"responses":{"200":{"description":"Limits.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"No such route.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/openapi.json":{"get":{"tags":["meta"],"summary":"This document (free)","operationId":"openapi","security":[],"responses":{"200":{"description":"OpenAPI 3.1.","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"No such route.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/validate":{"post":{"tags":["meta"],"summary":"Check a JSON Schema is usable (free)","operationId":"validateSchema","security":[],"description":"Free dry run. Confirms your schema is well-formed, bounded and evaluable, reports its size, depth and property count, and shows the nullable-widened version we would actually send the model. Use it while designing a schema so you never pay to discover a typo.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["schema"],"properties":{"schema":{"$ref":"#/components/schemas/JsonSchema"},"data":{"description":"Optional: also validate this value against the schema."}}},"example":{"schema":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]}}}}},"responses":{"200":{"description":"The schema is usable.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"stats":{"type":"object","properties":{"bytes":{"type":"integer"},"depth":{"type":"integer"},"nodes":{"type":"integer"},"properties":{"type":"integer"}}},"modelSchema":{"type":"object","description":"The nullable-widened, $ref-inlined schema the model is shown."},"warnings":{"type":"array","items":{"type":"string"}},"validation":{"type":"object","description":"Present only when `data` was supplied."}}}}}},"400":{"description":"The schema is not usable; `error.message` says exactly why.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/extract":{"post":{"tags":["extraction"],"summary":"Extract into your schema ($0.015)","operationId":"extract","description":"**$0.015 per call.**\n\nSource + JSON Schema in, conformant JSON out. The returned `data` has been\nvalidated against your schema before the response was built.\n\nAbsent values come back as `null`, so make fields nullable\n(`\"type\": [\"string\",\"null\"]`) unless you genuinely prefer the request to fail.\nIf a required, non-nullable field is not in the source, the response is a 502\nwith `code: \"schema_unsatisfiable\"`, the exact pointers, and no charge.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["source","schema"],"properties":{"source":{"$ref":"#/components/schemas/Source"},"schema":{"$ref":"#/components/schemas/JsonSchema"},"instructions":{"type":"string","maxLength":4000,"description":"Optional extra guidance: units, which of several entities on the page to prefer, date formats. Cannot override the no-fabrication rule or the schema."},"strict":{"type":"boolean","default":true,"description":"`false` opts out of the conformance guarantee: the best near-miss is returned with `valid:false` and the errors, and the call is charged. Useful while designing a schema."},"maxAttempts":{"type":"integer","minimum":1,"maximum":3,"default":3,"description":"Total model attempts, including repairs."},"maxChars":{"type":"integer","minimum":1000,"maximum":204800,"description":"Cap the extracted source text. Truncation happens at a semantic boundary and sets `source.truncated`."}}},"example":{"source":{"url":"https://example.com/product/widget-pro"},"schema":{"type":"object","properties":{"name":{"type":"string"},"price":{"type":["number","null"]},"currency":{"type":["string","null"]},"inStock":{"type":["boolean","null"]},"specs":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"value":{"type":"string"}},"required":["name","value"]}}},"required":["name","price","currency","inStock","specs"]},"strict":true}}}},"responses":{"200":{"description":"Extraction succeeded and `data` validates against your schema.","content":{"application/json":{"schema":{"type":"object","required":["data","valid","validationErrors","confidence","repairAttempts","usage"],"properties":{"data":{"description":"The extracted data. Validated against your schema."},"valid":{"type":"boolean","description":"True on every 2xx unless you passed `strict:false`."},"validationErrors":{"type":"array","items":{"type":"object","properties":{"instancePath":{"type":"string"},"schemaPath":{"type":"string"},"keyword":{"type":"string"},"message":{"type":"string"}}}},"confidence":{"$ref":"#/components/schemas/Confidence"},"confidenceOverall":{"type":["number","null"]},"absent":{"type":"array","items":{"type":"string"},"description":"JSON Pointers the model reports the source genuinely does not contain."},"notes":{"type":"string","description":"Ambiguity, assumed units, truncation, or a prompt-injection attempt seen in the source."},"repairAttempts":{"type":"integer","description":"0 means the first model output validated."},"attempts":{"type":"array","description":"One entry per model call, so you can see whether attempt 1 validated and why it did not.","items":{"type":"object","properties":{"attempt":{"type":"integer"},"valid":{"type":"boolean"},"errorCount":{"type":"integer"},"coercions":{"type":"integer"},"ms":{"type":"integer"},"keywords":{"type":"array","items":{"type":"string"}}}}},"coercions":{"type":"array","description":"Lossless fixes we applied locally (numeric string -> number, \"N/A\" -> null).","items":{"type":"object","properties":{"path":{"type":"string"},"from":{"type":"string"},"to":{"type":"string"}}}},"source":{"type":"object","properties":{"kind":{"type":"string"},"url":{"type":"string"},"finalUrl":{"type":"string"},"title":{"type":"string"},"chars":{"type":"integer"},"truncated":{"type":"boolean"}}},"usage":{"$ref":"#/components/schemas/Usage"},"paidBy":{"type":["string","null"]}}}}}},"400":{"description":"Malformed request or schema. Never charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Payment required — $0.015. The `PAYMENT-REQUIRED` response header carries the base64 x402 challenge. Any x402-aware client retries automatically.","headers":{"PAYMENT-REQUIRED":{"schema":{"type":"string"},"description":"Base64 x402 v2 challenge."}},"content":{"application/json":{"schema":{"type":"object"}}}},"403":{"description":"The URL was refused for SSRF safety. Rejected before the challenge; never charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Input over a size limit. Never charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"The result could not be made to conform to your schema within the attempt cap, or the extraction backend failed. Deliberately a 5xx: settlement is skipped, so you are not charged. `error.details.errors` names the exact JSON Pointers and `error.details.unsatisfiable` lists required, non-nullable fields the source did not contain.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"The extraction model is temporarily unavailable. Not charged; retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"A page fetch or model call timed out. Not charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/infer":{"post":{"tags":["extraction"],"summary":"Infer a schema and fill it ($0.02)","operationId":"infer","description":"**$0.02 per call.**\n\nFor \"just structure this for me\". No schema from you: we identify what the\ndocument is, design the schema a competent engineer would have written, and\nreturn it alongside the extracted data. The returned `data` is guaranteed to\nvalidate against the returned `schema` — otherwise the schema would not even\ndescribe the document it came from.\n\nKeep the schema and use it with `/extract` for every subsequent document of\nthe same kind: it is cheaper and the output is then stable across documents.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["source"],"properties":{"source":{"$ref":"#/components/schemas/Source"},"instructions":{"type":"string","maxLength":4000},"maxAttempts":{"type":"integer","minimum":1,"maximum":3},"maxChars":{"type":"integer","minimum":1000,"maximum":204800}}},"example":{"source":{"url":"https://example.com/2024/03/quarterly-results"}}}}},"responses":{"200":{"description":"A schema plus the document extracted into it.","content":{"application/json":{"schema":{"type":"object","required":["schema","data","valid","usage"],"properties":{"schema":{"type":"object","description":"JSON Schema draft 2020-12, with descriptions and nullable properties."},"data":{"description":"This document, validated against `schema`."},"documentKind":{"type":["string","null"]},"valid":{"const":true},"confidence":{"$ref":"#/components/schemas/Confidence"},"notes":{"type":"string"},"repairAttempts":{"type":"integer"},"attempts":{"type":"array","description":"One entry per model call, so you can see whether attempt 1 validated and why it did not.","items":{"type":"object","properties":{"attempt":{"type":"integer"},"valid":{"type":"boolean"},"errorCount":{"type":"integer"},"coercions":{"type":"integer"},"ms":{"type":"integer"},"keywords":{"type":"array","items":{"type":"string"}}}}},"source":{"type":"object"},"usage":{"$ref":"#/components/schemas/Usage"}}}}}},"400":{"description":"Malformed request or schema. Never charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Payment required — $0.02. The `PAYMENT-REQUIRED` response header carries the base64 x402 challenge. Any x402-aware client retries automatically.","headers":{"PAYMENT-REQUIRED":{"schema":{"type":"string"},"description":"Base64 x402 v2 challenge."}},"content":{"application/json":{"schema":{"type":"object"}}}},"403":{"description":"The URL was refused for SSRF safety. Rejected before the challenge; never charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Input over a size limit. Never charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"The result could not be made to conform to your schema within the attempt cap, or the extraction backend failed. Deliberately a 5xx: settlement is skipped, so you are not charged. `error.details.errors` names the exact JSON Pointers and `error.details.unsatisfiable` lists required, non-nullable fields the source did not contain.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"The extraction model is temporarily unavailable. Not charged; retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"A page fetch or model call timed out. Not charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/table":{"post":{"tags":["tables"],"summary":"Extract every table ($0.012)","operationId":"table","description":"**$0.012 per call.**\n\nAll tabular data in the document, as clean arrays of objects, with detected\nheaders, per-column types and units, and RFC 4180 CSV alongside the JSON.\n\nMerged cells are expanded locally with the real HTML placement rules before\nthe model sees anything, so `colspan`/`rowspan`, two-level headers and\nheader-in-first-column spec sheets come out right. Multi-table pages return\nevery table. Sources with no HTML tables fall back to scanning the text for\nfixed-width columns, Markdown pipe tables and CSV-ish blocks.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["source"],"properties":{"source":{"$ref":"#/components/schemas/Source"},"instructions":{"type":"string","maxLength":4000,"description":"e.g. \"only the pricing table\", \"keep footnote markers\", \"figures are in thousands\"."},"maxChars":{"type":"integer","minimum":1000,"maximum":204800}}},"example":{"source":{"url":"https://en.wikipedia.org/wiki/List_of_countries_by_GDP_(nominal)"}}}}},"responses":{"200":{"description":"Every table found.","content":{"application/json":{"schema":{"type":"object","required":["tables","tableCount","usage"],"properties":{"tables":{"type":"array","items":{"type":"object","properties":{"name":{"type":["string","null"]},"orientation":{"type":"string","enum":["row","column"],"description":"\"column\" means header-in-first-column, e.g. a key/value spec sheet."},"rowCount":{"type":"integer"},"columnCount":{"type":"integer"},"columns":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"type":{"type":"string","enum":["string","number","integer","boolean","date","mixed"],"description":"Re-derived locally from the values actually returned."},"modelType":{"type":"string","description":"Present only when the model's claimed type differed from the observed one."},"unit":{"type":["string","null"]},"nullCount":{"type":"integer"}}}},"rows":{"type":"array","items":{"type":"object","additionalProperties":true}},"csv":{"type":"string","description":"RFC 4180, CRLF, header row included."},"notes":{"type":"string"}}}},"tableCount":{"type":"integer"},"detected":{"type":"object","properties":{"htmlTables":{"type":"integer"},"mode":{"type":"string","enum":["html-grid","text-scan"]},"mergedCells":{"type":"boolean"},"skipped":{"type":"integer"}}},"notes":{"type":"string"},"source":{"type":"object"},"usage":{"$ref":"#/components/schemas/Usage"}}}}}},"400":{"description":"Malformed request or schema. Never charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Payment required — $0.012. The `PAYMENT-REQUIRED` response header carries the base64 x402 challenge. Any x402-aware client retries automatically.","headers":{"PAYMENT-REQUIRED":{"schema":{"type":"string"},"description":"Base64 x402 v2 challenge."}},"content":{"application/json":{"schema":{"type":"object"}}}},"403":{"description":"The URL was refused for SSRF safety. Rejected before the challenge; never charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Input over a size limit. Never charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"The result could not be made to conform to your schema within the attempt cap, or the extraction backend failed. Deliberately a 5xx: settlement is skipped, so you are not charged. `error.details.errors` names the exact JSON Pointers and `error.details.unsatisfiable` lists required, non-nullable fields the source did not contain.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"The extraction model is temporarily unavailable. Not charged; retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"A page fetch or model call timed out. Not charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/batch":{"post":{"tags":["extraction"],"summary":"One schema across many sources ($0.012 per item)","operationId":"batch","description":"**$0.012 per item**, up to 15 items. The total is computed from\nthe item count, so the 402 challenge you receive already states the exact\namount and your client can pay it in one hop.\n\nSources are fetched and processed concurrently (5 at a time).\nA per-item failure is reported inline as `{ ok: false, error }` and does not\nfail the call — but if *every* item fails the whole call returns 502 and is\nnot charged.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["sources","schema"],"properties":{"sources":{"type":"array","minItems":1,"maxItems":15,"items":{"$ref":"#/components/schemas/Source"}},"schema":{"$ref":"#/components/schemas/JsonSchema"},"instructions":{"type":"string","maxLength":4000},"strict":{"type":"boolean","default":true,"description":"Applies per item. With `strict:true` a non-conformant item fails as an item; the rest still return."},"maxAttempts":{"type":"integer","minimum":1,"maximum":3},"maxChars":{"type":"integer","minimum":1000,"maximum":204800}}},"example":{"sources":[{"url":"https://a.example/p/1"},{"url":"https://a.example/p/2"}],"schema":{"type":"object","properties":{"name":{"type":["string","null"]},"price":{"type":["number","null"]}},"required":["name","price"]}}}}},"responses":{"200":{"description":"Per-item results, in input order.","content":{"application/json":{"schema":{"type":"object","required":["count","succeeded","failed","results","usage"],"properties":{"count":{"type":"integer"},"succeeded":{"type":"integer"},"failed":{"type":"integer"},"results":{"type":"array","items":{"type":"object","properties":{"index":{"type":"integer"},"ok":{"type":"boolean"},"data":{},"valid":{"type":"boolean"},"confidence":{"$ref":"#/components/schemas/Confidence"},"absent":{"type":"array","items":{"type":"string"}},"notes":{"type":"string"},"repairAttempts":{"type":"integer"},"source":{"type":"object"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object"}}}}}},"notes":{"type":"string"},"usage":{"$ref":"#/components/schemas/Usage"}}}}}},"400":{"description":"Malformed request or schema. Never charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Payment required — $0.012 per item. The `PAYMENT-REQUIRED` response header carries the base64 x402 challenge. Any x402-aware client retries automatically.","headers":{"PAYMENT-REQUIRED":{"schema":{"type":"string"},"description":"Base64 x402 v2 challenge."}},"content":{"application/json":{"schema":{"type":"object"}}}},"403":{"description":"The URL was refused for SSRF safety. Rejected before the challenge; never charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Input over a size limit. Never charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"The result could not be made to conform to your schema within the attempt cap, or the extraction backend failed. Deliberately a 5xx: settlement is skipped, so you are not charged. `error.details.errors` names the exact JSON Pointers and `error.details.unsatisfiable` lists required, non-nullable fields the source did not contain.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"The extraction model is temporarily unavailable. Not charged; retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"A page fetch or model call timed out. Not charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/classify":{"post":{"tags":["classification"],"summary":"Classify text against your labels ($0.006)","operationId":"classify","description":"**$0.006 per call.**\n\nEvery label is scored 0-1, not just the winners, so you can threshold it\nyourself and see how close the call was (`margin`). The label set is baked\ninto the model's tool schema, so a label can never be skipped or invented.\n\n`multi:true` allows several labels, and allows none. `rubric` defines what\nyour labels mean and overrides the model's own reading of the names.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["text","labels"],"properties":{"text":{"type":"string","maxLength":400000,"description":"The text to classify."},"labels":{"type":"array","minItems":2,"maxItems":40,"items":{"type":"string","maxLength":80},"description":"Your label set. Unique, non-empty."},"multi":{"type":"boolean","default":false,"description":"Allow more than one label (and zero)."},"rubric":{"type":"string","maxLength":4000,"description":"What your labels mean. Authoritative."},"threshold":{"type":"number","minimum":0,"maximum":1,"default":0.5,"description":"Multi-label cutoff."}}},"example":{"text":"Charged twice for the same order and support has not replied in four days.","labels":["billing","bug","feature request","praise","churn risk"],"multi":true,"rubric":"churn risk: the customer signals they may leave or is visibly angry."}}}},"responses":{"200":{"description":"Scores for every label.","content":{"application/json":{"schema":{"type":"object","required":["labels","scores","rationale","usage"],"properties":{"labels":{"type":"array","items":{"type":"string"},"description":"The chosen labels, derived from `scores`."},"label":{"type":["string","null"],"description":"Single-label mode only."},"scores":{"type":"object","additionalProperties":{"type":"number","minimum":0,"maximum":1}},"ranked":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"score":{"type":"number"}}}},"top":{"type":["object","null"]},"margin":{"type":["number","null"],"description":"Gap between the top two scores; low means genuinely borderline."},"multi":{"type":"boolean"},"threshold":{"type":"number"},"rationale":{"type":"string"},"modelChoice":{"type":"array","items":{"type":"string"},"description":"Present only when the model's own pick disagreed with the score-derived one."},"usage":{"$ref":"#/components/schemas/Usage"}}}}}},"400":{"description":"Malformed request or schema. Never charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Payment required — $0.006. The `PAYMENT-REQUIRED` response header carries the base64 x402 challenge. Any x402-aware client retries automatically.","headers":{"PAYMENT-REQUIRED":{"schema":{"type":"string"},"description":"Base64 x402 v2 challenge."}},"content":{"application/json":{"schema":{"type":"object"}}}},"403":{"description":"The URL was refused for SSRF safety. Rejected before the challenge; never charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Input over a size limit. Never charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"The result could not be made to conform to your schema within the attempt cap, or the extraction backend failed. Deliberately a 5xx: settlement is skipped, so you are not charged. `error.details.errors` names the exact JSON Pointers and `error.details.unsatisfiable` lists required, non-nullable fields the source did not contain.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"The extraction model is temporarily unavailable. Not charged; retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"A page fetch or model call timed out. Not charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"schemas":{"Source":{"type":"object","description":"Exactly one of `url`, `html` or `text`. `url` is fetched for you (SSRF-guarded) and converted to Markdown; `html` is raw markup you already have; `text` is plain text, e.g. a PDF dumped to text.","properties":{"url":{"type":"string","format":"uri","description":"http(s) URL. Private, loopback, link-local and reserved addresses are refused."},"html":{"type":"string","description":"Raw HTML. Max 400000 characters."},"text":{"type":"string","description":"Plain text. Max 400000 characters."}},"additionalProperties":false,"minProperties":1,"maxProperties":1,"examples":[{"url":"https://example.com/product/widget-pro"},{"text":"Widget Pro — $19.99 — in stock"}]},"JsonSchema":{"type":"object","description":"A JSON Schema (draft 2020-12) describing the shape you want. Checked for well-formedness before the payment challenge, so a bad schema costs nothing. Max 65536 bytes, 14 levels deep, 250 properties. Only local `$ref`s (\"#/$defs/Name\"); remote schemas are never fetched. Make fields nullable (`\"type\": [\"string\",\"null\"]`) unless you would rather the request fail than receive a null.","additionalProperties":true},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":true}}}}},"Usage":{"type":"object","description":"Real model token usage for this request, summed across repair attempts.","properties":{"inputTokens":{"type":"integer"},"outputTokens":{"type":"integer"},"cacheReadTokens":{"type":"integer"},"cacheWriteTokens":{"type":"integer"},"modelCalls":{"type":"integer"},"model":{"type":"string"}}},"Confidence":{"type":"object","description":"RFC 6901 JSON Pointer (into `data`) -> 0-1 confidence. 1.0 = copied verbatim; 0.0 = set to null because the source did not contain it. Pointers that do not exist in `data` are dropped.","additionalProperties":{"type":"number","minimum":0,"maximum":1}}},"securitySchemes":{"x402":{"type":"apiKey","in":"header","name":"PAYMENT-SIGNATURE","description":"x402 v2 payment. There is no account and no API key: call the endpoint, receive a 402 whose `PAYMENT-REQUIRED` header carries the base64 challenge, sign an EIP-3009 USDC authorisation on Base for the stated amount, and resend with `PAYMENT-SIGNATURE`. Any x402-aware client (for example @x402/fetch) does all of this transparently. Failed requests are never settled."}}},"security":[{"x402":[]}],"x-x402":{"version":2,"scheme":"exact","network":"eip155:8453","networkName":"Base mainnet","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","assetName":"USDC","prices":{"/extract":"$0.015","/infer":"$0.02","/table":"$0.012","/batch":"$0.012","/classify":"$0.006"},"notes":"Prices are per call, except /batch which is per item. Failed requests are never settled: any 4xx or 5xx costs nothing."}}