Extract¶
POST /v1/extract runs one extraction: you send a schema and an input,
the API returns typed values with confidence and an audit trail.
POST https://api.trusttyped.com/v1/extract
Authorization: Bearer tt_live_…
Content-Type: application/json
Request body¶
{
"model": "typed-small-1",
"schema": {
"merchant": {"type": "string", "instruction": "Store name"},
"total": {"type": "number", "integer": true, "instruction": "Final total"},
"paid": {"type": "bool", "instruction": "Was it paid?"}
},
"input": {
"text": "Sunrise Cafe. Fried Rice 25000, Iced Tea 8000. Total 33000. Paid in cash."
},
"system": "You extract receipt fields.",
"options": {"review_threshold": 0.5, "max_new_tokens": 32},
"metadata": {"ticket": "INV-1043"},
"stream": false
}
| Field | Required | Description |
|---|---|---|
schema |
yes | The fields to fill: a map of field name → field spec. Inline object, or a registry reference sch_…@<version> (registry is not enabled yet). |
input |
yes | Exactly one of text or image; messages may accompany text. See below. |
model |
no | Public model name; defaults to the project default. List them with GET /v1/models. |
system |
no | Shared instruction for every field, up to 20 000 characters. |
options |
no | review_threshold (0–1, default 0.5), max_new_tokens (1–512, default 32), thinking (bool), thinking_budget (1–4096). |
secrets |
no | Values for {{secret.name}} placeholders used by call fields. Never stored, logged, or returned. Max 50 entries. |
metadata |
no | Free-form client data, returned as-is. Do not put personal data here. |
stream |
no | When true, the result is streamed. See Streaming. |
Field specs (type, instruction, depends_on, extract, rules, call,
compute, …) are documented in the engine reference:
Structured outputs,
Field object,
Condition object,
Rule object.
Input¶
input must contain at least one of:
| Key | Description |
|---|---|
text |
Up to 500 000 characters. |
messages |
OpenAI-style chat turns (role: system/user/assistant), up to 200. May accompany text. |
image |
A base64 image (a data: prefix is allowed). One image per request. |
Response body¶
A successful call returns 200 with an Extraction object:
| Field | Description |
|---|---|
id |
The request id (req_…). Same value as the X-Request-Id response header. |
object |
Always "extraction". |
model |
The public model that produced the result. |
schema |
{id, version, hash} — id/version are null for an inline schema. |
result |
The typed values, one per schema field. |
fields |
Per field: confidence (0–1, or null for compute/call fields) and needs_review (bool). |
rejected |
Set ({field, value}) when a reject rule stopped the request. |
ended |
Set when an end rule stopped extraction early. |
provenance |
Audit trail: engine version, model revision, backend, and hashes of the input (inputs are stored only as hashes). |
usage |
Token and field counts — see below. |
timing |
queue_ms, inference_ms, total_ms. |
metadata |
Echoed unchanged when you sent it. |
usage¶
| Key | Description |
|---|---|
input_tokens |
Prompt tokens counted by the engine's tokenizer. null if the engine did not report them. |
output_tokens |
Tokens generated by the engine's decoder. null if not reported. |
fields |
Number of fields in result. |
images |
Number of images in the request (0 or 1). |
Response headers¶
| Header | Description |
|---|---|
X-Request-Id |
The request id. Echoes your X-Request-Id when it matches ^[A-Za-z0-9][A-Za-z0-9._:\-]{7,127}$, otherwise a generated req_…. |
X-RateLimit-Limit-Requests |
Request limit per minute for this key. |
X-RateLimit-Remaining-Requests |
Remaining requests in the current window. |
X-RateLimit-Reset-Requests |
Seconds until the window resets. |
Example with a client¶
import httpx
resp = httpx.post(
"https://api.trusttyped.com/v1/extract",
headers={"Authorization": "Bearer tt_live_…"},
json={
"schema": {"total": {"type": "number", "integer": True}, "paid": "bool"},
"input": {"text": "Total 33000. Paid in cash."},
},
timeout=120,
)
resp.raise_for_status()
data = resp.json()
print(data["result"], data["usage"])
const resp = await fetch("https://api.trusttyped.com/v1/extract", {
method: "POST",
headers: {
Authorization: "Bearer tt_live_…",
"Content-Type": "application/json",
},
body: JSON.stringify({
schema: { total: { type: "number", integer: true }, paid: "bool" },
input: { text: "Total 33000. Paid in cash." },
}),
});
const data = await resp.json();
console.log(data.result, data.usage);
Errors¶
400 invalid body/schema, 401 bad key, 403 not permitted, 409 idempotency
conflict, 413 body too large, 429 rate/concurrency limit, 500 server,
503 engine busy, 504 engine timeout. Full table: Errors.