PageIndex Client
Configure index to process and store your documents, and chat to answer questions with your own LLM.
For index, you choose where documents are processed — cloud, which runs multimodal processing with OCR and image understanding, or local, which builds the index from the PDF's text layer using your own LLM. For chat there is no choice: it uses your own LLM in either mode. So the only setup difference between the two is which API keys you need.
| Cloud | Local | |
|---|---|---|
| PageIndex API key | Required | Not needed |
| LLM provider API key | Required for chat | Required for indexing and chat |
See Compare local and cloud for the full feature comparison.
Set up your client
Choose your index mode below for a complete configuration.
Set your PageIndex API key for indexing:
export PAGEINDEX_API_KEY="your-pageindex-key"
And your LLM provider's API key for chat:
export OPENAI_API_KEY="your-openai-key"
Then create the client:
from pageindex import PageIndexClient
client = PageIndexClient(index="cloud", chat="gpt-5.6-sol")
Set your LLM provider's API key for indexing and chat. No PageIndex API key is needed. This example uses the same provider's key for both models.
export OPENAI_API_KEY="your-openai-key"
Then create the client:
from pageindex import PageIndexClient
client = PageIndexClient(index="gpt-5.6-luna", chat="gpt-5.6-sol")
Documents are stored in ./.pageindex by default. To use another directory, include storage_path in the index configuration:
client = PageIndexClient(
index={"model": "gpt-5.6-luna", "storage_path": "./my-documents"},
chat="gpt-5.6-sol",
)
Continue with LLM Integration.
Use different LLMs
Model names follow LiteLLM's naming convention. Choose your provider below — the index mode is independent, so either one works with any model.
export OPENAI_API_KEY="your-openai-api-key"
client = PageIndexClient(index="cloud", chat="gpt-5.6-sol") # or index="gpt-5.6-luna" for local indexing
export ANTHROPIC_API_KEY="your-anthropic-api-key"
client = PageIndexClient(index="cloud", chat="anthropic/claude-opus-5") # or index="gpt-5.6-luna" for local indexing
export OPENROUTER_API_KEY="your-openrouter-api-key"
client = PageIndexClient(index="cloud", chat="openrouter/anthropic/claude-opus-5") # or index="gpt-5.6-luna" for local indexing
Set the server's base URL and API key, then use the model name it serves:
export OPENAI_API_KEY="your-api-key"
export OPENAI_BASE_URL="https://your-server.example/v1"
client = PageIndexClient(index="cloud", chat="your-model-name") # or index="gpt-5.6-luna" for local indexing
For model IDs containing slashes, use the openai/ prefix, for example openai/Qwen/....
The same provider naming convention applies to local indexing models passed as index=. For other providers, see the LiteLLM provider documentation.
Using your own agent framework
Configure your LLM and its API key in your agent framework. Keep the index configuration and its required credentials from above, and omit chat when creating the PageIndex client:
client = PageIndexClient(index="cloud")
client = PageIndexClient(index="gpt-5.6-luna")
Continue with Agent Integration.
Backend overrides
Include connection settings in the backend field of your index or chat configuration.
client = PageIndexClient(
index="cloud", # or "gpt-5.6-luna" for local indexing
chat={
"model": "gpt-5.6-sol",
"backend": {
"api_key": "your-api-key",
"base_url": "https://my-gateway.internal/v1",
},
},
)
client = PageIndexClient(
index={
"model": "gpt-5.6-luna",
"backend": {
"api_key": "your-api-key",
"base_url": "https://my-gateway.internal/v1",
},
},
)
Keys are passed through to the underlying client, such as api_key, base_url, api_version, and aws_*.
Per-call backend overrides
A call's backend keys override the corresponding defaults in chat["backend"]:
answer = client.chat(
"What changed?",
doc_id=doc_id,
backend={"api_key": "another-api-key"},
)
PageIndexClient() parameters
Use one configuration style per side. When passing index=, put local model, summary_model, storage_path, and backend inside its dict instead of also passing index_model, summary_model, storage_path, or index_backend. Likewise, use chat={"model": ..., "backend": ...} instead of combining chat= with chat_model or chat_backend.
| Name | Type | Description | Default |
|---|---|---|---|
| api_key | string | PageIndex cloud API key. Omit for local mode. | None |
| index | string or dict | The index side, grouped: "cloud", "local", a local index model name, or a dict ({"api_key"} for cloud; {"model", "summary_model", "backend", "storage_path"} for local). | None |
| chat | string or dict | The chat side, grouped: a model name, or a dict {"model", "backend"}. | None |
| mode | string | Cross-check on where documents live — "cloud" or "local". Always optional; the other arguments already carry the mode. | None |
| index_model | string | Local only — model used to index documents (structure and summaries). | gpt-5.6-luna |
| chat_model | string | The model that searches the tree and answers. Runs in your process, on your keys, in either index mode. | gpt-5.6-sol |
| model | string | Local only — one model for both roles. The role-specific arguments win over it. | None |
| storage_path | string | Local only — directory where indexed documents are stored. | ./.pageindex |
| index_backend | dict | Local only — connection overrides for the indexing lane's LLM calls (LiteLLM connection params). | None |
| chat_backend | dict | Default connection overrides for the chat surfaces. A call's own backend keys win over it. | None |
| instructions | string | Standing guidance for the answering agent — persona, language, format — appended after PageIndex's managed prompt on every surface that answers: chat() on every lane, and agent_instructions(). A call's own instructions= adds to it. | None |
| summary_model | string | Local only — legacy override for node summaries and document descriptions; index_model covers this. | None |
| retrieve_model | string | Legacy name for chat_model. | None |