Skip to main content
Endpoint
GET /ocr/v1/:id/download/:type

Output formats

TypeDescription
textPlain text extraction
jsonStructured data with word coordinates and confidence
pdfSearchable PDF with invisible text layer

Download text

curl https://api.case.dev/ocr/v1/JOB_ID/download/text \
  -H "Authorization: Bearer sk_case_YOUR_API_KEY" \
  -o extracted.txt
casedev ocr:v1 download --id $JOB_ID --type text
import Casedev from 'casedev';

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

const text = await client.ocr.v1.download(jobId, 'text');
console.log(text);
import casedev

client = casedev.Casedev(api_key='sk_case_YOUR_API_KEY')

text = client.ocr.v1.download(job_id, 'text')
print(text)
text, _ := client.Ocr.V1.Download(ctx, jobID, casedev.OcrV1DownloadParamsTypeText)
// text is *http.Response with content body

Download searchable PDF

The searchable PDF looks identical to the original but has an invisible text layer. Users can Ctrl+F to search.
curl https://api.case.dev/ocr/v1/JOB_ID/download/pdf \
  -H "Authorization: Bearer sk_case_YOUR_API_KEY" \
  -o searchable.pdf
casedev ocr:v1 download --id $JOB_ID --type pdf
const pdf = await client.ocr.v1.download(jobId, 'pdf');

// Save to file
fs.writeFileSync('searchable.pdf', Buffer.from(pdf));
pdf = client.ocr.v1.download(job_id, 'pdf')

with open('searchable.pdf', 'wb') as f:
    f.write(pdf)
pdf, _ := client.Ocr.V1.Download(ctx, jobID, casedev.OcrV1DownloadParamsTypePdf)
// pdf is *http.Response with content body

Download structured JSON

JSON includes word-level bounding boxes, confidence scores, and table structures.
curl https://api.case.dev/ocr/v1/JOB_ID/download/json \
  -H "Authorization: Bearer sk_case_YOUR_API_KEY" \
  -o ocr-data.json
casedev ocr:v1 download --id $JOB_ID --type json
const data = await client.ocr.v1.download(jobId, 'json');

// Access word-level data
for (const page of data.pages) {
  for (const block of page.blocks) {
    console.log(block.text, block.confidence);
  }
}
data = client.ocr.v1.download(job_id, 'json')

# Access word-level data
for page in data['pages']:
    for block in page['blocks']:
        print(block['text'], block['confidence'])
jsonData, _ := client.Ocr.V1.Download(ctx, jobID, casedev.OcrV1DownloadParamsTypeJson)
// jsonData is *http.Response with content body
JSON structure
{
  "pages": [
    {
      "page_number": 1,
      "width": 612,
      "height": 792,
      "blocks": [
        {
          "type": "text",
          "text": "DEPOSITION OF JOHN SMITH",
          "confidence": 0.98,
          "bbox": {"x": 72, "y": 72, "width": 468, "height": 24},
          "words": [
            {
              "text": "DEPOSITION",
              "confidence": 0.99,
              "bbox": {"x": 72, "y": 72, "width": 120, "height": 24}
            }
          ]
        }
      ]
    }
  ],
  "tables": [...],
  "metadata": {
    "page_count": 150,
    "engine": "doctr"
  }
}

Complete workflow

casedev llm:v1:chat create-completion \
  --model anthropic/claude-sonnet-4.5 \
  --message '{role: user, content: "Summarize this deposition."}'
// 1. Submit document
const job = await client.ocr.v1.process({
  document_url: 'https://storage.example.com/deposition.pdf'
});

// 2. Wait for completion
let result = await client.ocr.v1.retrieve(job.id);
while (result.status !== 'completed') {
  await new Promise(r => setTimeout(r, 5000));
  result = await client.ocr.v1.retrieve(job.id);
}

// 3. Download results
const text = await client.ocr.v1.download(job.id, 'text');
const pdf = await client.ocr.v1.download(job.id, 'pdf');

// 4. Use with LLM
const analysis = await client.llm.v1.chat.createCompletion({
  model: 'anthropic/claude-sonnet-4.5',
  messages: [
    { role: 'system', content: 'Summarize this deposition.' },
    { role: 'user', content: text }
  ]
});
import time

# 1. Submit document
job = client.ocr.v1.process(
    document_url='https://storage.example.com/deposition.pdf'
)

# 2. Wait for completion
result = client.ocr.v1.retrieve(job.id)
while result.status != 'completed':
    time.sleep(5)
    result = client.ocr.v1.retrieve(job.id)

# 3. Download results
text = client.ocr.v1.download(job.id, 'text')
pdf = client.ocr.v1.download(job.id, 'pdf')

# 4. Use with LLM
analysis = client.llm.v1.chat.create_completion(
    model='anthropic/claude-sonnet-4.5',
    messages=[
        {'role': 'system', 'content': 'Summarize this deposition.'},
        {'role': 'user', 'content': text}
    ]
)
resp, _ := client.Llm.V1.Chat.NewCompletion(ctx, casedev.LlmV1ChatNewCompletionParams{
	Model: casedev.F("anthropic/claude-sonnet-4.5"),
	Messages: casedev.F([]casedev.LlmV1ChatNewCompletionParamsMessage{
		{
			Role:    casedev.F(casedev.LlmV1ChatNewCompletionParamsMessagesRoleSystem),
			Content: casedev.F("Summarize this deposition."),
		},
		{
			Role:    casedev.F(casedev.LlmV1ChatNewCompletionParamsMessagesRoleUser),
			Content: casedev.F("Summarize this deposition."),
		},
	}),
})
fmt.Println(resp.Choices[0].Message.Content)