> ## Documentation Index
> Fetch the complete documentation index at: https://docs.docintell.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Re-processing Documents

> Re-run extraction on documents with improved models or document type hints

Documents sometimes need to be re-processed. This guide covers when and how to re-extract data from documents that have already been uploaded.

## When to Re-process

You should re-process a document when:

<CardGroup cols={2}>
  <Card title="Classification Issues" icon="question-circle">
    Document was classified as `OTHER` or `unknown` and you want to provide a type hint
  </Card>

  <Card title="Low Confidence" icon="gauge-low">
    Extraction had low confidence scores and you want to retry with explicit hints
  </Card>

  <Card title="Model Improvements" icon="sparkles">
    New extraction models are available and you want better results
  </Card>

  <Card title="Audit Trail" icon="file-search">
    Compare extraction accuracy across multiple runs for quality assurance
  </Card>
</CardGroup>

<Note>
  Re-processing creates a **new extraction job** but uses the **same document** in the Cold Vault.
  You don't need to re-upload the PDF - the original file is immutable and always available.
</Note>

***

## Re-process a Document

Re-process an existing document by creating a new extraction job:

<CodeGroup>
  ```bash cURL theme={null}
  # Basic re-processing (no hint)
  curl -X POST https://api.docintell.com/v1/documents/019370ab-c123-7def-8901-234567890abc/jobs \
    -H "Authorization: Bearer dk_live_YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{}'

  # Re-processing with document type hint
  curl -X POST https://api.docintell.com/v1/documents/019370ab-c123-7def-8901-234567890abc/jobs \
    -H "Authorization: Bearer dk_live_YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "document_type": "capital_call"
    }'
  ```

  ```python Python theme={null}
  import requests

  headers = {
      "Authorization": "Bearer dk_live_YOUR_API_KEY",
      "Content-Type": "application/json"
  }

  document_id = "019370ab-c123-7def-8901-234567890abc"

  # Basic re-processing (no hint)
  response = requests.post(
      f"https://api.docintell.com/v1/documents/{document_id}/jobs",
      headers=headers,
      json={}
  )

  # Re-processing with document type hint
  response = requests.post(
      f"https://api.docintell.com/v1/documents/{document_id}/jobs",
      headers=headers,
      json={"document_type": "capital_call"}
  )

  job_id = response.json()["job_id"]
  print(f"Re-processing job created: {job_id}")
  ```

  ```typescript TypeScript theme={null}
  const documentId = '019370ab-c123-7def-8901-234567890abc';

  // Basic re-processing (no hint)
  const response = await fetch(
    `https://api.docintell.com/v1/documents/${documentId}/jobs`,
    {
      method: 'POST',
      headers: {
        'Authorization': 'Bearer dk_live_YOUR_API_KEY',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({}),
    }
  );

  // Re-processing with document type hint
  const response = await fetch(
    `https://api.docintell.com/v1/documents/${documentId}/jobs`,
    {
      method: 'POST',
      headers: {
        'Authorization': 'Bearer dk_live_YOUR_API_KEY',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        document_type: 'capital_call',
      }),
    }
  );

  const { job_id } = await response.json();
  console.log(`Re-processing job created: ${job_id}`);
  ```

  ```go Go theme={null}
  import (
      "bytes"
      "encoding/json"
      "fmt"
      "net/http"
  )

  type ReprocessRequest struct {
      DocumentType string `json:"document_type,omitempty"`
  }

  documentID := "019370ab-c123-7def-8901-234567890abc"

  // Re-processing with document type hint
  reqBody := ReprocessRequest{
      DocumentType: "capital_call",
  }

  body, _ := json.Marshal(reqBody)
  url := fmt.Sprintf("https://api.docintell.com/v1/documents/%s/jobs", documentID)

  req, _ := http.NewRequest("POST", url, bytes.NewBuffer(body))
  req.Header.Set("Authorization", "Bearer dk_live_YOUR_API_KEY")
  req.Header.Set("Content-Type", "application/json")

  client := &http.Client{}
  resp, _ := client.Do(req)
  ```
</CodeGroup>

**Response** (`202 Accepted`):

```json theme={null}
{
  "document_id": "019370ab-c123-7def-8901-234567890abc",
  "job_id": "019370ab-d456-7def-8901-234567890def",
  "status": "pending",
  "vault_uri": "gs://docintel-vault/019370ab-c123-7def-8901-234567890abc.pdf",
  "created_at": "2024-01-15T14:30:00Z"
}
```

### Deduplication Behavior

DocIntell automatically prevents duplicate jobs for the same document:

* If a `pending` or `processing` job already exists, the **existing job** is returned
* No duplicate extraction jobs are created
* This prevents accidental re-submission from retry logic or double-clicks

<Accordion title="Example: Deduplication Response">
  If you call `POST /v1/documents/{id}/jobs` while a job is already in progress:

  ```json theme={null}
  {
    "document_id": "019370ab-c123-7def-8901-234567890abc",
    "job_id": "019370ab-d456-7def-8901-234567890def",
    "status": "processing",
    "vault_uri": "gs://docintel-vault/019370ab-c123-7def-8901-234567890abc.pdf",
    "created_at": "2024-01-15T14:28:00Z"
  }
  ```

  Notice the `job_id` and `created_at` match the existing job (not a new one).
</Accordion>

### Supported Document Types

You can provide a `document_type` hint to improve classification accuracy:

| Type                     | Description                  |
| ------------------------ | ---------------------------- |
| `capital_call`           | Capital call notices         |
| `distribution`           | Distribution notices         |
| `k1`                     | K-1 tax forms                |
| `nav_statement`          | NAV statements               |
| `audited_financial`      | Audited financial statements |
| `invoice`                | Commercial invoices          |
| `trade_confirmation`     | Trade confirmations          |
| `wire_confirmation`      | Wire transfer confirmations  |
| `subscription_agreement` | Subscription agreements      |
| `insurance`              | Insurance documents          |
| `investor_letter`        | Investor letters             |
| `unknown`                | Let the system auto-classify |

<Tip>
  If you're unsure of the document type, omit `document_type` entirely. The extraction engine
  will auto-classify the document based on its content.
</Tip>

***

## View Job History

List all extraction attempts for a document to see the full re-processing history:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET https://api.docintell.com/v1/documents/019370ab-c123-7def-8901-234567890abc/jobs \
    -H "Authorization: Bearer dk_live_YOUR_API_KEY"
  ```

  ```python Python theme={null}
  import requests

  headers = {
      "Authorization": "Bearer dk_live_YOUR_API_KEY"
  }

  document_id = "019370ab-c123-7def-8901-234567890abc"

  response = requests.get(
      f"https://api.docintell.com/v1/documents/{document_id}/jobs",
      headers=headers
  )

  jobs = response.json()["jobs"]
  print(f"Found {len(jobs)} extraction attempts")
  ```

  ```typescript TypeScript theme={null}
  const documentId = '019370ab-c123-7def-8901-234567890abc';

  const response = await fetch(
    `https://api.docintell.com/v1/documents/${documentId}/jobs`,
    {
      headers: {
        'Authorization': 'Bearer dk_live_YOUR_API_KEY',
      },
    }
  );

  const { jobs } = await response.json();
  console.log(`Found ${jobs.length} extraction attempts`);
  ```
</CodeGroup>

**Response:**

```json theme={null}
{
  "jobs": [
    {
      "job_id": "019370ab-d456-7def-8901-234567890def",
      "document_id": "019370ab-c123-7def-8901-234567890abc",
      "status": "completed",
      "created_at": "2024-01-15T14:30:00Z",
      "processing_completed_at": "2024-01-15T14:30:45Z",
      "processing_time_seconds": 45.2
    },
    {
      "job_id": "019370ab-d123-7def-8901-234567890abc",
      "document_id": "019370ab-c123-7def-8901-234567890abc",
      "status": "completed",
      "created_at": "2024-01-15T10:00:00Z",
      "processing_completed_at": "2024-01-15T10:00:52Z",
      "processing_time_seconds": 52.1
    }
  ],
  "total": 2,
  "page": 1,
  "per_page": 20
}
```

### Pagination

Job history supports pagination for documents with many re-processing attempts:

```bash theme={null}
# Get page 2 with 10 items per page
curl -X GET "https://api.docintell.com/v1/documents/019370ab-c123-7def-8901-234567890abc/jobs?page=2&per_page=10" \
  -H "Authorization: Bearer dk_live_YOUR_API_KEY"
