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

# Developer Quickstart

> Get started in 2 minutes

Follow these steps to set up your account and integrate with our API.

<Steps>
  <Step title="Sign Up and Create an API Key">
    1. Visit [Chunkr AI](https://chunkr.ai)
    2. Click on "Login" and create your account
    3. Once logged in, navigate to "API Keys" in the dashboard
  </Step>

  <Step title="Install our client SDK">
    <Warning>
      The Python SDK is currently in alpha. The `--pre` flag is required to install pre-release versions.
    </Warning>

    <CodeGroup>
      ```bash Python theme={"system"}
      pip install --pre chunkr-ai
      ```

      ```bash TypeScript theme={"system"}
      npm install chunkr-ai
      ```
    </CodeGroup>
  </Step>

  <Step title="Parse a document">
    <CodeGroup>
      ```python Python theme={"system"}
      import os
      import time

      from chunkr_ai import Chunkr
      from pydantic import BaseModel

      # Initialize the client
      client = Chunkr(api_key=os.environ["CHUNKR_API_KEY"])

      # Create a parse task using a file URL
      parse_task = client.tasks.parse.create(
          file="https://s3.us-east-1.amazonaws.com/chunkr-web/uploads/invoice.pdf"
      )

      # Alternatively, upload a local file first
      # with open('path/to/doc.pdf', 'rb') as f:
      #     uploaded = client.files.create(file=f)
      # parse_task = client.tasks.parse.create(file=uploaded.url)

      # Wait for parse task to complete
      while not parse_task.completed:
          parse_task = client.tasks.parse.get(task_id=parse_task.task_id)
          print(f"Parse Status: {parse_task.status}")
          time.sleep(3)

      if parse_task.status == "Succeeded":
          # Do something with the output
          pass
      else:  # Could be "Failed" or "Cancelled"
          print(f"Parse Status: {parse_task.status}")
      ```

      ```typescript TypeScript theme={"system"}
      import Chunkr from "chunkr-ai";
      import fs from "fs";
      import * as z from "zod";

      // Initialize the client
      const client = new Chunkr({ apiKey: process.env.CHUNKR_API_KEY! });

      // Create a parse task using a file URL
      let parseTask = await client.tasks.parse.create({
          file: "https://s3.us-east-1.amazonaws.com/chunkr-web/uploads/invoice.pdf",
      });

      // Alternatively, upload a local file first
      // const fileStream = fs.createReadStream("path/to/doc.pdf");
      // const uploaded = await client.files.create({
      //   file: fileStream,
      //   file_metadata: JSON.stringify({ name: "doc.pdf", type: "application/pdf" }),
      // });
      // let parseTask = await client.tasks.parse.create({ file: uploaded.url });

      // Wait for parse task to complete
      while (!parseTask.completed) {
          parseTask = await client.tasks.parse.get(parseTask.task_id);
          console.log(`Parse Status: ${parseTask.status}`);
          await new Promise((resolve) => setTimeout(resolve, 3000));
      }

      if (parseTask.status === "Succeeded") {
          // Do something with the output
      } else { // Could be "Failed" or "Cancelled"
          console.log(`Parse Status: ${parseTask.status}`);
      }
      ```
    </CodeGroup>
  </Step>

  <Step title="Extract structured data">
    <CodeGroup>
      ```python Python theme={"system"}
      class Invoice(BaseModel):
          invoice_number: str
          invoice_date: str
          total_amount: float

      # Use the parse task ID to create an extract task
      extract_task = client.tasks.extract.create(
          file=parse_task.task_id,
          schema=Invoice.model_json_schema() # Convert Pydantic model to JSON schema
      )

      # Wait for extract task to complete
      while not extract_task.completed:
          extract_task = client.tasks.extract.get(task_id=extract_task.task_id)
          print(f"Extract Status: {extract_task.status}")
          time.sleep(3)
      ```

      ```typescript TypeScript theme={"system"}
      const Invoice = z.object({
          invoice_number: z.string().min(1),
          invoice_date: z.string().min(1),
          total_amount: z.number().min(1),
      });

      let extractTask = await client.tasks.extract.create({
          file: parseTask.task_id,
          schema: z.toJSONSchema(Invoice), // Convert Zod schema to JSON schema
      });

      // Wait for extract task to complete
      while (!extractTask.completed) {
          extractTask = await client.tasks.extract.get(extractTask.task_id);
          console.log(`Extract Status: ${extractTask.status}`);
          await new Promise((resolve) => setTimeout(resolve, 3000));
      }
      ```
    </CodeGroup>
  </Step>

  <Step title="Explore Output">
    <CodeGroup>
      ```python Python theme={"system"}
      # Get parse results and print first 5 chunk contents
      if parse_task.output is not None:
          for chunk in parse_task.output.chunks[:5]:
              if chunk.content is not None:
                  print(chunk.content[:200])

      # Get extract results and print schema fields
      if extract_task.status == "Succeeded" and extract_task.output is not None:
          # Validate the results against the schema
          invoice = Invoice.model_validate(extract_task.output.results)
          # Do something with the invoice
          print(invoice)
      ```

      ```typescript TypeScript theme={"system"}
      // Get parse results and print first 5 chunk contents
      if (parseTask.output) {
          for (const chunk of parseTask.output?.chunks.slice(0, 5)) {
              console.log(chunk.content?.slice(0, 200));
          }
      }

      // Get extract results and print schema fields
      if (extractTask.status === "Succeeded" && extractTask.output) {
          const invoice = Invoice.parse(extractTask.output?.results);
          // Do something with the invoice
          console.log(invoice);
      }
      ```
    </CodeGroup>

    You can also explore the output [through our web interface](/pages/get-started/web-interface) in more detail.
  </Step>
</Steps>

<Accordion title="Full example (copy-paste)">
  <CodeGroup>
    ```python Python theme={"system"}
    import os
    import time

    from chunkr_ai import Chunkr
    from pydantic import BaseModel

    # Initialize the client
    client = Chunkr(api_key=os.environ["CHUNKR_API_KEY"])

    # Create a parse task using a file URL
    parse_task = client.tasks.parse.create(
        file="https://s3.us-east-1.amazonaws.com/chunkr-web/uploads/invoice.pdf"
    )

    # Alternatively, upload a local file first
    # with open('path/to/doc.pdf', 'rb') as f:
    #     uploaded = client.files.create(file=f)
    # parse_task = client.tasks.parse.create(file=uploaded.url)

    # Wait for parse task to complete
    while not parse_task.completed:
        parse_task = client.tasks.parse.get(task_id=parse_task.task_id)
        print(f"Parse Status: {parse_task.status}")
        time.sleep(3)

    if parse_task.status == "Succeeded":
        # Do something with the output
        pass
    else: # Could be "Failed" or "Cancelled"
        print(f"Parse Status: {parse_task.status}")

    class Invoice(BaseModel):
        invoice_number: str
        invoice_date: str
        total_amount: float


    extract_task = client.tasks.extract.create(
        file=parse_task.task_id,
        schema=Invoice.model_json_schema() # Convert Pydantic model to JSON schema
    )

    # Wait for extract task to complete
    while not extract_task.completed:
        extract_task = client.tasks.extract.get(task_id=extract_task.task_id)
        print(f"Extract Status: {extract_task.status}")
        time.sleep(3)

    # Get parse results and print first 5 chunk contents
    if parse_task.output is not None:
        for chunk in parse_task.output.chunks[:5]:
            if chunk.content is not None:
                print(chunk.content[:200])

    # Get extract results and print schema fields
    if extract_task.status == "Succeeded" and extract_task.output is not None:
        invoice = Invoice.model_validate(extract_task.output.results)
        # Do something with the invoice
        print(invoice)
    ```

    ```typescript TypeScript theme={"system"}
    import Chunkr from "chunkr-ai";
    import fs from "fs";
    import * as z from "zod";

    // Initialize the client
    const client = new Chunkr({ apiKey: process.env.CHUNKR_API_KEY! });

    // Create a parse task using a file URL
    let parseTask = await client.tasks.parse.create({
        file: "https://s3.us-east-1.amazonaws.com/chunkr-web/uploads/invoice.pdf",
    });

    // Alternatively, upload a local file first
    // const fileStream = fs.createReadStream("path/to/doc.pdf");
    // const uploaded = await client.files.create({
    //   file: fileStream,
    //   file_metadata: JSON.stringify({ name: "doc.pdf", type: "application/pdf" }),
    // });
    // let parseTask = await client.tasks.parse.create({ file: uploaded.url });

    // Wait for parse task to complete
    while (!parseTask.completed) {
        parseTask = await client.tasks.parse.get(parseTask.task_id);
        console.log(`Parse Status: ${parseTask.status}`);
        await new Promise((resolve) => setTimeout(resolve, 3000));
    }

    if (parseTask.status === "Succeeded") {
        // Do something with the output
    } else { // Could be "Failed" or "Cancelled"
        console.log(`Parse Status: ${parseTask.status}`);
    }

    const Invoice = z.object({
        invoice_number: z.string().min(1),
        invoice_date: z.string().min(1),
        total_amount: z.number().min(1),
    });

    let extractTask = await client.tasks.extract.create({
        file: parseTask.task_id,
        schema: z.toJSONSchema(Invoice), // Convert Zod schema to JSON schema
    });

    // Wait for extract task to complete
    while (!extractTask.completed) {
        extractTask = await client.tasks.extract.get(extractTask.task_id);
        console.log(`Extract Status: ${extractTask.status}`);
        await new Promise((resolve) => setTimeout(resolve, 3000));
    }

    // Get parse results and print first 5 chunk contents
    if (parseTask.output) {
        for (const chunk of parseTask.output?.chunks.slice(0, 5)) {
            console.log(chunk.content?.slice(0, 200));
        }
    }

    // Get extract results and print schema fields
    if (extractTask.status === "Succeeded" && extractTask.output) {
        const invoice = Invoice.parse(extractTask.output?.results);
        // Do something with the invoice
        console.log(invoice);
    }
    ```
  </CodeGroup>
</Accordion>

## Next Steps

Get to production with our task system and webhooks.

<Columns cols={2}>
  <Card title="Task Handling" href="/pages/task-system/task-handling" icon="upload">
    Learn how to handle tasks in production.
  </Card>

  <Card title="Webhooks" href="/pages/task-system/webhooks/overview" icon="bell">
    Receive real-time notifications.
  </Card>
</Columns>
