> ## Documentation Index
> Fetch the complete documentation index at: https://docs.reducto.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Citations

> Link extracted values to their source locations in the document

export const CitationsDiffViewer = () => {
  const [citationsEnabled, setCitationsEnabled] = React.useState(true);
  const [numericalEnabled, setNumericalEnabled] = React.useState(true);
  const highlight = str => {
    let escaped = str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
    return escaped.replace(/"([^"\\]*(\\.[^"\\]*)*)"/g, '<span style="color: #a5d6ff">$&</span>').replace(/\b(\d+\.?\d*)\b/g, '<span style="color: #79c0ff">$1</span>').replace(/\b(true|false|null)\b/g, '<span style="color: #ff7b72">$1</span>').replace(/(\/\/.*)/g, '<span style="color: #8b949e">$1</span>');
  };
  const getExample = () => {
    if (citationsEnabled && numericalEnabled) {
      return {
        request: `{
  "settings": {
    "citations": {
      "enabled": true
      // numerical_confidence: true (default)
    }
  }
}`,
        response: `{
  "result": {
    "invoice_total": {
      "value": 1523.47,
      "citations": [{
        "type": "Table",
        "content": "Total: $1,523.47",
        "bbox": {"page": 1, "left": 0.60},
        "confidence": "high",
        "granular_confidence": {
          "extract_confidence": 0.91,
          "parse_confidence": 0.98
        }
      }]
    }
  }
}`
      };
    } else if (citationsEnabled) {
      return {
        request: `{
  "settings": {
    "citations": {
      "enabled": true,
      "numerical_confidence": false
    }
  }
}`,
        response: `{
  "result": {
    "invoice_total": {
      "value": 1523.47,
      "citations": [{
        "type": "Table",
        "content": "Total: $1,523.47",
        "bbox": {"page": 1, "left": 0.60},
        "confidence": "high"
      }]
    }
  }
}`
      };
    } else {
      return {
        request: `{
  "settings": {
    "citations": {
      "enabled": false
    }
  }
}`,
        response: `{
  "result": {
    "invoice_total": 1523.47,
    "vendor_name": "Acme Corp",
    "due_date": "2024-02-15"
  }
}`
      };
    }
  };
  const example = getExample();
  return <div className="not-prose my-6 rounded-xl border border-zinc-200 dark:border-zinc-800 overflow-hidden shadow-sm">
      {}
      <div className="px-4 py-3 bg-zinc-50 dark:bg-zinc-900 border-b border-zinc-200 dark:border-zinc-800 flex flex-wrap items-center gap-x-6 gap-y-2">
        {}
        <label className="inline-flex items-center gap-2 cursor-pointer select-none">
          <button type="button" onClick={() => setCitationsEnabled(!citationsEnabled)} className={`relative inline-flex h-5 w-9 shrink-0 rounded-full border-2 border-transparent transition-colors ${citationsEnabled ? 'bg-purple-600' : 'bg-zinc-300 dark:bg-zinc-600'}`}>
            <span className={`pointer-events-none inline-block h-4 w-4 transform rounded-full bg-white shadow-sm transition ${citationsEnabled ? 'translate-x-4' : 'translate-x-0'}`} />
          </button>
          <span className={`text-sm font-mono ${citationsEnabled ? 'text-zinc-900 dark:text-white' : 'text-zinc-500 dark:text-zinc-400'}`}>
            citations.enabled
          </span>
        </label>
        
        {}
        <label className={`inline-flex items-center gap-2 cursor-pointer select-none ${!citationsEnabled ? 'opacity-40 cursor-not-allowed' : ''}`}>
          <button type="button" disabled={!citationsEnabled} onClick={() => citationsEnabled && setNumericalEnabled(!numericalEnabled)} className={`relative inline-flex h-5 w-9 shrink-0 rounded-full border-2 border-transparent transition-colors ${numericalEnabled && citationsEnabled ? 'bg-purple-600' : 'bg-zinc-300 dark:bg-zinc-600'}`}>
            <span className={`pointer-events-none inline-block h-4 w-4 transform rounded-full bg-white shadow-sm transition ${numericalEnabled && citationsEnabled ? 'translate-x-4' : 'translate-x-0'}`} />
          </button>
          <span className={`text-sm font-mono ${numericalEnabled && citationsEnabled ? 'text-zinc-900 dark:text-white' : 'text-zinc-500 dark:text-zinc-400'}`}>
            numerical_confidence
          </span>
        </label>
      </div>

      {}
      <div className="grid md:grid-cols-2">
        {}
        <div className="bg-[#0d1117] border-b md:border-b-0 md:border-r border-zinc-800">
          <div className="px-4 py-2 border-b border-zinc-800 flex items-center gap-2">
            <div className="flex gap-1.5">
              <div className="w-3 h-3 rounded-full bg-[#ff5f56]" />
              <div className="w-3 h-3 rounded-full bg-[#ffbd2e]" />
              <div className="w-3 h-3 rounded-full bg-[#27c93f]" />
            </div>
            <span className="text-xs text-zinc-500 ml-2 font-medium">Request</span>
          </div>
          <div className="p-4">
            <pre className="text-[13px] leading-relaxed overflow-x-auto m-0 text-zinc-300" style={{
    fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace'
  }} dangerouslySetInnerHTML={{
    __html: highlight(example.request)
  }} />
          </div>
        </div>
        
        {}
        <div className="bg-[#0d1117]">
          <div className="px-4 py-2 border-b border-zinc-800 flex items-center gap-2">
            <div className="flex gap-1.5">
              <div className="w-3 h-3 rounded-full bg-[#ff5f56]" />
              <div className="w-3 h-3 rounded-full bg-[#ffbd2e]" />
              <div className="w-3 h-3 rounded-full bg-[#27c93f]" />
            </div>
            <span className="text-xs text-zinc-500 ml-2 font-medium">Response</span>
          </div>
          <div className="p-4">
            <pre className="text-[13px] leading-relaxed overflow-x-auto m-0 text-zinc-300" style={{
    fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace'
  }} dangerouslySetInnerHTML={{
    __html: highlight(example.response)
  }} />
          </div>
        </div>
      </div>
    </div>;
};

Citations tell you exactly where each extracted value came from in the document. When enabled, every field includes bounding box coordinates pointing to the source text.

This matters for:

* **Verification**: Confirm extractions are correct by checking source text
* **Compliance**: Maintain audit trails for regulated workflows
* **Debugging**: See where the model looked when values are wrong
* **User experience**: Let users click from extracted data to the original location

```python theme={null}
result = client.extract.run(
    input=upload,
    instructions={"schema": schema},
    settings={
        "citations": {"enabled": True}
    }
)
```

<CitationsDiffViewer />

## Response Structure

With citations enabled, each value becomes an object with `value` and `citations`:

```json theme={null}
{
  "result": {
    "invoice_total": {
      "value": 1575.00,
      "citations": [
        {
          "type": "Table",
          "content": "Total Due: $1,575.00",
          "bbox": {
            "left": 0.65,
            "top": 0.82,
            "width": 0.25,
            "height": 0.03,
            "page": 1,
            "original_page": 1
          },
          "confidence": "high",
          "granular_confidence": {
            "extract_confidence": 0.95,
            "parse_confidence": 0.91
          },
          "parentBlock": {
            "type": "Table",
            "content": "Subtotal: $1,500.00\nTax: $75.00\nTotal Due: $1,575.00",
            "bbox": {"left": 0.60, "top": 0.75, "width": 0.35, "height": 0.12, "page": 1}
          }
        }
      ]
    }
  }
}
```

**Fields:**

* `type`: Block type (`Text`, `Table`, `Key Value`, etc.)
* `content`: The source text
* `bbox`: Bounding box coordinates (normalized 0-1 for PDFs/images)
* `confidence`: `"high"` or `"low"`
* `granular_confidence`: Numeric scores (`extract_confidence`, `parse_confidence`) between 0-1
* `parentBlock`: The larger Parse block containing this citation, for context

## Working with Citations

**Accessing a scalar field:**

```python theme={null}
invoice_number = result.result["invoice_number"]
print(f"Value: {invoice_number.value}")

if invoice_number.citations:
    citation = invoice_number.citations[0]
    print(f"Found on page {citation.bbox.page}")
    print(f"Source text: {citation.content}")
```

**Looping through array items:**

```python theme={null}
for item in result.result["line_items"]:
    amount = item["amount"]
    print(f"${amount.value}")
    
    if amount.citations:
        print(f"  Found on page {amount.citations[0].bbox.page}")
```

## Bounding Box Coordinates

For PDFs and images, coordinates are normalized to \[0, 1] relative to page dimensions. `left: 0.5` means halfway across the page.

`page` is the page number in the processed result. `original_page` is the page number in the original document, which differs when you use page ranges.

To convert to pixels, multiply by page dimensions:

```python theme={null}
x_px = bbox["left"] * page_width_px
y_px = bbox["top"] * page_height_px
```

## Spreadsheet Citations

Excel and CSV files use cell coordinates instead of normalized positions:

* `left`: Column number (1-indexed, so 1 = A, 2 = B, 3 = C)
* `top`: Row number (1-indexed, so 1 = first row)
* `page`: Sheet number (1-indexed position of the sheet in the workbook)

A citation with `{"left": 3, "top": 15, "page": 2}` points to cell C15 on the second sheet.

All extraction modes use this convention, including `spreadsheet_agent` and `deep_extract`.

## Confidence Scores

Each citation includes a `confidence` field with a categorical value (`"high"` or `"low"`).

By default in v3, `numerical_confidence` is **enabled**, which adds `granular_confidence` with numeric 0-1 scores:

```json theme={null}
{
  "confidence": "high",
  "granular_confidence": {
    "extract_confidence": 0.95,
    "parse_confidence": 0.91
  }
}
```

* `extract_confidence`: How confident the LLM is about the extraction
* `parse_confidence`: How confident the OCR/parsing is about the underlying text

To disable numeric scores and only get categorical confidence:

```python theme={null}
settings={
    "citations": {
        "enabled": True,
        "numerical_confidence": False  # Only return "high"/"low"
    }
}
```

Low `parse_confidence` suggests OCR errors. Low `extract_confidence` suggests the model was uncertain about interpretation.

## Constraints

**Citations disable chunking:** The document is processed as a single unit to maintain precise coordinate mapping.

**Empty citations:** A field's `citations` array can be empty in two cases. The value was inferred rather than found directly in the document, or the value was found but Reducto could not reliably localize it to a source span. The second case is rare. In both cases the `value` is still returned correctly. Always check `if field.citations:` before accessing them. For an inferred value, re-running will not add a citation, so adjust the schema or field description if you need the value tied to source text. For the rare localization failure, re-running the extraction can recover the citation.

## Studio Visualization

Every response includes a `studio_link`. In Studio, citations are interactive:

* Click an extracted field to highlight its source in the document
* Click a highlight to jump to the corresponding field