```

| Parameter  | Type    | Default | Description              |
| ---------- | ------- | ------- | ------------------------ |
| `page`     | integer | `1`     | Page number (1-indexed)  |
| `per_page` | integer | `20`    | Items per page (max 100) |

<Note>
  Jobs are ordered **newest first**. The first item (page 1, index 0) is always the most recent extraction attempt.
</Note>

***

## Common Re-processing Scenarios

### Scenario 1: Document Classified as OTHER

Your document was uploaded but classified as `OTHER` or `unknown`:

<Steps>
  <Step title="Check the current classification">
    ```bash theme={null}
    curl -X GET https://api.docintell.com/v1/jobs/019370ab-d123-7def-8901-234567890abc \
      -H "Authorization: Bearer dk_live_YOUR_API_KEY"
    ```

    Response shows:

    ```json theme={null}
    {
      "document_type": "unknown",
      "classification_reasoning": "Unable to classify document"
    }
    ```
  </Step>

  <Step title="Re-process with document type hint">
    ```bash theme={null}
    curl -X POST https://api.docintell.com/v1/documents/019370ab-c123-7def-8901-234567890abc/jobs \
      -H "Authorization: Bearer dk_live_YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"document_type": "capital_call"}'
    ```
  </Step>

  <Step title="Compare results">
    Retrieve both jobs and compare extraction quality:

    ```bash theme={null}
    # Original job (auto-classified as unknown)
    curl -X GET https://api.docintell.com/v1/jobs/019370ab-d123-7def-8901-234567890abc/results \
      -H "Authorization: Bearer dk_live_YOUR_API_KEY"

    # New job (with capital_call hint)
    curl -X GET https://api.docintell.com/v1/jobs/019370ab-d456-7def-8901-234567890def/results \
      -H "Authorization: Bearer dk_live_YOUR_API_KEY"
    ```
  </Step>
</Steps>

### Scenario 2: Low Confidence Extraction

Initial extraction had low confidence scores for critical fields:

<Steps>
  <Step title="Review confidence scores">
    ```bash theme={null}
    curl -X GET https://api.docintell.com/v1/jobs/019370ab-d123-7def-8901-234567890abc/results \
      -H "Authorization: Bearer dk_live_YOUR_API_KEY"
    ```

    Response shows low confidence:

    ```json theme={null}
    {
      "extraction": {
        "data": {
          "total_amount": 50000.00,
          "due_date": "2024-02-01"
        },
        "field_metadata": {
          "total_amount": {
            "confidence": 0.45,
            "reasoning": "Ambiguous - multiple dollar amounts found"
          }
        }
      }
    }
    ```
  </Step>

  <Step title="Re-process with correct document type">
    Providing the correct document type often improves confidence:

    ```bash theme={null}
    curl -X POST https://api.docintell.com/v1/documents/019370ab-c123-7def-8901-234567890abc/jobs \
      -H "Authorization: Bearer dk_live_YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"document_type": "invoice"}'
    ```
  </Step>

  <Step title="Verify improved confidence">
    ```json theme={null}
    {
      "extraction": {
        "data": {
          "total_amount": 50000.00,
          "due_date": "2024-02-01"
        },
        "field_metadata": {
          "total_amount": {
            "confidence": 0.92,
            "reasoning": "Found in 'Total Amount Due' section"
          }
        }
      }
    }
    ```
  </Step>
</Steps>

<Warning>
  **Confidence scores are self-reported by the LLM** and are directionally useful but not calibrated.
  A 90% confidence score does NOT mean 90% accuracy. Use scores for relative comparison between fields,
  not as absolute probabilities.
</Warning>

### Scenario 3: Comparing Extraction Runs

Track extraction accuracy improvements over time:

```python theme={null}
import requests

