BLOG · PRODUCT UPDATES

By Vik Paruchuri 3 min

Turbo Mode: Structured Extraction At 12s/doc

Turbo mode for the Datalab extraction API: structured JSON from any document at a median of ~12 seconds per document.

Today we’re launching turbo mode for the Datalab extraction API: structured JSON from any document at a median of ~12 seconds per document, for $6 per 1,000 pages.

Turbo is built for one job: when you need to turn a document into clean JSON, aligned to a schema, quickly. This matters for realtime user-in-the-loop flows, or for batch jobs that are less accuracy sensitive.

Lift model for extraction

Turbo is powered by lift, our new extraction model, which fills your JSON schema directly, with no external LLM calls. Here we compare it to our fast and balanced modes.

ModeField accuracyFull-doc accuracyCorrect nullsMedian latency*OutputPrice /1k pages
Turbo89.8%23.6%83.9%~12sJSON$6
Fast91.6%25.3%85.8%~29sJSON + citations$10
Balanced95.9%44.4%95.4%~54sJSON + citations + verification$35 + fees**

* End-to-end per document, including document parsing where the mode requires it. Measured at 8 concurrent requests on our 225-document benchmark — ~6,600 pages of invoices, bank statements, medical guidelines, legal filings.

** Balanced adds a compute surcharge on complex schemas — none for most documents, typically $0–$2 when it applies.

See it work

Here’s a real one-page invoice — a scanned services invoice with a line-item table, serial numbers, and the usual layout noise.

The invoice

Define the schema you want back:

{
  "type": "object",
  "properties": {
    "vendor": {
      "type": "object",
      "properties": {
        "name": { "type": "string" },
        "email": { "type": "string" },
        "phone": { "type": "string" }
      }
    },
    "invoice_number": { "type": "string" },
    "invoice_date": { "type": "string" },
    "due_date": { "type": "string" },
    "po_number": { "type": "string" },
    "payment_terms": { "type": "string" },
    "line_items": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "description": { "type": "string" },
          "quantity": { "type": "number" },
          "unit_price": { "type": "number" },
          "amount": { "type": "number" }
        }
      }
    },
    "subtotal": { "type": "number" },
    "tax": { "type": "number" },
    "total": { "type": "number" },
    "shipping_cost": {
      "type": "number",
      "description": "Shipping charge, if any"
    }
  }
}

Send the file with extraction_mode=turbo:

curl -X POST https://www.datalab.to/api/v1/extract 
  -H "X-Api-Key: $DATALAB_API_KEY" 
  -F "[email protected]" 
  -F "extraction_mode=turbo" 
  -F "page_schema=$(cat schema.json)"

Or from Python:

import json
import time

import requests

API_KEY = "YOUR_API_KEY"
headers = {"X-Api-Key": API_KEY}

with open("invoice.pdf", "rb") as f:
    submit = requests.post(
        "https://www.datalab.to/api/v1/extract",
        headers=headers,
        files={"file": ("invoice.pdf", f, "application/pdf")},
        data={
            "extraction_mode": "turbo",
            "page_schema": json.dumps(schema),
        },
    ).json()

while True:
    result = requests.get(submit["request_check_url"], headers=headers).json()
    if result["status"] == "complete":
        break
    time.sleep(1)

extraction = json.loads(result["extraction_schema_json"])

And get back:

{
  "vendor": {
    "name": "Wireless, Inc.",
    "email": "[email protected]",
    "phone": "+1 9252441"
  },
  "invoice_number": "32611",
  "invoice_date": "03/01/2024",
  "due_date": "03/31/2024",
  "po_number": "USPO5754",
  "payment_terms": "Net 30",
  "line_items": [
    {
      "description": "TRBOTALK WIDE-AREA CONNECT+ REPEATER SERVICE FOR 19 UNITS @ $22/MO SL7550e SN: 682TUP2382, 682TUP2407, 682TST1748 ...",
      "quantity": 19,
      "unit_price": 22.0,
      "amount": 418.0
    },
    {
      "description": "iTALK AIRTIME FOR FIVE UNITS",
      "quantity": 5,
      "unit_price": 45.0,
      "amount": 225.0
    }
  ],
  "subtotal": 643.0,
  "tax": 0.0,
  "total": 643.0,
  "shipping_cost": null
}

A few things worth noticing:

  • The table comes back as data. Quantities, rates, and amounts land in line_items as numbers (19 × $22.00 = $418.00) — including the serial numbers buried in the description rows.
  • The nulls are real nulls. There’s no shipping charge anywhere on the invoice, so shipping_cost comes back null instead of a plausible-looking wrong value. The schema grammar explicitly allows null for every field, so the model is never forced to invent.
  • No templates, no field mapping. The schema is the whole configuration — change it and the same document yields a different extraction.

What you trade

Turbo gives up two things relative to fast and balanced:

  • No citations. Fast and balanced return block-level citations pointing each value back to its location in the document. Turbo returns the JSON only.
  • A couple of points of accuracy. 89.8% field accuracy vs 91.6% (fast) and 95.9% (balanced).

If you need an audit trail, or you’re extracting from documents where every field matters, use balanced. If you’re processing a million pages of fairly regular documents and want them quickly, turbo is the right tool.

Turbo mode is available now in the API and the playground. Send a file, get JSON.

START

Get started in minutes.

Free tier. No credit card. SOC 2 Type II.