Skip to main content
Loaders are responsible for reading files from your disk or cloud storage and converting them into plain text that Cognee can process. When you run remember(), Cognee automatically selects the most appropriate loader for each file based on its extension and content type.

Loader Selection

Cognee uses a priority system to decide which loader to use. It tries to match a loader in the following order:
  1. CodeLoader: For source-code files (.py, .ts, .go, .rs, etc.). It sits ahead of TextLoader because code content-sniffs as plain text, so TextLoader would otherwise claim it first.
  2. TextLoader: For plain text files (.txt, .md, .json, .xml, etc.).
  3. PyPdfLoader: For PDF files (requires pypdf).
  4. ImageLoader: For images (uses vision models to transcribe content, with an optional local OCR pass).
  5. AudioLoader: For audio files (uses transcription models).
  6. VideoLoader: For video files (transcribes the audio track with inline [HH:MM:SS] timestamps).
  7. DltCsvLoader: For CSV files, when cognee[dlt] is installed (routes rows through dlt structured ingestion instead of text).
  8. CsvLoader: For CSV files (converts rows to text).
  9. UnstructuredLoader: For complex formats like .docx, .pptx, .epub (requires unstructured).
  10. AdvancedPdfLoader: For layout-aware PDF extraction (requires unstructured).
  11. DoclingLoader: If no other loader can ingest the file type, Docling is used for conversion (if the type is supported).
If you want to force a specific loader or provide custom configuration, you can use the preferred_loaders parameter in remember().

Available Loaders

Core Loaders

These are available by default in every Cognee installation:
  • CodeLoader: Claims source-code files by file-name extension and stores them verbatim under their original extension. Files it claims take the deterministic code graph pipeline during cognify() instead of LLM-based extraction. See the “Code Loader” accordion below.
  • TextLoader: Reads text files with UTF-8 encoding.
  • CsvLoader: Reads CSV files and converts each row into a structured text format (Row N: key: value).
  • ImageLoader: Uses an LLM vision model to transcribe the image content. By default the transcription uses an extraction-oriented prompt that asks for entities, relationships, verbatim text, and structured content (tables, charts, diagrams) rather than a short caption. An optional local OCR pass can be enabled to append recognized text to the transcription; it requires pip install cognee[rapidocr]. See the “Image transcription and OCR” accordion below.
  • AudioLoader: Uses an audio transcription API to transcribe audio files. This depends on your configured LLM provider supporting transcription endpoints; see LLM Providers for provider-specific caveats.
  • VideoLoader: Transcribes a video’s audio track into text with inline [HH:MM:SS] segment timestamps, then feeds it through the normal text pipeline. .mp4 and .webm do not require ffmpeg; other containers do (see the VideoLoader usage accordion below).

External Loaders

These require additional dependencies to be installed:
  • PyPdfLoader: Extracts text from PDFs page by page using the pypdf library, preserving page boundaries with Page N: markers in the extracted text. Requires pip install cognee[docs] (or pip install pypdf).
  • AdvancedPdfLoader: Layout-aware PDF extraction using the unstructured library. Extracts text, tables (as HTML), and image placeholders per page. Falls back to PyPdfLoader automatically if extraction fails. Requires pip install cognee[docs], plus poppler and tesseract installed on the system.
  • UnstructuredLoader: Handles many office and document formats (.docx, .xlsx, .pptx, .odt, .rtf, .eml, .epub, .html, and more) via unstructured’s auto-partition. Requires pip install cognee[docs].
  • BeautifulSoupLoader: Extracts text from HTML files using BeautifulSoup. Applies CSS selector rules to pull structured content from specific tags. Requires pip install cognee[scraping].
  • DoclingLoader: Catch-all fallback that converts a wide range of document formats (PDF, DOCX, XLSX, PPTX, HTML, Markdown, and more) to plain text via Docling. Supported extensions are discovered dynamically from Docling’s FormatToExtensions map. Requires pip install cognee[docling].
  • DltCsvLoader: Ingests .csv files through the dlt structured path instead of flattening them to text — the rows are loaded into a dlt staging database and the loader emits one manifest per CSV file, which cognify turns into row nodes deterministically from the schema, with no LLM extraction. It registers above CsvLoader in the priority order, so once the extra is installed every CSV takes this route by default. Requires pip install 'cognee[dlt]'.

Supported File Extensions

