Skip to main content
Three steps to make a document searchable:
  1. Create a vault (once per case)
  2. Upload your file
  3. Process it (we call this “ingest”)
After processing, the document is fully searchable by meaning.

Step 1: Create a vault

A vault is a container for your documents. Create one per case or matter.
Endpoint
POST /vault
import Casedev from 'casedev';

const client = new Casedev({ apiKey: 'sk_case_YOUR_API_KEY' });

const vault = await client.vault.create({
  name: 'Smith v. Hospital 2024',
  description: 'Discovery and depositions'
});

console.log(vault.id);  // Save this—you'll use it for everything
Response
{
  "id": "vault_abc123xyz",
  "name": "Smith v. Hospital 2024",
  "description": "Discovery and depositions",
  "enableIndexing": true,
  "createdAt": "2025-01-15T10:30:00Z"
}

Vault options

OptionDefaultDescription
namerequiredDisplay name for the vault
descriptionoptionalDescription of the vault’s purpose
enableIndexingtrueEnable vector search. Set false for storage-only vaults
enableGraphtrueEnable GraphRAG knowledge graph (requires indexing)

Storage-only vaults

If you only need document storage without search capabilities, create a storage-only vault:
const vault = await client.vault.create({
  name: 'Archive Storage',
  enableIndexing: false  // No vector index, no search
});
Storage-only vaults skip vector bucket and index creation. Files can be uploaded and downloaded, but search and GraphRAG are unavailable. Use this for pure archival or when you’ll process documents externally.

Step 2: Upload a file

Uploading is two parts: get a secure URL, then PUT your file to it.
Endpoint
POST /vault/:id/upload
// Get an upload URL
const upload = await client.vault.upload(vault.id, {
  filename: 'deposition-johnson.pdf',
  contentType: 'application/pdf',
  metadata: {
    witness: 'Dr. Sarah Johnson',
    date: '2024-11-04'
  }
});

// Upload the file directly to S3
await fetch(upload.uploadUrl, {
  method: 'PUT',
  headers: { 'Content-Type': 'application/pdf' },
  body: fileBuffer
});

console.log(upload.objectId);  // Use this for the next step

Why two steps?

Security and speed. Your file goes directly to encrypted storage—we’re never a bottleneck for large uploads.

Supported file types

TypeExtensions
Documents.pdf, .doc, .docx, .txt, .rtf, .xml
Images.png, .jpg, .jpeg, .tiff, .bmp
Audio.mp3, .m4a, .wav, .flac, .ogg
Video.mp4, .webm, .mov
Court recordings.ftr

Step 3: Process the file

This is where the magic happens. Processing (we call it “ingest”) does different things based on file type:
File typeWhat we do
Scanned PDF, imagesOCR to extract text
Audio, videoTranscribe with speaker labels
FTR recordingsConvert → Transcribe
Digital PDF, DOCX, TXT, RTF, XMLExtract text directly
Then for all files: split into chunks, convert to vectors, index for search.
Endpoint
POST /vault/:vaultId/ingest/:objectId
const result = await client.vault.ingest(vault.id, upload.objectId);

console.log(result.status);  // 'processing'

Processing time

FileTime
10-page clean PDF~10 seconds
50-page scanned PDF~2-3 minutes
300-page scanned PDF~12-15 minutes
1-hour audio/video~5-10 minutes
Processing is async—you get an immediate response while we work in the background.

Check status

// Poll until complete
let obj = await client.vault.objects.retrieve(vault.id, objectId);

while (obj.ingestionStatus === 'processing') {
  await new Promise(r => setTimeout(r, 5000));
  obj = await client.vault.objects.retrieve(vault.id, objectId);
}

if (obj.ingestionStatus === 'completed') {
  console.log('Ready to search!');
}

Complete example

Upload an entire folder of discovery documents:
import Casedev from 'casedev';
import fs from 'fs';
import path from 'path';

const client = new Casedev({ apiKey: process.env.CASEDEV_API_KEY });

async function uploadDiscovery(folderPath: string) {
  // 1. Create vault
  const vault = await client.vault.create({
    name: 'Matter 2024-1234 Discovery'
  });

  // 2. Upload each file
  const files = fs.readdirSync(folderPath);

  for (const file of files) {
    const filePath = path.join(folderPath, file);
    if (!fs.statSync(filePath).isFile()) continue;

    // Get upload URL
    const upload = await client.vault.upload(vault.id, {
      filename: file,
      contentType: 'application/pdf'
    });

    // Upload to S3
    await fetch(upload.uploadUrl, {
      method: 'PUT',
      body: fs.readFileSync(filePath)
    });

    // Process
    await client.vault.ingest(vault.id, upload.objectId);

    console.log(`✓ ${file}`);
  }

  console.log(`\nVault ready: ${vault.id}`);
  return vault.id;
}

uploadDiscovery('./discovery_documents');
Metadata matters. Add metadata like witness, document_type, or date when uploading—you can filter search results by these fields later.

Next: Search your documents

Now that your documents are processed, learn how to search them →