headers = {"Authorization": "Bearer dk_live_YOUR_API_KEY"}
document_id = "019370ab-c123-7def-8901-234567890abc"

# Get all jobs for the document
jobs_response = requests.get(
    f"https://api.docintell.com/v1/documents/{document_id}/jobs",
    headers=headers
)
jobs = jobs_response.json()["jobs"]

# Compare results across all jobs
for job in jobs:
    if job["status"] == "completed":
        results = requests.get(
            f"https://api.docintell.com/v1/jobs/{job['job_id']}/results",
            headers=headers
        ).json()

        print(f"Job {job['job_id']}:")
        print(f"  Created: {job['created_at']}")
        print(f"  Type: {results['classification']['document_type']}")
        print(f"  Confidence: {results['classification']['confidence']}")
        print(f"  Processing Time: {job['processing_time_seconds']}s")
        print()
```

***

## Best Practices

<CardGroup cols={2}>
  <Card title="Don't Re-process Pending Jobs" icon="clock">
    **Why:** Deduplication prevents duplicate jobs, but checking status first avoids unnecessary API calls.

    ```python theme={null}
    # Check status before re-processing
    status = requests.get(
        f"https://api.docintell.com/v1/documents/{document_id}/status",
        headers=headers
    ).json()

    if status["status"] in ["pending", "processing"]:
        print("Job already in progress")
    else:
        # Safe to re-process
        requests.post(...)
    ```
  </Card>

  <Card title="Use Webhooks for Completion" icon="webhook">
    **Why:** Polling for job completion wastes API quota and adds latency.

    Set up webhooks once and receive notifications for all jobs:

    ```bash theme={null}
    curl -X POST https://api.docintell.com/v1/webhooks \
      -H "Authorization: Bearer dk_live_YOUR_API_KEY" \
      -d '{
        "url": "https://yourapp.com/webhooks/docintel",
        "events": ["document.processing.completed"]
      }'
    ```
  </Card>

  <Card title="Track Job IDs for Comparison" icon="database">
    **Why:** Each extraction creates a unique `job_id`. Track them to compare results.

    ```python theme={null}
    job_mapping = {
        "original": "019370ab-d123-7def-8901-234567890abc",
        "with_hint": "019370ab-d456-7def-8901-234567890def"
    }

    # Compare confidence scores
    for label, job_id in job_mapping.items():
        results = get_job_results(job_id)
        print(f"{label}: {results['classification']['confidence']}")
    ```
  </Card>

  <Card title="Use Meaningful Document Type Hints" icon="lightbulb">
    **Why:** Type hints significantly improve extraction accuracy for known document types.

    <Check>
      **DO:** Provide `document_type` if you know the document type
    </Check>

    <Check>
      **DON'T:** Use `"unknown"` as a hint - omit `document_type` instead
    </Check>
  </Card>
</CardGroup>

***

## Rate Limiting

Re-processing is subject to the **document ingestion rate limit**: **100 documents/hour** per tenant.

Rate limit headers are returned in responses:

```
HTTP/1.1 202 Accepted
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1705329600
```

<Warning>
  If you exceed the rate limit, you'll receive a `429 Too Many Requests` error:

  ```json theme={null}
  {
    "error": "rate_limit_exceeded",
    "message": "Document ingestion rate limit exceeded (100 documents/hour)",
    "details": {
      "limit": 100,
      "remaining": 0,
      "reset_at": "2024-01-15T15:00:00Z"
    }
  }
  ```
</Warning>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Job Status" icon="chart-line" href="/api-reference/jobs/get-job">
    Monitor extraction job progress
  </Card>

  <Card title="Extraction Results" icon="file-chart-column" href="/api-reference/jobs/get-job-results">
    Retrieve full extraction data with metadata
  </Card>

  <Card title="Webhook Setup" icon="webhook" href="/guides/webhook-setup">
    Get real-time notifications for job completion
  </Card>

  <Card title="Error Handling" icon="triangle-exclamation" href="/guides/error-handling">
    Handle extraction failures gracefully
  </Card>
</CardGroup>
