Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.case.dev/llms.txt

Use this file to discover all available pages before exploring further.

What You’ll Build

A script that:
  1. Searches your indexed documents in a vault
  2. Analyzes the results with an LLM
  3. Returns structured insights with source citations
Time to complete: 15 minutes

Architecture

Prerequisites

  • Case.dev API key (get one here)
  • A vault with ingested documents (we’ll set one up if you don’t have one)

Step 1: Set Up Your Vault

If you already have a vault with indexed documents, skip to Step 2.

Create a vault

curl -X POST https://api.case.dev/vault \
  -H "Authorization: Bearer $CASEDEV_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Legal Research Vault"}'
Save the returned id — you’ll need it.

Upload a document

# Get upload URL
UPLOAD_RESPONSE=$(curl -s -X POST "https://api.case.dev/vault/$VAULT_ID/upload" \
  -H "Authorization: Bearer $CASEDEV_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"filename": "contract.pdf", "contentType": "application/pdf"}')

UPLOAD_URL=$(echo $UPLOAD_RESPONSE | jq -r '.uploadUrl')
OBJECT_ID=$(echo $UPLOAD_RESPONSE | jq -r '.objectId')

# Upload your file
curl -X PUT "$UPLOAD_URL" \
  -H "Content-Type: application/pdf" \
  --data-binary @contract.pdf

Ingest (index) the document

curl -X POST "https://api.case.dev/vault/$VAULT_ID/ingest/$OBJECT_ID" \
  -H "Authorization: Bearer $CASEDEV_API_KEY"

# Check status (poll until completed)
curl "https://api.case.dev/vault/$VAULT_ID/objects/$OBJECT_ID" \
  -H "Authorization: Bearer $CASEDEV_API_KEY" | jq '.ingestionStatus'
Ingestion is async. Wait for ingestionStatus: "completed" before searching. For production, use webhooks instead of polling.

Step 2: Search Your Documents

Query your vault with a natural language question:
curl -X POST "https://api.case.dev/vault/$VAULT_ID/search" \
  -H "Authorization: Bearer $CASEDEV_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "What are the key terms of this agreement?",
    "method": "hybrid",
    "limit": 10
  }'
Response
{
  "chunks": [
    {
      "text": "The Parties agree to the following terms...",
      "object_id": "obj_xyz789",
      "hybridScore": 0.89,
      "vectorScore": 0.92,
      "bm25Score": 0.78
    }
  ],
  "sources": [
    { "id": "obj_xyz789", "filename": "contract.pdf" }
  ]
}

Step 3: Analyze with an LLM

Pass the search results to an LLM for structured analysis:
casedev llm:v1:chat create-completion \
  --model anthropic/claude-sonnet-4.5 \
  --message '{role: system, content: "You are a legal document analyst. Cite specific passages to support your analysis."}' \
  --message '{role: user, content: "<document excerpts>\n\nQuestion: What are the key terms of this agreement?"}' \
  --temperature 0.3
Response
{
  "choices": [{
    "message": {
      "content": "Based on the contract excerpts, the key terms include:\n\n1. **Payment Terms**: Section 3.2 states that payment is due within 30 days...\n\n2. **Termination**: Either party may terminate with 90 days written notice (Section 7.1)...\n\n3. **Liability Cap**: Liability is limited to the total fees paid in the preceding 12 months (Section 9.3)..."
    }
  }],
  "usage": {
    "prompt_tokens": 1245,
    "completion_tokens": 387,
    "total_tokens": 1632,
    "cost": 0.004896
  }
}

Complete Example

Putting it all together — a reusable function that searches and analyzes:
# 1. Search vault for relevant documents
casedev vault search --id $VAULT_ID \
  --query "What are the indemnification clauses?" \
  --method hybrid --limit 10

# 2. Analyze with LLM
casedev llm:v1:chat create-completion \
  --model anthropic/claude-sonnet-4.5 \
  --message '{role: system, content: "You are a senior legal analyst. Answer using only the provided excerpts."}' \
  --message '{role: user, content: "<document excerpts from search>\n\nQuestion: What are the indemnification clauses?"}' \
  --temperature 0.3

Extending the Analyzer

Add Entity Extraction

Run a second LLM pass to extract structured entities:
casedev llm:v1:chat create-completion \
  --model openai/gpt-4o \
  --message '{role: system, content: "Extract named entities as JSON: {people: [], organizations: [], dates: [], locations: [], monetary_amounts: []}"}' \
  --message '{role: user, content: "<document text>"}' \
  --temperature 0

Generate a PDF Report

Convert the analysis into a formatted document:
casedev format:v1 document \
  --content "# Report" \
  --input-format md --output-format pdf

Production Tips

Error Handling

# CLI displays errors to stderr with status codes
casedev vault search --id $VAULT_ID --query "analysis query"
# Error: 404 Not Found — check your vault ID
# Error: 429 Too Many Requests — retry after a delay
Use temperature: 0 for factual extraction tasks. Try cheaper models like deepseek/deepseek-chat for simpler analysis.

Next Steps