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

# Quickstart

> Extract structured data from a document in under 5 minutes

## 1. Get an API key

Sign up at [dev.thedrive.ai](https://dev.thedrive.ai) and create an API key from the dashboard. Free tier includes 100 credits/month.

## 2. Install the SDK

<CodeGroup>
  ```bash Python theme={null}
  pip install thedriveai
  ```

  ```bash TypeScript theme={null}
  npm install @thedriveai/sdk
  ```
</CodeGroup>

## 3. Extract data

<CodeGroup>
  ```python Python theme={null}
  from thedriveai import TheDriveAI

  client = TheDriveAI(api_key="tda_live_...")

  result = client.extract(
      file="invoice.pdf",
      schema={
          "invoice_number": {"type": "string", "description": "The invoice number"},
          "vendor": {"type": "string", "description": "Company name"},
          "total": {"type": "number", "description": "Total amount due"},
          "is_paid": {"type": "boolean", "description": "Whether the invoice is marked as paid"},
      },
  )

  print(result.data)
  # {"invoice_number": "INV-2024-0042", "vendor": "Acme Corp", "total": 1234.56, "is_paid": false}

  print(result.confidence)
  # {"invoice_number": 0.96, "vendor": 0.94, "total": 0.91, "is_paid": 0.85}
  ```

  ```typescript TypeScript theme={null}
  import { TheDriveAI } from "@thedriveai/sdk";
  import { readFileSync } from "fs";

  const client = new TheDriveAI({ apiKey: "tda_live_..." });

  const result = await client.extract({
    file: readFileSync("invoice.pdf"),
    schema: {
      invoice_number: { type: "string", description: "The invoice number" },
      vendor: { type: "string", description: "Company name" },
      total: { type: "number", description: "Total amount due" },
      is_paid: { type: "boolean", description: "Whether the invoice is marked as paid" },
    },
  });

  console.log(result.data);
  // { invoice_number: "INV-2024-0042", vendor: "Acme Corp", total: 1234.56, is_paid: false }
  ```

  ```bash cURL theme={null}
  curl -X POST https://dev.thedrive.ai/api/v1/extract \
    -H "X-API-Key: tda_live_..." \
    -F file=@invoice.pdf \
    -F 'schema={
      "invoice_number": {"type": "string", "description": "The invoice number"},
      "vendor": {"type": "string", "description": "Company name"},
      "total": {"type": "number", "description": "Total amount due"}
    }'
  ```
</CodeGroup>

## 4. Or use Pydantic / Zod

Instead of writing raw JSON schemas, use the tools you already know.

<CodeGroup>
  ```python Pydantic theme={null}
  from pydantic import BaseModel, Field
  from thedriveai import TheDriveAI

  class Invoice(BaseModel):
      invoice_number: str = Field(description="The invoice number")
      vendor: str = Field(description="Company name")
      total: float = Field(description="Total amount due")
      is_paid: bool = Field(description="Whether the invoice is marked as paid")

  client = TheDriveAI(api_key="tda_live_...")
  result = client.extract(file="invoice.pdf", schema=Invoice)

  print(result.data["vendor"])  # "Acme Corp"
  print(result.data["total"])   # 1234.56
  ```

  ```typescript Zod theme={null}
  import { TheDriveAI, fromZod } from "@thedriveai/sdk";
  import { readFileSync } from "fs";
  import { z } from "zod";

  const Invoice = z.object({
    invoice_number: z.string().describe("The invoice number"),
    vendor: z.string().describe("Company name"),
    total: z.number().describe("Total amount due"),
    is_paid: z.boolean().describe("Whether the invoice is marked as paid"),
  });

  const client = new TheDriveAI({ apiKey: "tda_live_..." });
  const result = await client.extract({
    file: readFileSync("invoice.pdf"),
    schema: fromZod(Invoice),
  });

  console.log(result.data.vendor); // "Acme Corp"
  console.log(result.data.total);  // 1234.56
  ```
</CodeGroup>

Both approaches support nested objects, arrays, enums, and optional fields. See [Schemas](/developer/schemas) for the full reference.

## 5. Extract from a URL

You can pass a URL instead of uploading a file. Works with any public URL — the API renders JavaScript-heavy pages with a headless browser.

<CodeGroup>
  ```python Python theme={null}
  result = client.extract(
      url="https://example.com/pricing",
      schema={
          "plans": {
              "type": "array",
              "description": "Available pricing plans",
              "items": {
                  "type": "object",
                  "properties": {
                      "name": {"type": "string", "description": "Plan name"},
                      "price": {"type": "number", "description": "Monthly price"},
                  }
              }
          }
      },
  )
  ```

  ```typescript TypeScript theme={null}
  const result = await client.extract({
    url: "https://example.com/pricing",
    schema: {
      plans: {
        type: "array",
        description: "Available pricing plans",
        items: {
          type: "object",
          properties: {
            name: { type: "string", description: "Plan name" },
            price: { type: "number", description: "Monthly price" },
          },
        },
      },
    },
  });
  ```
</CodeGroup>

## What's in the response

Every extraction returns:

| Field          | Description                                          |
| -------------- | ---------------------------------------------------- |
| `data`         | Extracted values, type-enforced to match your schema |
| `confidence`   | Per-field confidence scores (0.0 - 1.0)              |
| `citations`    | Per-field source text snippets from the document     |
| `field_status` | Per-field found/not\_found status with type info     |
| `credits_used` | Credits consumed for this request                    |

## Error handling

<CodeGroup>
  ```python Python theme={null}
  from thedriveai import TheDriveAI, TheDriveAIError

  try:
      result = client.extract(file="doc.pdf", schema={...})
  except TheDriveAIError as e:
      print(e.status_code)  # 400, 413, 503, etc.
      print(e.detail)       # Error detail from the API
  ```

  ```typescript TypeScript theme={null}
  import { TheDriveAI, TheDriveAIError } from "@thedriveai/sdk";

  try {
    const result = await client.extract({...});
  } catch (e) {
    if (e instanceof TheDriveAIError) {
      console.log(e.statusCode); // 400, 413, 503, etc.
      console.log(e.detail);     // Error detail from the API
    }
  }
  ```
</CodeGroup>

| Status | Meaning                                          |
| ------ | ------------------------------------------------ |
| `400`  | Invalid schema, missing file/URL, or bad request |
| `401`  | Missing or invalid API key                       |
| `413`  | File too large (max 50 MB)                       |
| `503`  | AI service temporarily unavailable               |

## What's next

<CardGroup cols={2}>
  <Card title="Analyze" icon="magnifying-glass-chart" href="/developer/analyze">
    Compute and reason over documents — sums, comparisons, risk assessments.
  </Card>

  <Card title="Cross-Analyze" icon="code-compare" href="/developer/cross-analyze">
    Validate an invoice against a contract, reconcile spreadsheets, compare agreements.
  </Card>

  <Card title="Schemas" icon="brackets-curly" href="/developer/schemas">
    Full type reference — arrays, nested objects, enums, required fields, Pydantic, Zod.
  </Card>

  <Card title="Async & Webhooks" icon="webhook" href="/developer/webhooks">
    Process documents asynchronously with webhook notifications.
  </Card>
</CardGroup>
