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

# Quickstart

> Your first document extraction in 5 minutes

Get your first document extracted in 5 minutes. This guide walks you through obtaining an API key and uploading a document.

## Integration Overview

```mermaid theme={null}
flowchart LR
    A[Get API Key] --> B[Upload PDF]
    B --> C[Wait for Processing]
    C --> D[Extraction Complete]
```

## Prerequisites

* A DocIntell account ([sign up here](https://app.docintell.com))
* A PDF document to extract (or use our sample invoice)
* `curl` or your favorite HTTP client

## Step 1: Get Your API Key

<Steps>
  <Step title="Log in to Dashboard">
    Go to [app.docintell.com](https://app.docintell.com) and sign in.
  </Step>

  <Step title="Navigate to API Keys">
    Click **Settings** → **API Keys** in the sidebar.
  </Step>

  <Step title="Create a New Key">
    Click **Create API Key**, give it a name (e.g., "Development"), and select the environment:

    * **Live** (`dk_live_...`) — Production use
    * **Test** (`dk_test_...`) — Development and testing
  </Step>

  <Step title="Copy Your Key">
    <Warning>Your API key is only shown once! Copy it now and store it securely.</Warning>
  </Step>
</Steps>

## Step 2: Ingest a Document

Upload your first PDF to DocIntell. The API accepts documents up to 100MB.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.docintell.com/v1/documents \
    -H "Authorization: Bearer dk_live_YOUR_API_KEY" \
    -F "file=@invoice.pdf" \
    -F "retention_years=7"
  ```

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

  response = requests.post(
      "https://api.docintell.com/v1/documents",
      headers={"Authorization": "Bearer dk_live_YOUR_API_KEY"},
      files={"file": open("invoice.pdf", "rb")},
      data={"retention_years": 7}
  )

  result = response.json()
  print(f"Document ID: {result['document_id']}")
  print(f"Job ID: {result['job_id']}")
  print(f"Status: {result['status']}")
  ```

  ```typescript TypeScript theme={null}
  const formData = new FormData();
  formData.append('file', fs.createReadStream('invoice.pdf'));
  formData.append('retention_years', '7');

  const response = await fetch('https://api.docintell.com/v1/documents', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer dk_live_YOUR_API_KEY',
    },
    body: formData,
  });

  const result = await response.json();
  console.log(`Document ID: ${result.document_id}`);
  console.log(`Job ID: ${result.job_id}`);
  ```
</CodeGroup>

**Response (202 Accepted):**

```json theme={null}
{
  "document_id": "019370ab-c123-7def-8901-234567890abc",
  "job_id": "019370ab-c456-7def-8901-234567890def",
  "status": "pending",
  "vault_uri": "gs://docintell-vault/tenant-xxx/2025/019370ab.pdf",
  "created_at": "2025-12-03T10:30:00Z"
}
```

<Note>
  The `202 Accepted` response means your document is queued for processing.
  Extraction typically completes in under 60 seconds for a 50-page document.
</Note>

## Step 3: Check Job Status

Poll the job status until extraction completes:

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

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

  job_id = "019370ab-c456-7def-8901-234567890def"

  while True:
      response = requests.get(
          f"https://api.docintell.com/v1/jobs/{job_id}",
          headers={"Authorization": "Bearer dk_live_YOUR_API_KEY"}
      )
      job = response.json()

      if job["status"] == "completed":
          print("Extraction complete!")
          break
      elif job["status"] == "failed":
          print(f"Extraction failed: {job.get('error_message')}")
          break

      print(f"Status: {job['status']}... waiting")
      time.sleep(2)
  ```

  ```typescript TypeScript theme={null}
  const jobId = '019370ab-c456-7def-8901-234567890def';

  const pollStatus = async () => {
    while (true) {
      const response = await fetch(
        `https://api.docintell.com/v1/jobs/${jobId}`,
        { headers: { 'Authorization': 'Bearer dk_live_YOUR_API_KEY' } }
      );
      const job = await response.json();

      if (job.status === 'completed') {
        console.log('Extraction complete!');
        return job;
      }
      if (job.status === 'failed') {
        throw new Error(job.error_message);
      }

      await new Promise(r => setTimeout(r, 2000));
    }
  };
  ```
</CodeGroup>

**Response (completed):**

```json theme={null}
{
  "job_id": "019370ab-c456-7def-8901-234567890def",
  "document_id": "019370ab-c123-7def-8901-234567890abc",
  "status": "completed",
  "created_at": "2025-12-03T10:30:00Z",
  "processing_completed_at": "2025-12-03T10:30:45Z",
  "processing_time_seconds": 45.2
}
```

<Tip>
  **Pro tip:** Use [webhooks](/concepts/webhooks) instead of polling for production workloads.
  DocIntell will POST to your endpoint when extraction completes.
</Tip>

<Check>
  **Congratulations!** You've successfully uploaded your first document for extraction.
</Check>

## What's Next?

<CardGroup cols={2}>
  <Card title="Webhooks" icon="webhook" href="/guides/webhook-setup">
    Set up real-time notifications
  </Card>

  <Card title="Error Handling" icon="bug" href="/guides/error-handling">
    Handle errors gracefully
  </Card>

  <Card title="API Reference" icon="code" href="/api-reference/introduction">
    Complete API documentation
  </Card>
</CardGroup>

## Common Issues

<AccordionGroup>
  <Accordion title="401 Unauthorized">
    Check that your API key is correct and included in the `Authorization` header with the `Bearer ` prefix.
  </Accordion>

  <Accordion title="400 Invalid file type">
    Only PDF files are supported. Ensure your file has a `.pdf` extension and correct MIME type.
  </Accordion>

  <Accordion title="413 File too large">
    Maximum file size is 100MB. For larger documents, consider splitting them.
  </Accordion>

  <Accordion title="429 Rate limit exceeded">
    You've exceeded the rate limit. Check the `Retry-After` header and try again later.
  </Accordion>
</AccordionGroup>
