> ## 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.

# Process document

> Extract text from PDFs, images, and scanned documents

Submit a document for OCR. We extract text, detect tables, and optionally generate a searchable PDF. Processing is async — you get a job ID immediately, then poll for results or use webhooks.

```bash title="Endpoint" theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
POST /ocr/v1/process
```

<CodeGroup>
  ```bash title="cURL" theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
  curl -X POST https://api.case.dev/ocr/v1/process \
    -H "Authorization: Bearer sk_case_YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "document_url": "https://storage.example.com/scanned-deposition.pdf"
    }'
  ```

  ```bash title="CLI" theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
  casedev ocr:v1 process \
    --document-url "https://storage.example.com/document.pdf"
  ```

  ```typescript title="Typescript" theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
  import Casedev from 'casedev';

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

  const job = await client.ocr.v1.process({
    document_url: 'https://storage.example.com/scanned-deposition.pdf'
  });

  console.log(job.id); // 1f4a195e-026b-41ff-b367-c61089f5f367
  ```

  ```python title="Python" theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
  import casedev

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

  job = client.ocr.v1.process(
      document_url='https://storage.example.com/scanned-deposition.pdf'
  )

  print(job.id)  # 1f4a195e-026b-41ff-b367-c61089f5f367
  ```

  ```go title="Go" theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
  job, _ := client.Ocr.V1.Process(ctx, casedev.OcrV1ProcessParams{
  	DocumentURL: casedev.F("https://storage.example.com/document.pdf"),
  })
  fmt.Println(job.ID)
  ```
</CodeGroup>

```json title="Response" theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
{
  "id": "1f4a195e-026b-41ff-b367-c61089f5f367",
  "status": "pending",
  "document_url": "https://storage.example.com/scanned-deposition.pdf",
  "engine": "doctr",
  "created_at": "2025-11-04T09:30:12Z",
  "links": {
    "self": "https://api.case.dev/ocr/v1/1f4a195e-026b-41ff-b367-c61089f5f367",
    "text": "https://api.case.dev/ocr/v1/1f4a195e-026b-41ff-b367-c61089f5f367/download/text",
    "json": "https://api.case.dev/ocr/v1/1f4a195e-026b-41ff-b367-c61089f5f367/download/json"
  }
}
```

## Parameters

### Required

| Parameter      | Type   | Description                                 |
| -------------- | ------ | ------------------------------------------- |
| `document_url` | string | URL to your document. HTTP/HTTPS or `s3://` |

### Optional

| Parameter      | Type   | Default        | Description                             |
| -------------- | ------ | -------------- | --------------------------------------- |
| `document_id`  | string | auto-generated | Your internal reference ID              |
| `engine`       | string | `doctr`        | OCR engine (see below)                  |
| `callback_url` | string | —              | Webhook URL for completion notification |
| `features`     | object | `{}`           | Additional processing options           |

### OCR engines

| Engine      | Best for                                    | Speed  |
| ----------- | ------------------------------------------- | ------ |
| `doctr`     | Clean printed text, typed documents         | Fast   |
| `paddleocr` | Tables, forms, complex layouts, handwriting | Medium |

<Info>
  **For legal documents:** Start with `doctr`. If you're getting poor results on forms or tables, try `paddleocr`.
</Info>

### Features

Enable additional processing:

```json title="JSON" theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
{
  "features": {
    "embed": {},          // Generate searchable PDF
    "tables": {           // Extract tables as CSV
      "format": "csv"
    }
  }
}
```

## Checking status

Poll the job to check if processing is complete:

<CodeGroup>
  ```bash title="CLI" theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
  casedev ocr:v1 retrieve --id $JOB_ID
  ```

  ```typescript title="Typescript" theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
  const result = await client.ocr.v1.retrieve(job.id);

  if (result.status === 'completed') {
    // Download the extracted text
    const text = await client.ocr.v1.download(job.id, 'text');
    console.log(text);
  }
  ```

  ```python title="Python" theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
  result = client.ocr.v1.retrieve(job.id)

  if result.status == 'completed':
      # Download the extracted text
      text = client.ocr.v1.download(job.id, 'text')
      print(text)
  ```

  ```go title="Go" theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
  result, _ := client.Ocr.V1.Get(ctx, jobID)
  fmt.Println(result.Status)
  ```
</CodeGroup>

## Using webhooks

For large documents, use webhooks instead of polling:

<CodeGroup>
  ```bash title="CLI" theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
  casedev ocr:v1 process \
    --document-url "https://storage.example.com/500-page-discovery.pdf" \
    --callback-url "https://your-app.com/api/ocr-complete"
  ```

  ```typescript title="Typescript" theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
  const job = await client.ocr.v1.process({
    document_url: 'https://storage.example.com/500-page-discovery.pdf',
    callback_url: 'https://your-app.com/api/ocr-complete'
  });
  ```

  ```python title="Python" theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
  job = client.ocr.v1.process(
      document_url='https://storage.example.com/500-page-discovery.pdf',
      callback_url='https://your-app.com/api/ocr-complete'
  )
  ```

  ```go title="Go" theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
  job, _ := client.Ocr.V1.Process(ctx, casedev.OcrV1ProcessParams{
  	DocumentURL: casedev.F("https://storage.example.com/500-page-discovery.pdf"),
  	CallbackURL: casedev.F("https://your-app.com/api/ocr-complete"),
  })
  ```
