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

# Build From Documents

> Turn PDFs, Markdown, Office files, and folders into a searchable knowledge base.

Use this walkthrough when your source material lives in files: PDFs, DOCX, PPTX, XLSX, Markdown, HTML, TXT, CSV, or a folder containing many supported documents.

## What you will build

A `docs` collection from `files/docs/`, with retrieval and chat over the parsed documents.

## Prerequisites

```bash theme={null}
pip install "ragrails[voyage,qdrant]"
export VOYAGE_API_KEY="..."
export OPENAI_API_KEY="..."
docker run -p 6333:6333 qdrant/qdrant
```

## 1. Pick the input shape

| Source shape    | SDK                                                  | CLI                                    | REST                                        |
| --------------- | ---------------------------------------------------- | -------------------------------------- | ------------------------------------------- |
| One file        | `docs="files/guide.pdf"`                             | `--docs files/guide.pdf`               | `/v1/ingest/docs` with `files`              |
| Many files      | `docs=["a.pdf", "b.docx"]`                           | repeat `--docs`                        | `/v1/ingest/docs` with `files` list         |
| Folder          | `docs={"folder": "files/docs/"}`                     | `--folder files/docs/`                 | `/v1/ingest/docs` or pipeline `docs.folder` |
| Remote file URL | `docs="https://example.com/guide.pdf"`               | `--docs https://example.com/guide.pdf` | `/v1/ingest/docs` with `files`              |
| Browser upload  | `docs=[{"content": bytes, "filename": "guide.pdf"}]` | Not supported                          | `/v1/ingest/docs/upload`                    |

## 2. Ingest the folder

<CodeGroup>
  ```python SDK theme={null}
  from ragrails import RagRails

  rag = RagRails(
      collection="docs",
      vector_store={"provider": "qdrant", "url": "http://localhost:6333"},
      embedding={"provider": "voyage", "model": "voyage-3"},
      llm={"provider": "openai", "model": "gpt-4o-mini"},
  )

  result = rag.ingest(
      docs={"folder": "files/docs/"},
      chunking={"chunk_size": 900, "chunk_overlap": 120},
      storage={"collection": "docs"},
  )

  print(f"stored={result.stored} failed={result.failed}")
  ```

  ```bash CLI theme={null}
  ragrails ingest \
    --folder files/docs/ \
    --vector-db qdrant \
    --collection docs \
    --url http://localhost:6333 \
    --provider voyage \
    --model voyage-3 \
    --chunk-size 900 \
    --chunk-overlap 120
  ```

  ```bash REST API theme={null}
  curl -X POST http://127.0.0.1:8000/v1/pipelines/ingest \
    -H "Content-Type: application/json" \
    -d '{
      "docs": {"folder": "files/docs/"},
      "chunking": {"chunk_size": 900, "chunk_overlap": 120},
      "embedding": {"provider": "voyage", "model": "voyage-3"},
      "storage": {"vector_db": "qdrant", "collection": "docs", "url": "http://localhost:6333"}
    }'
  ```
</CodeGroup>

## 3. Query or chat

<CodeGroup>
  ```python SDK theme={null}
  hits = rag.query("What does the guide cover?", retrieval={"top_k": 5})
  answer = rag.chat("How do I get started?", history=[])
  ```

  ```bash CLI theme={null}
  ragrails query "What does the guide cover?" \
    --vector-db qdrant \
    --collection docs \
    --url http://localhost:6333 \
    --provider voyage \
    --model voyage-3 \
    --top-k 5

  ragrails chat "How do I get started?" \
    --vector-db qdrant \
    --collection docs \
    --url http://localhost:6333 \
    --embedder-provider voyage \
    --embedder-model voyage-3 \
    --llm-provider openai \
    --llm-model gpt-4o-mini
  ```

  ```bash REST API theme={null}
  curl -X POST http://127.0.0.1:8000/v1/chat \
    -H "Content-Type: application/json" \
    -d '{
      "query": "How do I get started?",
      "llm_provider": "openai",
      "llm_model": "gpt-4o-mini",
      "embedder_provider": "voyage",
      "embedder_model": "voyage-3",
      "vector_db": "qdrant",
      "collection": "docs",
      "url": "http://localhost:6333",
      "history": []
    }'
  ```
</CodeGroup>

## Uploads over REST

Use multipart upload when the client sends file bytes to the server.

```bash theme={null}
curl -X POST http://127.0.0.1:8000/v1/ingest/docs/upload \
  -F "files=@files/guide.pdf" \
  -F "frontmatter=false" \
  -F "title=Guide" \
  -F "description=Product guide"
```

## Next steps

* [Extraction](/features/extraction)
* [Chunking](/features/chunking)
* [Internal Knowledge Base](/use-cases/internal-knowledge-base)
* [Knowledge Base Maintenance](/features/knowledge-base-maintenance)
