1. Submit for OCR
curl -X POST https://api.case.dev/ocr/v1/process \
-H "Authorization: Bearer $CASEDEV_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"document_url": "https://your-storage.com/user-upload.pdf",
"engine": "doctr",
"features": {"embed": {}}
}'
casedev ocr:v1 process \
--document-url "https://storage.example.com/document.pdf"
import Casedev from 'casedev';
const client = new Casedev({ apiKey: process.env.CASEDEV_API_KEY });
// Process a document uploaded by your user
const job = await client.ocr.v1.process({
document_url: documentUrl, // URL from your user's upload
engine: 'doctr', // Fast, good for printed text
features: {
embed: {} // Generate searchable PDF
}
});
console.log(`OCR job started: ${job.id}`);
import casedev
import os
client = casedev.Casedev(api_key=os.environ['CASEDEV_API_KEY'])
# Process a document uploaded by your user
job = client.ocr.v1.process(
document_url=document_url, # URL from your user's upload
engine='doctr', # Fast, good for printed text
features={
'embed': {} # Generate searchable PDF
}
)
print(f'OCR job started: {job.id}')
job, _ := client.Ocr.V1.Process(ctx, casedev.OcrV1ProcessParams{
DocumentURL: casedev.F("https://storage.example.com/document.pdf"),
})
fmt.Println(job.ID)
2. Wait for completion
OCR runs asynchronously. Poll for status or use webhooks to notify your users:# Poll for status
curl "https://api.case.dev/ocr/v1/$JOB_ID" \
-H "Authorization: Bearer $CASEDEV_API_KEY"
casedev ocr:v1 retrieve --id $JOB_ID
// Poll for completion
let result = await client.ocr.v1.retrieve(job.id);
while (result.status === 'processing' || result.status === 'pending') {
console.log(`Status: ${result.status} (${result.chunks_completed}/${result.chunk_count} pages)`);
await new Promise(r => setTimeout(r, 5000));
result = await client.ocr.v1.retrieve(job.id);
}
if (result.status === 'completed') {
console.log(`✅ OCR complete! ${result.page_count} pages processed.`);
console.log(`Confidence: ${(result.confidence * 100).toFixed(1)}%`);
}
import time
# Poll for completion
result = client.ocr.v1.retrieve(job.id)
while result.status in ['processing', 'pending']:
print(f'Status: {result.status} ({result.chunks_completed}/{result.chunk_count} pages)')
time.sleep(5)
result = client.ocr.v1.retrieve(job.id)
if result.status == 'completed':
print(f'✅ OCR complete! {result.page_count} pages processed.')
print(f'Confidence: {result.confidence * 100:.1f}%')
result, _ := client.Ocr.V1.Get(ctx, jobID)
fmt.Println(result.Status)
3. Download results
Provide extracted text, structured data, or a searchable PDF:# Download text
curl "https://api.case.dev/ocr/v1/$JOB_ID/download/text" \
-H "Authorization: Bearer $CASEDEV_API_KEY" \
-o extracted.txt
# Download searchable PDF
curl "https://api.case.dev/ocr/v1/$JOB_ID/download/pdf" \
-H "Authorization: Bearer $CASEDEV_API_KEY" \
-o searchable.pdf
casedev ocr:v1 download --id $JOB_ID --type text
// Download plain text for your user
const text = await client.ocr.v1.download(job.id, 'text');
// Download searchable PDF (original with invisible text layer)
const pdf = await client.ocr.v1.download(job.id, 'pdf');
fs.writeFileSync('searchable-document.pdf', Buffer.from(pdf));
// Download structured JSON (with word coordinates for highlighting)
const json = await client.ocr.v1.download(job.id, 'json');
console.log(`Extracted ${json.pages.length} pages`);
# Download plain text for your user
text = client.ocr.v1.download(job.id, 'text')
# Download searchable PDF (original with invisible text layer)
pdf = client.ocr.v1.download(job.id, 'pdf')
with open('searchable-document.pdf', 'wb') as f:
f.write(pdf)
# Download structured JSON (with word coordinates for highlighting)
json_data = client.ocr.v1.download(job.id, 'json')
print(f'Extracted {len(json_data["pages"])} pages')
text, _ := client.Ocr.V1.Download(ctx, jobID, casedev.OcrV1DownloadParamsTypeText)
// text is *http.Response with content body
4. Analyze with AI
Enhance your feature with automatic data extraction:curl -X POST https://api.case.dev/llm/v1/chat/completions \
-H "Authorization: Bearer $CASEDEV_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic/claude-sonnet-4.5",
"messages": [
{"role": "system", "content": "Extract key dates, parties, and claims. Format as JSON."},
{"role": "user", "content": "[OCR TEXT]"}
],
"temperature": 0
}'
casedev llm:v1:chat create-completion \
--model anthropic/claude-sonnet-4.5 \
--message '{role: system, content: "Extract key dates, parties, and claims from this document. Format as JSON."}' \
--message '{role: user, content: "<OCR text>"}' \
--temperature 0
// Extract key information for your user
const analysis = await client.llm.v1.chat.createCompletion({
model: 'anthropic/claude-sonnet-4.5',
messages: [
{
role: 'system',
content: 'Extract key dates, parties, and claims from this document. Format as JSON.'
},
{
role: 'user',
content: text
}
],
temperature: 0 // Deterministic for factual extraction
});
// Return structured data to your user
console.log(analysis.choices[0].message.content);
# Extract key information for your user
analysis = client.llm.v1.chat.create_completion(
model='anthropic/claude-sonnet-4.5',
messages=[
{
'role': 'system',
'content': 'Extract key dates, parties, and claims from this document. Format as JSON.'
},
{
'role': 'user',
'content': text
}
],
temperature=0 # Deterministic for factual extraction
)
# Return structured data to your user
print(analysis.choices[0].message.content)
// Extract key information for your user
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("Extract key dates, parties, and claims from this document. Format as JSON."),
},
{
Role: casedev.F(casedev.LlmV1ChatNewCompletionParamsMessagesRoleUser),
Content: casedev.F(text), // OCR-extracted text
},
}),
Temperature: casedev.F(float64(0)),
})
fmt.Println(resp.Choices[0].Message.Content)
OCR engines
Choose the right engine based on your users’ document types:| Engine | Best for | Speed |
|---|---|---|
doctr | Clean printed text | Fast |
paddleocr | Tables, forms, complex layouts | Slower |
Recommendation: Start with
doctr for most use cases. Switch to paddleocr if your users need table extraction or have complex document layouts.
