# 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.

- Canonical: https://www.datalab.to/blog/turbo-extraction
- Published: 2026-06-11
- Authors: Vik Paruchuri

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.

| Mode      | Field accuracy | Full-doc accuracy | Correct nulls | Median latency\* | Output                          | Price /1k pages |
| --------- | -------------- | ----------------- | ------------- | ---------------- | ------------------------------- | --------------- |
| **Turbo** | 89.8%          | 23.6%             | 83.9%         | **~12s**         | JSON                            | **$6**          |
| Fast      | 91.6%          | 25.3%             | 85.8%         | ~29s             | JSON + citations                | $10             |
| Balanced  | 95.9%          | 44.4%             | 95.4%         | ~54s             | JSON + 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](/images/blog/turbo-extraction/rfc_invoice.png)

Define the schema you want back:

```json
{
  "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`:

```bash
curl -X POST https://www.datalab.to/api/v1/extract \
  -H "X-Api-Key: $DATALAB_API_KEY" \
  -F "file=@invoice.pdf" \
  -F "extraction_mode=turbo" \
  -F "page_schema=$(cat schema.json)"
```

Or from Python:

```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:

```json
{
  "vendor": {
    "name": "Wireless, Inc.",
    "email": "Accounting@rfcwireless.com",
    "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](https://www.datalab.to) and the playground. Send a file, get JSON.
