---
title: "Elixir API Reference"
---
## Elixir API Reference v5.0.0-rc.3
### Functions
#### extract_bytes()
Extract content from a byte array.
This is the main entry point for in-memory extraction. It performs the following steps:
1. Validate MIME type
2. Handle legacy format conversion if needed
3. Select appropriate extractor from registry
4. Extract content
5. Run post-processing pipeline
**Returns:**
An `ExtractionResult` containing the extracted content and metadata.
**Errors:**
Returns `KreuzbergError.Validation` if MIME type is invalid.
Returns `KreuzbergError.UnsupportedFormat` if MIME type is not supported.
**Signature:**
```elixir
@spec extract_bytes(content, mime_type, config) :: {:ok, term()} | {:error, term()}
def extract_bytes(content, mime_type, config)
```
**Parameters:**
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `content` | `binary()` | Yes | The byte array to extract |
| `mime_type` | `String.t()` | Yes | MIME type of the content |
| `config` | `ExtractionConfig` | Yes | Extraction configuration |
**Returns:** `ExtractionResult`
**Errors:** Returns `{:error, reason}`
---
#### extract_file()
Extract content from a file.
This is the main entry point for file-based extraction. It performs the following steps:
1. Check cache for existing result (if caching enabled)
2. Detect or validate MIME type
3. Select appropriate extractor from registry
4. Extract content
5. Run post-processing pipeline
6. Store result in cache (if caching enabled)
**Returns:**
An `ExtractionResult` containing the extracted content and metadata.
**Errors:**
Returns `KreuzbergError.Io` if the file doesn't exist (NotFound) or for other file I/O errors.
Returns `KreuzbergError.UnsupportedFormat` if MIME type is not supported.
**Signature:**
```elixir
@spec extract_file(path, mime_type, config) :: {:ok, term()} | {:error, term()}
def extract_file(path, mime_type, config)
```
**Parameters:**
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `path` | `String.t()` | Yes | Path to the file to extract |
| `mime_type` | `String.t() \| nil` | No | Optional MIME type override. If None, will be auto-detected |
| `config` | `ExtractionConfig` | Yes | Extraction configuration |
**Returns:** `ExtractionResult`
**Errors:** Returns `{:error, reason}`
---
#### extract_file_sync()
Synchronous wrapper for `extract_file`.
This is a convenience function that blocks the current thread until extraction completes.
For async code, use `extract_file` directly.
Uses the global Tokio runtime for 100x+ performance improvement over creating
a new runtime per call. Always uses the global runtime to avoid nested runtime issues.
This function is only available with the `tokio-runtime` feature. For WASM targets,
use a truly synchronous extraction approach instead.
**Signature:**
```elixir
@spec extract_file_sync(path, mime_type, config) :: {:ok, term()} | {:error, term()}
def extract_file_sync(path, mime_type, config)
```
**Parameters:**
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `path` | `String.t()` | Yes | Path to the file |
| `mime_type` | `String.t() \| nil` | No | The mime type |
| `config` | `ExtractionConfig` | Yes | The configuration options |
**Returns:** `ExtractionResult`
**Errors:** Returns `{:error, reason}`
---
#### extract_bytes_sync()
Synchronous wrapper for `extract_bytes`.
Uses the global Tokio runtime for 100x+ performance improvement over creating
a new runtime per call.
With the `tokio-runtime` feature, this blocks the current thread using the global
Tokio runtime. Without it (WASM), this calls a truly synchronous implementation.
**Signature:**
```elixir
@spec extract_bytes_sync(content, mime_type, config) :: {:ok, term()} | {:error, term()}
def extract_bytes_sync(content, mime_type, config)
```
**Parameters:**
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `content` | `binary()` | Yes | The content to process |
| `mime_type` | `String.t()` | Yes | The mime type |
| `config` | `ExtractionConfig` | Yes | The configuration options |
**Returns:** `ExtractionResult`
**Errors:** Returns `{:error, reason}`
---
#### detect_mime_type_from_bytes()
Detect MIME type from raw file bytes.
Uses magic byte signatures to detect file type from content.
Falls back to `infer` crate for comprehensive detection.
For ZIP-based files, inspects contents to distinguish Office Open XML
formats (DOCX, XLSX, PPTX) from plain ZIP archives.
**Returns:**
The detected MIME type string.
**Errors:**
Returns `KreuzbergError.UnsupportedFormat` if MIME type cannot be determined.
**Signature:**
```elixir
@spec detect_mime_type_from_bytes(content) :: {:ok, term()} | {:error, term()}
def detect_mime_type_from_bytes(content)
```
**Parameters:**
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `content` | `binary()` | Yes | Raw file bytes |
**Returns:** `String.t()`
**Errors:** Returns `{:error, reason}`
---
#### get_extensions_for_mime()
Get file extensions for a given MIME type.
Returns all known file extensions that map to the specified MIME type.
**Returns:**
A vector of file extensions (without leading dot) for the MIME type.
**Signature:**
```elixir
@spec get_extensions_for_mime(mime_type) :: {:ok, term()} | {:error, term()}
def get_extensions_for_mime(mime_type)
```
**Parameters:**
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `mime_type` | `String.t()` | Yes | The MIME type to look up |
**Returns:** `list(String.t())`
**Errors:** Returns `{:error, reason}`
---
#### clear_embedding_backends()
Clear all embedding backends from the global registry.
Calls `shutdown()` on every registered backend, then empties the registry.
**Errors:**
- Any error returned by a backend's `shutdown()` method. The first error
encountered stops processing of remaining backends.
**Signature:**
```elixir
@spec clear_embedding_backends() :: {:ok, term()} | {:error, term()}
def clear_embedding_backends()
```
**Returns:** `:ok`
**Errors:** Returns `{:error, reason}`
---
#### list_embedding_backends()
List the names of all registered embedding backends.
Used by `kreuzberg-cli`, the api/mcp endpoints, and generated language
bindings.
**Signature:**
```elixir
@spec list_embedding_backends() :: {:ok, term()} | {:error, term()}
def list_embedding_backends()
```
**Returns:** `list(String.t())`
**Errors:** Returns `{:error, reason}`
---
#### list_document_extractors()
List names of all registered document extractors.
**Signature:**
```elixir
@spec list_document_extractors() :: {:ok, term()} | {:error, term()}
def list_document_extractors()
```
**Returns:** `list(String.t())`
**Errors:** Returns `{:error, reason}`
---
#### clear_document_extractors()
Clear all document extractors from the global registry.
Calls `shutdown()` on every registered extractor, then empties the registry.
**Errors:**
- Any error returned by an extractor's `shutdown()` method. The first error
encountered stops processing of remaining extractors.
**Signature:**
```elixir
@spec clear_document_extractors() :: {:ok, term()} | {:error, term()}
def clear_document_extractors()
```
**Returns:** `:ok`
**Errors:** Returns `{:error, reason}`
---
#### list_ocr_backends()
List all registered OCR backends.
Returns the names of all OCR backends currently registered in the global registry.
**Returns:**
A vector of OCR backend names.
**Signature:**
```elixir
@spec list_ocr_backends() :: {:ok, term()} | {:error, term()}
def list_ocr_backends()
```
**Returns:** `list(String.t())`
**Errors:** Returns `{:error, reason}`
---
#### clear_ocr_backends()
Clear all OCR backends from the global registry.
Removes all OCR backends and calls their `shutdown()` methods.
**Returns:**
- `Ok(())` if all backends were cleared successfully
- `Err(...)` if any shutdown method failed
**Signature:**
```elixir
@spec clear_ocr_backends() :: {:ok, term()} | {:error, term()}
def clear_ocr_backends()
```
**Returns:** `:ok`
**Errors:** Returns `{:error, reason}`
---
#### list_post_processors()
List all registered post-processor names.
Returns a vector of all post-processor names currently registered in the
global registry.
**Returns:**
- `Ok(Vec)` - Vector of post-processor names
- `Err(...)` if the registry lock is poisoned
**Signature:**
```elixir
@spec list_post_processors() :: {:ok, term()} | {:error, term()}
def list_post_processors()
```
**Returns:** `list(String.t())`
**Errors:** Returns `{:error, reason}`
---
#### clear_post_processors()
Remove all registered post-processors.
**Signature:**
```elixir
@spec clear_post_processors() :: {:ok, term()} | {:error, term()}
def clear_post_processors()
```
**Returns:** `:ok`
**Errors:** Returns `{:error, reason}`
---
#### list_renderers()
List names of all registered renderers.
**Errors:**
Returns an error if the registry lock is poisoned.
**Signature:**
```elixir
@spec list_renderers() :: {:ok, term()} | {:error, term()}
def list_renderers()
```
**Returns:** `list(String.t())`
**Errors:** Returns `{:error, reason}`
---
#### clear_renderers()
Clear all renderers from the global registry.
Removes every renderer, including the built-in defaults (markdown, html,
djot, plain). After calling this no renderers are registered; re-register
as needed.
**Errors:**
Returns an error if the registry lock is poisoned.
**Signature:**
```elixir
@spec clear_renderers() :: {:ok, term()} | {:error, term()}
def clear_renderers()
```
**Returns:** `:ok`
**Errors:** Returns `{:error, reason}`
---
#### list_validators()
List names of all registered validators.
**Signature:**
```elixir
@spec list_validators() :: {:ok, term()} | {:error, term()}
def list_validators()
```
**Returns:** `list(String.t())`
**Errors:** Returns `{:error, reason}`
---
#### clear_validators()
Remove all registered validators.
**Signature:**
```elixir
@spec clear_validators() :: {:ok, term()} | {:error, term()}
def clear_validators()
```
**Returns:** `:ok`
**Errors:** Returns `{:error, reason}`
---
#### compare()
Compare two extraction results and return a structured diff.
The comparison is purely structural — no I/O, no side effects. All fields
of `ExtractionDiff` are populated according to the provided `DiffOptions`.
**Signature:**
```elixir
@spec compare(a, b, opts) :: {:ok, term()} | {:error, term()}
def compare(a, b, opts)
```
**Parameters:**
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `a` | `ExtractionResult` | Yes | The extraction result |
| `b` | `ExtractionResult` | Yes | The extraction result |
| `opts` | `DiffOptions` | Yes | The options to use |
**Returns:** `ExtractionDiff`
---
#### embed_texts_async()
Generate embeddings asynchronously for a list of text strings.
This is the async counterpart to `embed_texts`. It offloads the blocking
ONNX inference work to a dedicated blocking thread pool via Tokio's
`spawn_blocking`, keeping the async executor free.
Returns one embedding vector per input text in the same order.
**Errors:**
- `KreuzbergError.MissingDependency` if ONNX Runtime is not installed
- `KreuzbergError.Embedding` if the preset name is unknown, model download fails,
or the blocking inference task panics
**Signature:**
```elixir
@spec embed_texts_async(texts, config) :: {:ok, term()} | {:error, term()}
def embed_texts_async(texts, config)
```
**Parameters:**
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `texts` | `list(String.t())` | Yes | Vec of strings to embed (owned, sent to blocking thread) |
| `config` | `EmbeddingConfig` | Yes | Embedding configuration specifying model, batch size, and normalization |
**Returns:** `list(list(float()))`
**Errors:** Returns `{:error, reason}`
---
#### render_pdf_page_to_png()
Render a single PDF page to PNG bytes.
Returns raw PNG-encoded bytes for the specified page at the given DPI.
Uses pdf_oxide with tiny-skia for pure-Rust rendering.
**Errors:**
Returns `KreuzbergError.Parsing` if the PDF cannot be opened, authenticated,
or rendered, or if `page_index` is out of range.
**Signature:**
```elixir
@spec render_pdf_page_to_png(pdf_bytes, page_index, dpi, password) :: {:ok, term()} | {:error, term()}
def render_pdf_page_to_png(pdf_bytes, page_index, dpi, password)
```
**Parameters:**
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `pdf_bytes` | `binary()` | Yes | Raw PDF file bytes |
| `page_index` | `integer()` | Yes | Zero-based page index |
| `dpi` | `integer() \| nil` | No | Resolution in dots per inch (default: 150) |
| `password` | `String.t() \| nil` | No | Optional password for encrypted PDFs |
**Returns:** `binary()`
**Errors:** Returns `{:error, reason}`
---
#### detect_mime_type()
Detect the MIME type of a file at the given path.
Uses the file extension and optionally the file content to determine the MIME type.
Set `check_exists` to `true` to verify the file exists before detection.
**Signature:**
```elixir
@spec detect_mime_type(path, check_exists) :: {:ok, term()} | {:error, term()}
def detect_mime_type(path, check_exists)
```
**Parameters:**
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `path` | `String.t()` | Yes | Path to the file |
| `check_exists` | `boolean()` | Yes | The check exists |
**Returns:** `String.t()`
**Errors:** Returns `{:error, reason}`
---
#### embed_texts()
Embed a list of texts using the configured embedding model.
Returns a 2D vector where each inner vector is the embedding for the corresponding text.
**Signature:**
```elixir
@spec embed_texts(texts, config) :: {:ok, term()} | {:error, term()}
def embed_texts(texts, config)
```
**Parameters:**
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `texts` | `list(String.t())` | Yes | The texts |
| `config` | `EmbeddingConfig` | Yes | The configuration options |
**Returns:** `list(list(float()))`
**Errors:** Returns `{:error, reason}`
---
#### get_embedding_preset()
Get an embedding preset by name.
Returns `nil` if no preset with the given name exists. Returns an owned
clone so the value is safe to pass across FFI boundaries.
**Signature:**
```elixir
@spec get_embedding_preset(name) :: {:ok, term()} | {:error, term()}
def get_embedding_preset(name)
```
**Parameters:**
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `name` | `String.t()` | Yes | The name |
**Returns:** `EmbeddingPreset | nil`
---
#### list_embedding_presets()
List the names of all available embedding presets.
Returns owned `String`s so the values are safe to pass across FFI boundaries.
**Signature:**
```elixir
@spec list_embedding_presets() :: {:ok, term()} | {:error, term()}
def list_embedding_presets()
```
**Returns:** `list(String.t())`
---
### Types
#### AccelerationConfig
Hardware acceleration configuration for ONNX Runtime models.
Controls which execution provider (CPU, CoreML, CUDA, TensorRT) is used
for inference in layout detection and embedding generation.
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `provider` | `ExecutionProviderType` | `:auto` | Execution provider to use for ONNX inference. |
| `device_id` | `integer()` | — | GPU device ID (for CUDA/TensorRT). Ignored for CPU/CoreML/Auto. |
---
#### ArchiveEntry
A single file extracted from an archive.
When archives (ZIP, TAR, 7Z, GZIP) are extracted with recursive extraction
enabled, each processable file produces its own full `ExtractionResult`.
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `path` | `String.t()` | — | Archive-relative file path (e.g. "folder/document.pdf"). |
| `mime_type` | `String.t()` | — | Detected MIME type of the file. |
| `result` | `ExtractionResult` | — | Full extraction result for this file. |
---
#### ArchiveMetadata
Archive (ZIP/TAR/7Z) metadata.
Extracted from compressed archive files containing file lists and size information.
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `format` | `String.t()` | — | Archive format ("ZIP", "TAR", "7Z", etc.) |
| `file_count` | `integer()` | — | Total number of files in the archive |
| `file_list` | `list(String.t())` | `[]` | List of file paths within the archive |
| `total_size` | `integer()` | — | Total uncompressed size in bytes |
| `compressed_size` | `integer() \| nil` | `nil` | Compressed size in bytes (if available) |
---
#### BBox
Bounding box in original image coordinates (x1, y1) top-left, (x2, y2) bottom-right.
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `x1` | `float()` | — | X1 |
| `y1` | `float()` | — | Y1 |
| `x2` | `float()` | — | X2 |
| `y2` | `float()` | — | Y2 |
---
#### BatchBytesItem
Batch item for byte array extraction.
Used with `batch_extract_bytes` and `batch_extract_bytes_sync`
to represent a single item in a batch extraction job.
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `content` | `binary()` | — | The content bytes to extract from |
| `mime_type` | `String.t()` | — | MIME type of the content (e.g., "application/pdf", "text/html") |
| `config` | `FileExtractionConfig \| nil` | `nil` | Per-item configuration overrides (None uses batch-level defaults) |
---
#### BatchFileItem
Batch item for file extraction.
Used with `batch_extract_files` and `batch_extract_files_sync`
to represent a single file in a batch extraction job.
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `path` | `String.t()` | — | Path to the file to extract from |
| `config` | `FileExtractionConfig \| nil` | `nil` | Per-file configuration overrides (None uses batch-level defaults) |
---
#### BibtexMetadata
BibTeX bibliography metadata.
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `entry_count` | `integer()` | — | Number of entries in the bibliography. |
| `citation_keys` | `list(String.t())` | `[]` | Citation keys |
| `authors` | `list(String.t())` | `[]` | Authors |
| `year_range` | `YearRange \| nil` | `nil` | Year range (year range) |
| `entry_types` | `map() \| nil` | `%{}` | Entry types |
---
#### BoundingBox
Bounding box coordinates for element positioning.
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `x0` | `float()` | — | Left x-coordinate |
| `y0` | `float()` | — | Bottom y-coordinate |
| `x1` | `float()` | — | Right x-coordinate |
| `y1` | `float()` | — | Top y-coordinate |
---
#### CacheStats
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `total_files` | `integer()` | — | Total files |
| `total_size_mb` | `float()` | — | Total size mb |
| `available_space_mb` | `float()` | — | Available space mb |
| `oldest_file_age_days` | `float()` | — | Oldest file age days |
| `newest_file_age_days` | `float()` | — | Newest file age days |
---
#### CellChange
A single changed cell within a table.
Defined here (rather than only in `crate.diff`) so `RevisionDelta` can
reference it unconditionally, without requiring the `diff` Cargo feature.
`crate.diff` re-exports this type verbatim.
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `row` | `integer()` | — | Zero-based row index. |
| `col` | `integer()` | — | Zero-based column index. |
| `from` | `String.t()` | — | Value before the change. |
| `to` | `String.t()` | — | Value after the change. |
---
#### Chunk
A text chunk with optional embedding and metadata.
Chunks are created when chunking is enabled in `ExtractionConfig`. Each chunk
contains the text content, optional embedding vector (if embedding generation
is configured), and metadata about its position in the document.
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `content` | `String.t()` | — | The text content of this chunk. |
| `chunk_type` | `ChunkType` | `/* serde(default) */` | Semantic structural classification of this chunk. Assigned by the heuristic classifier based on content patterns and heading context. Defaults to `ChunkType.Unknown` when no rule matches. |
| `embedding` | `list(float()) \| nil` | `nil` | Optional embedding vector for this chunk. Only populated when `EmbeddingConfig` is provided in chunking configuration. The dimensionality depends on the chosen embedding model. |
| `metadata` | `ChunkMetadata` | — | Metadata about this chunk's position and properties. |
---
#### ChunkMetadata
Metadata about a chunk's position in the original document.
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `byte_start` | `integer()` | — | Byte offset where this chunk starts in the original text (UTF-8 valid boundary). |
| `byte_end` | `integer()` | — | Byte offset where this chunk ends in the original text (UTF-8 valid boundary). |
| `token_count` | `integer() \| nil` | `nil` | Number of tokens in this chunk (if available). This is calculated by the embedding model's tokenizer if embeddings are enabled. |
| `chunk_index` | `integer()` | — | Zero-based index of this chunk in the document. |
| `total_chunks` | `integer()` | — | Total number of chunks in the document. |
| `first_page` | `integer() \| nil` | `nil` | First page number this chunk spans (1-indexed). Only populated when page tracking is enabled in extraction configuration. |
| `last_page` | `integer() \| nil` | `nil` | Last page number this chunk spans (1-indexed, equal to first_page for single-page chunks). Only populated when page tracking is enabled in extraction configuration. |
| `heading_context` | `HeadingContext \| nil` | `/* serde(default) */` | Heading context when using Markdown chunker. Contains the heading hierarchy this chunk falls under. Only populated when `ChunkerType.Markdown` is used. |
| `image_indices` | `list(integer())` | `/* serde(default) */` | Indices into `ExtractionResult.images` for images on pages covered by this chunk. Contains zero-based indices into the top-level `images` collection for every image whose `page_number` falls within `[first_page, last_page]`. Empty when image extraction is disabled or the chunk spans no pages with images. |
---
#### ChunkingConfig
Chunking configuration.
Configures text chunking for document content, including chunk size,
overlap, trimming behavior, and optional embeddings.
Use `..the default constructor` when constructing to allow for future field additions:
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `max_characters` | `integer()` | `1000` | Maximum size per chunk (in units determined by `sizing`). When `sizing` is `Characters` (default), this is the max character count. When using token-based sizing, this is the max token count. Default: 1000 |
| `overlap` | `integer()` | `200` | Overlap between chunks (in units determined by `sizing`). Default: 200 |
| `trim` | `boolean()` | `true` | Whether to trim whitespace from chunk boundaries. Default: true |
| `chunker_type` | `ChunkerType` | `:text` | Type of chunker to use (Text or Markdown). Default: Text |
| `embedding` | `EmbeddingConfig \| nil` | `nil` | Optional embedding configuration for chunk embeddings. |
| `preset` | `String.t() \| nil` | `nil` | Use a preset configuration (overrides individual settings if provided). |
| `sizing` | `ChunkSizing` | `:characters` | How to measure chunk size. Default: `Characters` (Unicode character count). Enable `chunking-tiktoken` or `chunking-tokenizers` features for token-based sizing. |
| `prepend_heading_context` | `boolean()` | `false` | When `true` and `chunker_type` is `Markdown`, prepend the heading hierarchy path (e.g. `"# Title > ## Section\n\n"`) to each chunk's content string. This is useful for RAG pipelines where each chunk needs self-contained context about its position in the document structure. Default: `false` |
| `topic_threshold` | `float() \| nil` | `nil` | Optional cosine similarity threshold for semantic topic boundary detection. Only used when `chunker_type` is `Semantic` and an `EmbeddingConfig` is provided. You almost never need to set this. When omitted, defaults to `0.75` which works well for most documents. Lower values detect more topic boundaries (more, smaller chunks); higher values detect fewer. Range: `0.0..=1.0`. |
### Functions
#### default()
**Signature:**
```elixir
def default()
```
---
#### CitationMetadata
Citation file metadata (RIS, PubMed, EndNote).
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `citation_count` | `integer()` | — | Number of citations |
| `format` | `String.t() \| nil` | `nil` | Format |
| `authors` | `list(String.t())` | `[]` | Authors |
| `year_range` | `YearRange \| nil` | `nil` | Year range (year range) |
| `dois` | `list(String.t())` | `[]` | Dois |
| `keywords` | `list(String.t())` | `[]` | Keywords |
---
#### ContentFilterConfig
Cross-extractor content filtering configuration.
Controls whether "furniture" content (headers, footers, page numbers,
watermarks, repeating text) is included in or stripped from extraction
results. Applies across all extractors (PDF, DOCX, RTF, ODT, HTML, etc.)
with format-specific implementation.
When `nil` on `ExtractionConfig`, each extractor uses its current
default behavior unchanged.
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `include_headers` | `boolean()` | `false` | Include running headers in extraction output. - PDF: Disables top-margin furniture stripping and prevents the layout model from treating `PageHeader`-classified regions as furniture. - DOCX: Includes document headers in text output. - RTF/ODT: Headers already included; this is a no-op when true. - HTML/EPUB: Keeps `` element content. Default: `false` (headers are stripped or excluded). |
| `include_footers` | `boolean()` | `false` | Include running footers in extraction output. - PDF: Disables bottom-margin furniture stripping and prevents the layout model from treating `PageFooter`-classified regions as furniture. - DOCX: Includes document footers in text output. - RTF/ODT: Footers already included; this is a no-op when true. - HTML/EPUB: Keeps `