Cognee selects loaders based on file type. The table below shows the supported extensions and their default loaders. Extensions are matched case-insensitively for the text-only formats that carry no content signature — .txt, .csv, .md, .json, .xml, .yaml, and .yml — so REPORT.CSV and report.csv are detected as the same type and get the same loader. .log files are case-insensitive too: an unrecognized extension like .LOG falls back to plain text, which lands on the same TextLoader. Formats identified from their content, such as PDFs, images, audio, and video, were never case-sensitive.
Note: Files with extensions not in this table cannot be remembered by default. Use a custom loader to handle additional formats. When no registered loader can handle a file, remember() raises a ValueError that names the file’s extension and lists the currently supported extensions. For office and document formats that ship only via an optional loader (for example .pptx, .docx, .xlsx, .html, .epub), install cognee[docling] for Docling or cognee[docs] for Unstructured-backed loaders, then retry.

Usage

You can override the default loader selection by specifying preferred_loaders. This is useful when you want to pass specific configuration options to a loader.
Opting out of the dlt CSV route. When cognee[dlt] is installed, DltCsvLoader outranks CsvLoader for every .csv file. Name csv_loader explicitly to restore text flattening for a single call:
The same channel carries per-call dlt options — primary_key, write_disposition, max_rows_per_table, and column_value_columns — to DltCsvLoader:
CodeLoader is a core loader that claims source-code files so they take Cognee’s deterministic code graph pipeline instead of the LLM extraction path.
Matched by extension only. Content sniffing cannot identify a programming language — it reports code as plain text — so CodeLoader looks at the file-name extension and ignores the detected MIME type entirely. It claims these 31 extensions:.c, .cc, .cpp, .cs, .cxx, .dart, .fs, .go, .h, .hcl, .hh, .hpp, .java, .js, .jsx, .kt, .kts, .php, .proto, .py, .rake, .rb, .rs, .scala, .svelte, .swift, .tf, .ts, .tsx, .vb, .vueExtensions that double as generic config or markup are deliberately not claimed — .yaml and .yml (Ansible), .json (OpenAPI), and template formats such as .xaml, .razor, .cshtml, and .hbs. Claiming those would hijack ordinary documents, so files with those extensions keep going to TextLoader as before. .graphql is also left out, for a different reason: the extractor only reads GraphQL schemas inside a larger project, not as lone files.Stored under the real extension. Like TextLoader, CodeLoader stores content verbatim under a content-hash file name, but it keeps the original suffix — code_<content_hash>.<ext> (for example code_a1b2c3....py). The storage file name is the only place the extension survives, and language detection downstream depends on it.No LLM or embedding calls. Claimed files are classified as code files and routed by cognify() down a dedicated code route whose task list runs the code graph extraction directly. Chunking, entity extraction with an LLM, and summarization do not run for them, so they also cost nothing in a cognify(dry_run=True) estimate — see Dry-run cost estimation.Requires the enola binary. The code graph extraction is performed by enola, an external Go CLI, not by Python code inside Cognee. The first cognify() run over a code file downloads and installs a pinned enola release automatically; set ENOLA_PATH to use a binary you installed yourself, or ENOLA_AUTO_INSTALL=false to disable the auto-install, in which case a missing binary raises EnolaNotInstalledError.Opting out. preferred_loaders is tried before the default priority order, so you can send a code file back down the normal text and LLM path:
AdvancedPdfLoader uses the unstructured library to perform layout-aware extraction, preserving page structure, tables, image metadata, and page numbers. It groups content by page and prepends Page N: markers to each page’s extracted text, making source pages traceable in downstream chunks. Because PyPdfLoader has higher default priority, you need to request it explicitly with preferred_loaders. It accepts a strategy parameter that controls the trade-off between speed and accuracy:If you want to inspect those page markers after ingestion, retrieve raw chunks with SearchType.CHUNKS. The page number is kept in the chunk text, not in a separate metadata field.
Make sure poppler and tesseract are installed on your system before using AdvancedPdfLoader, in addition to installing the Python dependencies with pip install cognee[docs].
Cognee does not automatically distinguish scanned (image-only) PDFs from text PDFs. The default PyPdfLoader reads the embedded text layer page by page and skips pages with no extractable text. For a scanned PDF — where each page is an image with no text layer — this silently produces empty or near-empty output, and no OCR is performed.A text layer is the selectable, machine-readable text embedded in the PDF. If a page has no text layer, PyPdfLoader omits that page and no Page N: marker is added for it. If pypdf errors on a malformed page, Cognee logs a warning, skips that page, and continues loading the rest of the document.To process scanned PDFs, explicitly select AdvancedPdfLoader with an OCR strategy. Because PyPdfLoader has higher default priority, you must request the OCR-capable loader through preferred_loaders:
Use strategy="ocr_only" for fully image-based or scanned PDFs, and strategy="hi_res" for documents that mix a text layer with scanned images. OCR requires pip install cognee[docs] plus poppler and tesseract installed on the system. For non-English or CJK scanned documents, also install the matching Tesseract language packs (see the next accordion).
Standard PDF text extraction via PyPdfLoader or AdvancedPdfLoader with strategy="fast" often fails silently on CJK and other non-Latin documents. These PDFs commonly embed glyphs as images or use non-standard font encodings, which can lead to empty or garbled output.Use AdvancedPdfLoader with an OCR-based strategy and install Tesseract language packs for your target language.Step 1 — install Tesseract language packs (Ubuntu/Debian):
Step 2 — use ocr_only strategy with the languages parameter:
The languages list accepts ISO 639-2 Tesseract language codes. Common values:Use strategy="hi_res" for better layout accuracy when the document has mixed text and images, and strategy="ocr_only" for fully image-based or scanned PDFs.
If you also need translation after OCR extraction, use the Multilingual Ingestion pipeline before building the knowledge graph.
UnstructuredLoader handles a wide range of office and document formats using unstructured’s auto-partition feature. It supports the same strategy options as AdvancedPdfLoader.Supported file types:
DoclingLoader is the lowest-priority loader and acts as a catch-all fallback for any file type that no other loader can ingest. It converts the document with Docling and exports plain text via Docling’s export_to_text(). Supported extensions are pulled at runtime from Docling’s FormatToExtensions (PDF, DOCX, XLSX, PPTX, HTML, Markdown, and more), so the available formats track your installed Docling version.Install with pip install 'cognee[docling]'. Because it sits last in the loader priority, Cognee only reaches for it when no higher-priority loader matches — to force it on a file another loader would normally handle (for example, to use Docling’s layout-aware parsing on a PDF instead of PyPdfLoader), pass it through preferred_loaders:
When to use Docling vs. AdvancedPdfLoader: prefer AdvancedPdfLoader for PDFs when you need per-page markers, HTML-formatted tables, or OCR strategy control (see the Advanced PDF Loader accordion above). Reach for DoclingLoader when you want a single unified converter across many formats, or for non-PDF files Cognee does not otherwise handle.
BeautifulSoupLoader parses HTML files using CSS selectors. By default it applies a comprehensive set of extraction rules covering common HTML content areas (headings, paragraphs, articles, tables, code blocks, etc.). You can pass your own extraction_rules dict to target specific elements.Each rule is a dict with the following optional keys:
Overlapping CSS rules are deduplicated. Rules are applied in the order they appear in extraction_rules, against a single parsed document. Once a rule extracts an element, elements nested inside it are skipped by later rules, so content covered by a broad selector is not emitted a second time by a narrower one. With the default rules, for example, article runs before paragraphs, so a <p> inside an <article> is extracted once as part of the article rather than repeated. Deduplication works in one direction only: a broad rule listed after a narrower one is not suppressed by it and re-emits the shared content anyway, so list broader selectors before narrower ones — as the default rules do — to avoid duplicates.Deduplication only skips descendants of already-extracted elements. Two rules whose selectors match the exact same element still extract that element twice. Matches within a single rule are likewise not deduplicated against each other, so one selector matching both an element and its descendant emits the shared text twice.For XPath-based extraction (requires pip install lxml):
XPath rules are evaluated against a separate lxml tree and do not take part in the deduplication described above. An XPath rule never suppresses a later CSS rule, and it is never suppressed by an earlier one — so mixing XPath and CSS rules that cover the same elements can still repeat content.
ImageLoader uses your configured LLM to describe image content — there is no separate VLM configuration. To process images, set LLM_MODEL to a vision-capable model.Vision-capable models by provider:
If your LLM_MODEL does not support vision, remembering an image file will fail at the description step. Switch to a vision-capable model and retry.
Ollama users: Pull a vision-capable model (e.g. ollama pull llava) and set LLM_MODEL="llava". Text-only models such as llama3.1 cannot process images. See LLM Providers for full Ollama setup.
For the prompt, token cap, and optional OCR pass used during transcription, see the “Image transcription and OCR” accordion below.
ImageLoader turns an image into text in two steps: a vision-LLM transcription, and — when enabled — a local OCR pass whose recognized text is appended to that transcription. Both are controlled by environment variables.Extraction-oriented transcription (default). The default prompt asks the vision model for concise, factual text aimed at graph extraction: the entities shown and their attributes, the relationships between them, all visible text, numbers, dates, and labels transcribed verbatim, and structured content (tables as rows, charts as series and data points, diagrams as how the elements connect). This produces longer text than a caption, which is why the token cap defaults to 1024.
Optional local OCR. OCR is off by default. When switched on, Cognee runs RapidOCR locally — a pip-only dependency, no system binary — and appends the recognized text to the vision transcription under an [OCR extracted text] heading:
Because the OCR text is part of the loaded text, it flows through chunking, extraction, and storage like any other content. This is most useful for screenshots, scanned pages, and dense charts where the vision model paraphrases labels instead of reproducing them.
OCR text is truncated at 8000 characters (the tail is replaced with ...). If the OCR pass itself fails, Cognee logs an error and continues with the vision transcription alone rather than failing the ingestion.
Custom transcription prompt. IMAGE_TRANSCRIPTION_PROMPT_PATH accepts either a file name inside Cognee’s built-in prompt directory (cognee/infrastructure/llm/prompts) or an absolute path, so you can keep your own prompt file anywhere on disk:
Empty transcriptions on reasoning models. IMAGE_TRANSCRIPTION_MAX_COMPLETION_TOKENS caps reasoning tokens as well as output tokens, so on a reasoning model (including the default openai/gpt-5-mini) a small cap can consume the whole budget on reasoning and return empty content. Cognee logs a warning naming the file and suggesting a higher IMAGE_TRANSCRIPTION_MAX_COMPLETION_TOKENS, then continues with empty text for that image. If images ingest but contribute nothing to the graph, raise the cap.
VideoLoader ingests a video by transcribing its audio track and inlining per-segment [HH:MM:SS] timestamps into the resulting text, for example:
Because the timestamps are part of the text, they survive chunking and stay searchable. From there the transcript flows through the normal TextDocument pipeline (chunking, entity/relationship extraction, graph + vector storage) — there is no separate video document type, so a video becomes queryable memory with no special handling downstream.VideoLoader is a core loader, available in every installation. Supported extensions: .mp4, .m4v, .mov, .webm, .mkv, .avi.
ffmpeg requirement. .mp4 and .webm do not require any extra tooling: if ffmpeg is unavailable, Cognee can send those containers straight to the transcription endpoint. Other containers (.mov, .mkv, .avi, .m4v) require system ffmpeg on your PATH to extract the audio track first. When ffmpeg is present it is also used for .mp4/.webm to keep the upload small.If a container needs ffmpeg and none is found, remember() raises a RuntimeError explaining that ffmpeg must be installed and on your PATH, or that you can supply the video as .mp4 or .webm instead. There is no cognee[video] extra — install ffmpeg through your system package manager.
Inline [HH:MM:SS] markers require a transcription model that supports segmented (verbose_json) output, such as whisper-1. Providers or models without segmented output fall back to a plain transcript with no timestamp markers; the transcript is still ingested normally.
If you need to handle a custom file format, you can create your own loader class and register it with Cognee.
supported_extensions values must not include a leading dot — use bare extensions like "custom" and "jpeg", not ".custom" or ".jpeg". Loader matching compares against the file’s dot-free extension, so a dotted value would never match.
load() receives ingestion context. Beyond the loader-specific options you pass via preferred_loaders, Cognee forwards the current ingestion context to load() as keyword arguments: dataset_name, dataset_id, user, and original_file_name (the user’s real file name, which can differ from file_path when the bytes are a localized copy of an s3:// source or an upload). Accept **kwargs — as the example above does — and ignore what you don’t need.Returning a LoaderResult. load() normally returns the stored derived-text path as a plain str. A loader that also owns the record’s identity and routing can instead return a LoaderResult:
Returning a plain string remains fully supported; only loaders that need stable identity or custom routing need LoaderResult. The built-in DltCsvLoader uses it to carry a CSV manifest’s stable data_id and its no-LLM cognify route stamp.