Solution Patterns & Playbooks

Citation Grounding Without Embeddings: Files API and Search Results

Not every question-answering system needs a vector database. If your corpus is modest or you already have a search engine, Claude can deliver source-cited answers with far less infrastructure.

Claude 3P 101 · Updated July 2026 · Unofficial guide

The default mental model for "chat with our documents" involves an embedding pipeline, a vector database, and a retrieval layer — a real system to build and operate. For many enterprise cases that machinery is overkill. Claude's citations feature works on any document content you place in the request, however it got there. That opens two lighter architectures: pass the documents directly (uploaded once via the Files API or inlined per request), or reuse a search engine you already run and pass its results. Both produce answers with verifiable citations; neither requires an embedding in sight.

How citations work

Set "citations": {"enabled": true} on a document content block — a standard Messages API feature, no beta header — and Claude's answer comes back with citation objects pointing at the exact supporting passages. The format depends on the document type: plain text yields character-range citations (sentence-chunked), PDFs yield page-location citations, and "custom content" documents yield citations against content blocks you define yourself. The cited_text returned doesn't count toward your output tokens, and the docs note citations are more token-efficient and reliable than prompting the model to quote sources. All active models support citations except Claude Haiku 3, and the feature is GA on the Claude API, Claude Platform on AWS, Amazon Bedrock, Google Vertex AI, and Microsoft Foundry.

Two documented constraints to design around: citations cannot be combined with structured outputs in the same request (400 error), and scanned PDFs without extractable text are not citable — run OCR upstream if your corpus includes scans.

Architecture A: whole documents, no retrieval

If the documents relevant to a query fit in the context window — and with 1M-token windows on most current models, a policy manual or a contract set usually does — skip retrieval entirely. Upload documents once through the Files API (POST /v1/files, beta header files-api-2025-04-14, up to 500 MB per file, 500 GB per organization) and reference them by file_id in each request, so you aren't re-transmitting megabytes per question. Files persist until deleted and storage operations are free; the file content bills as normal input tokens when used. Pair this with prompt caching — the document block is identical across requests, so after the first request it can be served as a cache read at 0.1x the base input price.

Platform note: the Files API is available on the Claude API, Claude Platform on AWS, and Microsoft Foundry (Hosted-on-Anthropic deployments only) — not on Amazon Bedrock or Google Cloud. On Bedrock and Vertex AI, the same architecture works by inlining documents as base64 or plain-text blocks in each request and leaning on prompt caching; you lose the upload-once convenience, not the citations.
from anthropic import AnthropicAWS  # Claude Platform on AWS

client = AnthropicAWS()  # uses AWS_REGION + ANTHROPIC_AWS_WORKSPACE_ID
msg = client.messages.create(
    model="claude-sonnet-5", max_tokens=1024,
    messages=[{"role": "user", "content": [
        {"type": "document",
         "source": {"type": "file", "file_id": "file_abc123"},
         "citations": {"enabled": True}},
        {"type": "text", "text": "What is our refund window for annual plans?"}]}])

Architecture B: your existing search engine as the retriever

If you already operate full-text search — an intranet index, a ticketing system, an e-commerce catalog — it can serve as the retrieval layer. Run the user's question through it, then pass the top hits into the request as citable content: the Messages API supports search-result content blocks, which are GA on the Claude API, Claude Platform on AWS, Bedrock, Vertex AI, and Foundry, or you can wrap each hit in its own plain-text document block with citations enabled, following the documented RAG guidance of one chunk per document block. The reliability advantage over a vector store is organizational, not just technical: your search engine's relevance behavior is already understood, tuned, and access-controlled.

When you've outgrown this pattern

These architectures share one honest limit: retrieval quality is whatever your search engine (or "send everything") gives you. When queries are paraphrase-heavy and keyword search keeps missing relevant passages, that's the signal to add semantic retrieval — covered in hybrid retrieval and chunking strategies. The citation layer described here carries over unchanged; only the retriever is replaced.

Where to go next

See the feature gaps article for what Bedrock and Vertex don't support, and the feature matrix for the full availability picture.

Sources