Quick start

Upload a PDF, then ask questions about it. You get back, for each question, the pages likely to answer it.

Build with a coding agent

Paste this into Claude Code, Cursor, Codex or any agent that can read a link. The skill tells it how to use the API.

Read https://search.pageindex.ai/SKILL.md and follow it to set up Page Search API in this project.

Or set it up yourself, in four steps:

1. Get an API key

Sign in to the console and create a key. It is shown once; keep it in an environment variable.

export PAGEINDEX_SEARCH_API_KEY=pis_live_...

Install the SDK for Python (source) or JavaScript (source). Any other language can call the API directly, as the curl examples do.

pip install pageindex-search

2. Upload a document

Send a PDF of up to 100 MB. The call waits until the document is ready (up to 10 seconds by default; set wait to change it), then returns it. A larger document may come back with "status": "processing" and a 202; search it once it is ready. The SDKs wait for you.

from pageindex_search import PageSearch

client = PageSearch()  # reads PAGEINDEX_SEARCH_API_KEY

doc = client.documents.upload("report.pdf")
print(doc.id, doc.status, doc.pages)
Response
{
  "object": "document",
  "id": "doc_60a07bcef3094b68806070f2",
  "filename": "report.pdf",
  "status": "ready",
  "pages": 160,
  "bytes": 1252586,
  "created_at": "2026-10-26T06:52:57Z",
  "duplicate": false
}

Ask up to 10 questions in one search; ten take about as long as one.

result = client.search(["What was capital expenditure in 2018?", "Who is the CEO?"], document=doc)

for answer in result.results:
    print(answer.question)
    for page in answer.documents[0].pages:
        print("  page", page.page, page.relevance)
Response
{
  "object": "search",
  "id": "srch_51b0c2…",
  "results": [
    {"question": "What was capital expenditure in 2018?",
     "documents": [{"document_id": "doc_60a07bcef3094b68806070f2", "filename": "report.pdf", "page_count": 160,
                    "pages": [{"page": 39, "relevance": 1.0}, {"page": 126, "relevance": 1.0}, {"page": 49, "relevance": 0.9}, …],
                    "failed_pages": [], …}]},
    {"question": "Who is the CEO?",
     "documents": [{"document_id": "doc_60a07bcef3094b68806070f2", "filename": "report.pdf", "page_count": 160,
                    "pages": [{"page": 8, "relevance": 1.0}, {"page": 134, "relevance": 1.0}, …],
                    "failed_pages": [], …}]}
  ],
  "failed_documents": [],
  "processing_documents": [],
  "usage": {"documents": 0, "pages": 160, "questions": 2, "cost_usd": 0.112, "balance_usd": 4.888},
  "seconds": 0.88
}

Each question lists, under the document searched, the pages likely to help, most relevant first, each with its relevance from 0 to 1, to one decimal. It may list none, when no page is likely to help. Set "top_k": 5 (in Python, top_k=5; in JavaScript, { topK: 5 }) to get exactly that many pages instead. Search the same document as often as you like: it is processed once.

4. Reuse or delete a document

A document is kept until you delete it. Keep its id, or list your documents to find it, and search it again whenever you like: it is not processed again. Uploading the same file again also returns the same document. Delete documents you no longer need: past 10,000 stored pages, storage is charged.

# Your documents, newest first: the loop goes through every page of them
for doc in client.documents.list():
    print(doc.id, doc.filename, doc.pages)

# Search one again by its id: nothing to upload, nothing to wait for
result = client.search(["What was revenue in 2018?"], document="doc_60a07bcef3094b68806070f2")

# Delete one you no longer need
client.documents.delete("doc_60a07bcef3094b68806070f2")

Next

  • Concepts: what relevance means, which documents a search covers, and how documents are kept and billed.
  • Search pages: search across all your documents, a collection, or those whose metadata meets a filter.
  • Agent tools and MCP: let an LLM agent search and read the documents itself.
  • API reference: every endpoint, field and error.