</CodeGroup>

We POST the completed job to your callback URL when processing finishes.

## S3 URLs

If your document is in S3, use an `s3://` URL:

<CodeGroup>
  ```bash title="CLI" theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
  casedev ocr:v1 process \
    --document-url "s3://your-bucket/documents/deposition.pdf"
  ```

  ```typescript title="Typescript" theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
  const job = await client.ocr.v1.process({
    document_url: 's3://your-bucket/documents/deposition.pdf'
  });
  ```

  ```python title="Python" theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
  job = client.ocr.v1.process(
      document_url='s3://your-bucket/documents/deposition.pdf'
  )
  ```

  ```go title="Go" theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
  job, _ := client.Ocr.V1.Process(ctx, casedev.OcrV1ProcessParams{
  	DocumentURL: casedev.F("s3://your-bucket/documents/deposition.pdf"),
  })
  ```
</CodeGroup>

We automatically generate a presigned URL to access the file.

## Examples

### Scanned deposition

<CodeGroup>
  ```bash title="CLI" theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
  casedev ocr:v1 process \
    --document-url "https://storage.example.com/deposition-smith.pdf" \
    --document-id smith-depo-2024 \
    --engine doctr \
    --features.embed '{}'
  ```

  ```typescript title="Typescript" theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
  const job = await client.ocr.v1.process({
    document_url: 'https://storage.example.com/deposition-smith.pdf',
    document_id: 'smith-depo-2024',
    engine: 'doctr',
    features: { embed: {} }  // Generate searchable PDF
  });
  ```

  ```python title="Python" theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
  job = client.ocr.v1.process(
      document_url='https://storage.example.com/deposition-smith.pdf',
      document_id='smith-depo-2024',
      engine='doctr',
      features={'embed': {}}  # Generate searchable PDF
  )
  ```

  ```go title="Go" theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
  job, _ := client.Ocr.V1.Process(ctx, casedev.OcrV1ProcessParams{
  	DocumentURL: casedev.F("https://storage.example.com/deposition-smith.pdf"),
  	DocumentID:  casedev.F("smith-depo-2024"),
  	Engine:      casedev.F(casedev.OcrV1ProcessParamsEngineDoctr),
  	Features: casedev.F(casedev.OcrV1ProcessParamsFeatures{
  		Embed: casedev.F(casedev.OcrV1ProcessParamsFeaturesEmbed{}),
  	}),
  })
  ```
</CodeGroup>

### Medical records with tables

<CodeGroup>
  ```bash title="CLI" theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
  casedev ocr:v1 process \
    --document-url "https://storage.example.com/patient-records.pdf" \
    --engine paddleocr \
    --features.tables '{"format": "csv"}' \
    --features.embed '{}' \
    --callback-url "https://your-app.com/webhooks/ocr"
  ```

  ```typescript title="Typescript" theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
  const job = await client.ocr.v1.process({
    document_url: 'https://storage.example.com/patient-records.pdf',
    engine: 'paddleocr',  // Better for tables and forms
    features: {
      tables: { format: 'csv' },
      embed: {}
    },
    callback_url: 'https://your-app.com/webhooks/ocr'
  });
  ```

  ```python title="Python" theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
  job = client.ocr.v1.process(
      document_url='https://storage.example.com/patient-records.pdf',
      engine='paddleocr',  # Better for tables and forms
      features={
          'tables': {'format': 'csv'},
          'embed': {}
      },
      callback_url='https://your-app.com/webhooks/ocr'
  )
  ```

  ```go title="Go" theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
  job, _ := client.Ocr.V1.Process(ctx, casedev.OcrV1ProcessParams{
  	DocumentURL: casedev.F("https://storage.example.com/patient-records.pdf"),
  	Engine:      casedev.F(casedev.OcrV1ProcessParamsEnginePaddleocr),
  	Features: casedev.F(casedev.OcrV1ProcessParamsFeatures{
  		Tables: casedev.F(casedev.OcrV1ProcessParamsFeaturesTables{Format: casedev.F("csv")}),
  		Embed:  casedev.F(casedev.OcrV1ProcessParamsFeaturesEmbed{}),
  	}),
  	CallbackURL: casedev.F("https://your-app.com/webhooks/ocr"),
  })
  ```
</CodeGroup>

### Handwritten notes

<CodeGroup>
  ```bash title="CLI" theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
  casedev ocr:v1 process \
    --document-url "https://storage.example.com/witness-notes.jpg" \
    --engine paddleocr
  ```

  ```typescript title="Typescript" theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
  const job = await client.ocr.v1.process({
    document_url: 'https://storage.example.com/witness-notes.jpg',
    engine: 'paddleocr'  // Better for handwriting
  });
  ```

  ```python title="Python" theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
  job = client.ocr.v1.process(
      document_url='https://storage.example.com/witness-notes.jpg',
      engine='paddleocr'  # Better for handwriting
  )
  ```

  ```go title="Go" theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
  job, _ := client.Ocr.V1.Process(ctx, casedev.OcrV1ProcessParams{
  	DocumentURL: casedev.F("https://storage.example.com/witness-notes.jpg"),
  	Engine:      casedev.F(casedev.OcrV1ProcessParamsEnginePaddleocr),
  })
  ```
</CodeGroup>
