---
title: Getting Started | Developer Documentation
description: Guide on how to use the LlamaExtract SDK for programmatic data extraction, including schema definition and batch processing.
---

For a more programmatic approach, the SDK is the recommended way to experiment with different schemas and run extractions at scale.

Note

The examples below use the **v2** Extract SDK (`llama-cloud`). If you need to use **Extract v1**, switch to the v1 documentation using the toggle at the top of the left sidebar.

You can visit the Github repo for the [Python SDK](https://github.com/run-llama/llama-cloud-py) or the [Typescript SDK](https://github.com/run-llama/llama-cloud-ts).

First, [get an api key](../../general/api_key). You can export it as an environment variable for easy access or pass it directly to clients later.

Terminal window

```
export LLAMA_CLOUD_API_KEY=llx-xxxxxx
```

Then, install dependencies:

- [Python](#tab-panel-589)
- [TypeScript](#tab-panel-590)
- [Go](#tab-panel-591)
- [Java](#tab-panel-592)
- [CLI](#tab-panel-593)

Terminal window

```
pip install llama-cloud>=2.8
```

Terminal window

```
npm install @llamaindex/llama-cloud zod
```

Terminal window

```
go get github.com/run-llama/llama-parse-go
```

```
implementation("ai.llamaindex:llama-cloud:1.3.0")
```

Terminal window

```
go install github.com/run-llama/llama-parse-cli/cmd/llp@latest
```

Now we have our libraries and our API key available, let’s create a script file and extract data from files. In this case, we’re using some sample [resumes](https://github.com/run-llama/llama_cloud_services/tree/main/examples/extract/data) from our example:

## Quick Start

- [Python](#tab-panel-594)
- [TypeScript](#tab-panel-595)
- [Go](#tab-panel-596)
- [Java](#tab-panel-597)
- [CLI](#tab-panel-598)

```
import time
from pydantic import BaseModel, Field
from llama_cloud import LlamaCloud


# Define schema using Pydantic
class Resume(BaseModel):
    name: str = Field(description="Full name of candidate")
    email: str = Field(description="Email address")
    skills: list[str] = Field(description="Technical skills and technologies")


client = LlamaCloud(api_key="your_api_key")


# Upload a file to extract from
file_obj = client.files.create(file="resume.pdf", purpose="extract")


# Extract data from document
job = client.extract.create(
    file_input=file_obj.id,
    configuration={
        "data_schema": Resume.model_json_schema(),
        "extraction_target": "per_doc",
        "tier": "agentic",
    },
)


# Poll for completion
while job.status not in ("COMPLETED", "FAILED", "CANCELLED"):
    time.sleep(2)
    job = client.extract.get(job.id)


print(job.extract_result)
```

```
import fs from 'fs';
import { z } from 'zod';
import LlamaCloud from '@llamaindex/llama-cloud';


// Define schema using Zod
const ResumeSchema = z.object({
    name: z.string().describe("Full name of candidate"),
    email: z.string().describe("Email address"),
    skills: z.array(z.string()).describe("Technical skills and technologies"),
});


const client = new LlamaCloud({
  apiKey: 'your_api_key',
});


// Upload a file to extract from
const fileObj = await client.files.create({
  file: fs.createReadStream('resume.pdf'),
  purpose: 'extract',
});


// Extract data from document
let job = await client.extract.create({
  file_input: fileObj.id,
  configuration: {
      data_schema: z.toJSONSchema(ResumeSchema),
      extraction_target: 'per_doc',
      tier: 'agentic',
  },
});


// Poll for completion
while (!['COMPLETED', 'FAILED', 'CANCELLED'].includes(job.status)) {
  await new Promise((r) => setTimeout(r, 2000));
  job = await client.extract.get(job.id);
}


console.log(job.extract_result);
```

```
package main


import (
    "context"
    "fmt"
    "log"
    "os"
    "time"


    llamacloud "github.com/run-llama/llama-parse-go"
)


func main() {
    ctx := context.Background()
    client := llamacloud.NewClient()


    // Define schema as a JSON Schema literal
    dataSchema := map[string]*llamacloud.ExtractConfigurationDataSchemaUnionParam{
        "type": {OfString: llamacloud.String("object")},
        "properties": {OfAnyMap: map[string]any{
            "name":  map[string]any{"type": "string", "description": "Full name of candidate"},
            "email": map[string]any{"type": "string", "description": "Email address"},
            "skills": map[string]any{
                "type":        "array",
                "items":       map[string]any{"type": "string"},
                "description": "Technical skills and technologies",
            },
        }},
        "required": {OfAnyArray: []any{"name", "email", "skills"}},
    }


    // Upload a file to extract from
    f, err := os.Open("resume.pdf")
    if err != nil {
        log.Fatal(err)
    }
    defer f.Close()


    fileObj, err := client.Files.New(ctx, llamacloud.FileNewParams{
        File:    f,
        Purpose: "extract",
    })
    if err != nil {
        log.Fatal(err)
    }


    // Extract data from document
    job, err := client.Extract.New(ctx, llamacloud.ExtractNewParams{
        ExtractV2JobCreate: llamacloud.ExtractV2JobCreateParam{
            FileInput: fileObj.ID,
            Configuration: llamacloud.ExtractConfigurationParam{
                DataSchema:       dataSchema,
                ExtractionTarget: llamacloud.ExtractConfigurationExtractionTargetPerDoc,
                Tier:             llamacloud.ExtractConfigurationTierAgentic,
            },
        },
    })
    if err != nil {
        log.Fatal(err)
    }


    // Poll for completion
    for job.Status != "COMPLETED" && job.Status != "FAILED" && job.Status != "CANCELLED" {
        time.Sleep(2 * time.Second)
        job, err = client.Extract.Get(ctx, job.ID, llamacloud.ExtractGetParams{})
        if err != nil {
            log.Fatal(err)
        }
    }


    fmt.Println(job.ExtractResult.RawJSON())
}
```

```
import ai.llamaindex.llamacloud.client.LlamaCloudClient;
import ai.llamaindex.llamacloud.client.okhttp.LlamaCloudOkHttpClient;
import ai.llamaindex.llamacloud.core.JsonValue;
import ai.llamaindex.llamacloud.models.extract.ExtractConfiguration;
import ai.llamaindex.llamacloud.models.extract.ExtractCreateParams;
import ai.llamaindex.llamacloud.models.extract.ExtractGetParams;
import ai.llamaindex.llamacloud.models.extract.ExtractV2Job;
import ai.llamaindex.llamacloud.models.extract.ExtractV2JobCreate;
import ai.llamaindex.llamacloud.models.files.FileCreateParams;
import ai.llamaindex.llamacloud.models.files.FileCreateResponse;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;


LlamaCloudClient client = LlamaCloudOkHttpClient.fromEnv();


// Define schema as a JSON Schema literal
Map<String, Object> nameField = new HashMap<>();
nameField.put("type", "string");
nameField.put("description", "Full name of candidate");


Map<String, Object> emailField = new HashMap<>();
emailField.put("type", "string");
emailField.put("description", "Email address");


Map<String, Object> skillItems = new HashMap<>();
skillItems.put("type", "string");
Map<String, Object> skillsField = new HashMap<>();
skillsField.put("type", "array");
skillsField.put("items", skillItems);
skillsField.put("description", "Technical skills and technologies");


Map<String, Object> properties = new HashMap<>();
properties.put("name", nameField);
properties.put("email", emailField);
properties.put("skills", skillsField);


ExtractConfiguration.DataSchema dataSchema = ExtractConfiguration.DataSchema.builder()
        .putAdditionalProperty("type", JsonValue.from("object"))
        .putAdditionalProperty("properties", JsonValue.from(properties))
        .putAdditionalProperty("required", JsonValue.from(Arrays.asList("name", "email", "skills")))
        .build();


// Upload a file to extract from
FileCreateResponse fileObj = client.files().create(
        FileCreateParams.builder()
                .file(Paths.get("resume.pdf"))
                .purpose("extract")
                .build());


// Extract data from document
ExtractV2Job job = client.extract().create(
        ExtractCreateParams.builder()
                .extractV2JobCreate(
                        ExtractV2JobCreate.builder()
                                .fileInput(fileObj.id())
                                .configuration(
                                        ExtractConfiguration.builder()
                                                .dataSchema(dataSchema)
                                                .extractionTarget(ExtractConfiguration.ExtractionTarget.PER_DOC)
                                                .tier(ExtractConfiguration.Tier.AGENTIC)
                                                .build())
                                .build())
                .build());


// Poll for completion
while (!job.status().equals("COMPLETED")
        && !job.status().equals("FAILED")
        && !job.status().equals("CANCELLED")) {
    Thread.sleep(2000);
    job = client.extract().get(ExtractGetParams.builder().jobId(job.id()).build());
}


System.out.println(job.extractResult());
```

Terminal window

```
# Define schema as a JSON Schema literal
DATA_SCHEMA='{
  "type": "object",
  "properties": {
    "name": {"type": "string", "description": "Full name of candidate"},
    "email": {"type": "string", "description": "Email address"},
    "skills": {"type": "array", "items": {"type": "string"}, "description": "Technical skills and technologies"}
  },
  "required": ["name", "email", "skills"]
}'


# Upload a file to extract from
FILE_ID=$(llp files create --file resume.pdf --purpose extract | jq -r '.id')


# Extract data from document
JOB_ID=$(llp extract create \
  --file-input "$FILE_ID" \
  --configuration "{\"data_schema\": $DATA_SCHEMA, \"extraction_target\": \"per_doc\", \"tier\": \"agentic\"}" \
  | jq -r '.id')


# Poll for completion
while true; do
  JOB=$(llp extract get --job-id "$JOB_ID")
  STATUS=$(echo "$JOB" | jq -r '.status')
  case "$STATUS" in COMPLETED|FAILED|CANCELLED) break ;; esac
  sleep 2
done


echo "$JOB" | jq '.extract_result'
```

Run your script to see the extracted result!

## Defining Schemas

Schemas can be defined using either Pydantic/Zod models or JSON Schema. Refer to the [Schemas](/llamaparse/extract/guides/configuring-extract/#schema-design-and-restrictions/index.md) page for more details.

## Other Extraction APIs

### Extraction over bytes or text

You can also call extraction directly over raw text.

- [Python](#tab-panel-599)
- [TypeScript](#tab-panel-600)
- [Go](#tab-panel-601)
- [Java](#tab-panel-602)
- [CLI](#tab-panel-603)

```
import io
import time
from llama_cloud import LlamaCloud


client = LlamaCloud(api_key="your_api_key")


source_text = "Candidate Name: Jane Doe\nEmail: jane.doe@example.com"
source_buffer = io.BytesIO(source_text.encode('utf-8'))


file_obj = client.files.create(file=source_buffer, purpose="extract", external_file_id="resume.txt")


job = client.extract.create(
    file_input=file_obj.id,
    configuration={
        "data_schema": Resume.model_json_schema(),
        "extraction_target": "per_doc",
        "tier": "agentic",
    },
)


while job.status not in ("COMPLETED", "FAILED", "CANCELLED"):
    time.sleep(2)
    job = client.extract.get(job.id)
```

```
import LlamaCloud from '@llamaindex/llama-cloud';


const client = new LlamaCloud({
  apiKey: 'your_api_key',
});


const sourceText = 'Candidate Name: Jane Doe\nEmail: jane.doe@example.com';


const fileObj = await client.files.create({
  file: Buffer.from(sourceText, 'utf-8'),
  purpose: 'extract',
  external_file_id: 'resume.txt',
});


let job = await client.extract.create({
  file_input: fileObj.id,
  configuration: {
      data_schema: z.toJSONSchema(ResumeSchema),
      extraction_target: 'per_doc',
      tier: 'agentic',
  },
});


while (!['COMPLETED', 'FAILED', 'CANCELLED'].includes(job.status)) {
  await new Promise((r) => setTimeout(r, 2000));
  job = await client.extract.get(job.id);
}
```

```
import (
    "strings"


    llamacloud "github.com/run-llama/llama-parse-go"
)


client := llamacloud.NewClient()


sourceText := "Candidate Name: Jane Doe\nEmail: jane.doe@example.com"


fileObj, err := client.Files.New(ctx, llamacloud.FileNewParams{
    File:           strings.NewReader(sourceText),
    Purpose:        "extract",
    ExternalFileID: llamacloud.String("resume.txt"),
})
if err != nil {
    log.Fatal(err)
}


job, err := client.Extract.New(ctx, llamacloud.ExtractNewParams{
    ExtractV2JobCreate: llamacloud.ExtractV2JobCreateParam{
        FileInput: fileObj.ID,
        Configuration: llamacloud.ExtractConfigurationParam{
            DataSchema:       dataSchema,
            ExtractionTarget: llamacloud.ExtractConfigurationExtractionTargetPerDoc,
            Tier:             llamacloud.ExtractConfigurationTierAgentic,
        },
    },
})
if err != nil {
    log.Fatal(err)
}


for job.Status != "COMPLETED" && job.Status != "FAILED" && job.Status != "CANCELLED" {
    time.Sleep(2 * time.Second)
    job, err = client.Extract.Get(ctx, job.ID, llamacloud.ExtractGetParams{})
    if err != nil {
        log.Fatal(err)
    }
}
```

```
import java.nio.charset.StandardCharsets;


LlamaCloudClient client = LlamaCloudOkHttpClient.fromEnv();


String sourceText = "Candidate Name: Jane Doe\nEmail: jane.doe@example.com";


FileCreateResponse fileObj = client.files().create(
        FileCreateParams.builder()
                .file(sourceText.getBytes(StandardCharsets.UTF_8))
                .purpose("extract")
                .externalFileId("resume.txt")
                .build());


ExtractV2Job job = client.extract().create(
        ExtractCreateParams.builder()
                .extractV2JobCreate(
                        ExtractV2JobCreate.builder()
                                .fileInput(fileObj.id())
                                .configuration(
                                        ExtractConfiguration.builder()
                                                .dataSchema(dataSchema)
                                                .extractionTarget(ExtractConfiguration.ExtractionTarget.PER_DOC)
                                                .tier(ExtractConfiguration.Tier.AGENTIC)
                                                .build())
                                .build())
                .build());


while (!job.status().equals("COMPLETED")
        && !job.status().equals("FAILED")
        && !job.status().equals("CANCELLED")) {
    Thread.sleep(2000);
    job = client.extract().get(ExtractGetParams.builder().jobId(job.id()).build());
}
```

Terminal window

```
printf 'Candidate Name: Jane Doe\nEmail: jane.doe@example.com' > resume.txt


FILE_ID=$(llp files create \
  --file resume.txt \
  --purpose extract \
  --external-file-id resume.txt \
  | jq -r '.id')


JOB_ID=$(llp extract create \
  --file-input "$FILE_ID" \
  --configuration "{\"data_schema\": $DATA_SCHEMA, \"extraction_target\": \"per_doc\", \"tier\": \"agentic\"}" \
  | jq -r '.id')


while true; do
  STATUS=$(llp extract get --job-id "$JOB_ID" | jq -r '.status')
  case "$STATUS" in COMPLETED|FAILED|CANCELLED) break ;; esac
  sleep 2
done
```

### Extraction from a Parse Job ID

If you’ve already parsed a document with LlamaParse, you can pass the parse job ID directly to extraction instead of uploading the file again. This skips re-parsing, saving both time and credits. It’s especially useful when you want to extract with multiple schemas from the same document.

- [Python](#tab-panel-604)
- [TypeScript](#tab-panel-605)
- [Go](#tab-panel-606)
- [Java](#tab-panel-607)
- [CLI](#tab-panel-608)

```
import time
from llama_cloud import LlamaCloud


client = LlamaCloud(api_key="your_api_key")


# Step 1: Parse the document once
parse_job = client.parsing.create(
    tier="agentic",
    version="latest",
    upload_file="./document.pdf",
)
parse_result = client.parsing.wait_for_completion(parse_job.id, verbose=True)


# Step 2: Extract using the parse job ID (no re-upload needed)
job = client.extract.create(
    file_input=parse_job.id,  # e.g. "pjb-xxxxxxxx-..."
    configuration={
        "data_schema": Resume.model_json_schema(),
        "extraction_target": "per_doc",
        "tier": "agentic",
    },
)


# Poll for completion
while job.status not in ("COMPLETED", "FAILED", "CANCELLED"):
    time.sleep(2)
    job = client.extract.get(job.id)


print(job.extract_result)
```

```
import fs from 'fs';
import LlamaCloud from '@llamaindex/llama-cloud';


const client = new LlamaCloud({ apiKey: 'your_api_key' });


// Step 1: Parse the document once
let parseJob = await client.parsing.create({
  tier: 'agentic',
  version: 'latest',
  upload_file: fs.createReadStream('./document.pdf'),
});
parseJob = await client.parsing.waitForCompletion(parseJob.id);


// Step 2: Extract using the parse job ID (no re-upload needed)
let job = await client.extract.create({
  file_input: parseJob.id,  // e.g. "pjb-xxxxxxxx-..."
  configuration: {
      data_schema: z.toJSONSchema(ResumeSchema),
      extraction_target: 'per_doc',
      tier: 'agentic',
  },
});


// Poll for completion
while (!['COMPLETED', 'FAILED', 'CANCELLED'].includes(job.status)) {
  await new Promise((r) => setTimeout(r, 2000));
  job = await client.extract.get(job.id);
}


console.log(job.extract_result);
```

```
client := llamacloud.NewClient()


// Step 1: Parse the document once
f, err := os.Open("./document.pdf")
if err != nil {
    log.Fatal(err)
}
defer f.Close()


parseFile, err := client.Files.New(ctx, llamacloud.FileNewParams{
    File:    f,
    Purpose: "parse",
})
if err != nil {
    log.Fatal(err)
}


parseJob, err := client.Parsing.New(ctx, llamacloud.ParsingNewParams{
    Tier:    llamacloud.ParsingNewParamsTierAgentic,
    Version: llamacloud.ParsingNewParamsVersionLatest,
    FileID:  llamacloud.String(parseFile.ID),
})
if err != nil {
    log.Fatal(err)
}


parseResult, err := client.Parsing.Get(ctx, parseJob.ID, llamacloud.ParsingGetParams{})
if err != nil {
    log.Fatal(err)
}
for parseResult.Job.Status != "COMPLETED" &&
    parseResult.Job.Status != "FAILED" &&
    parseResult.Job.Status != "CANCELLED" {
    time.Sleep(2 * time.Second)
    parseResult, err = client.Parsing.Get(ctx, parseJob.ID, llamacloud.ParsingGetParams{})
    if err != nil {
        log.Fatal(err)
    }
}


// Step 2: Extract using the parse job ID (no re-upload needed)
job, err := client.Extract.New(ctx, llamacloud.ExtractNewParams{
    ExtractV2JobCreate: llamacloud.ExtractV2JobCreateParam{
        FileInput: parseJob.ID, // e.g. "pjb-xxxxxxxx-..."
        Configuration: llamacloud.ExtractConfigurationParam{
            DataSchema:       dataSchema,
            ExtractionTarget: llamacloud.ExtractConfigurationExtractionTargetPerDoc,
            Tier:             llamacloud.ExtractConfigurationTierAgentic,
        },
    },
})
if err != nil {
    log.Fatal(err)
}


// Poll for completion
for job.Status != "COMPLETED" && job.Status != "FAILED" && job.Status != "CANCELLED" {
    time.Sleep(2 * time.Second)
    job, err = client.Extract.Get(ctx, job.ID, llamacloud.ExtractGetParams{})
    if err != nil {
        log.Fatal(err)
    }
}


fmt.Println(job.ExtractResult.RawJSON())
```

```
import ai.llamaindex.llamacloud.models.parsing.ParsingCreateParams;
import ai.llamaindex.llamacloud.models.parsing.ParsingCreateResponse;
import ai.llamaindex.llamacloud.models.parsing.ParsingGetParams;
import ai.llamaindex.llamacloud.models.parsing.ParsingGetResponse;


LlamaCloudClient client = LlamaCloudOkHttpClient.fromEnv();


// Step 1: Parse the document once
FileCreateResponse parseFile = client.files().create(
        FileCreateParams.builder()
                .file(Paths.get("./document.pdf"))
                .purpose("parse")
                .build());


ParsingCreateResponse parseJob = client.parsing().create(
        ParsingCreateParams.builder()
                .tier(ParsingCreateParams.Tier.AGENTIC)
                .version(ParsingCreateParams.Version.LATEST)
                .fileId(parseFile.id())
                .build());


ParsingGetResponse parseResult = client.parsing().get(
        ParsingGetParams.builder().jobId(parseJob.id()).build());
while (!parseResult.job().status().equals(ParsingGetResponse.Job.Status.COMPLETED)
        && !parseResult.job().status().equals(ParsingGetResponse.Job.Status.FAILED)
        && !parseResult.job().status().equals(ParsingGetResponse.Job.Status.CANCELLED)) {
    Thread.sleep(2000);
    parseResult = client.parsing().get(
            ParsingGetParams.builder().jobId(parseJob.id()).build());
}


// Step 2: Extract using the parse job ID (no re-upload needed)
ExtractV2Job job = client.extract().create(
        ExtractCreateParams.builder()
                .extractV2JobCreate(
                        ExtractV2JobCreate.builder()
                                .fileInput(parseJob.id()) // e.g. "pjb-xxxxxxxx-..."
                                .configuration(
                                        ExtractConfiguration.builder()
                                                .dataSchema(dataSchema)
                                                .extractionTarget(ExtractConfiguration.ExtractionTarget.PER_DOC)
                                                .tier(ExtractConfiguration.Tier.AGENTIC)
                                                .build())
                                .build())
                .build());


// Poll for completion
while (!job.status().equals("COMPLETED")
        && !job.status().equals("FAILED")
        && !job.status().equals("CANCELLED")) {
    Thread.sleep(2000);
    job = client.extract().get(ExtractGetParams.builder().jobId(job.id()).build());
}


System.out.println(job.extractResult());
```

Terminal window

```
# Step 1: Parse the document once
PARSE_FILE_ID=$(llp files create --file ./document.pdf --purpose parse | jq -r '.id')


PARSE_JOB_ID=$(llp parsing create \
  --tier agentic \
  --version latest \
  --file-id "$PARSE_FILE_ID" \
  | jq -r '.id')


while true; do
  STATUS=$(llp parsing get --job-id "$PARSE_JOB_ID" | jq -r '.job.status')
  case "$STATUS" in COMPLETED|FAILED|CANCELLED) break ;; esac
  sleep 2
done


# Step 2: Extract using the parse job ID (no re-upload needed)
JOB_ID=$(llp extract create \
  --file-input "$PARSE_JOB_ID" \
  --configuration "{\"data_schema\": $DATA_SCHEMA, \"extraction_target\": \"per_doc\", \"tier\": \"agentic\"}" \
  | jq -r '.id')


# Poll for completion
while true; do
  JOB=$(llp extract get --job-id "$JOB_ID")
  STATUS=$(echo "$JOB" | jq -r '.status')
  case "$STATUS" in COMPLETED|FAILED|CANCELLED) break ;; esac
  sleep 2
done


echo "$JOB" | jq '.extract_result'
```

The `file_input` field accepts either a file ID (`dfl-...`) or a parse job ID (`pjb-...`). For a more detailed example including extracting with multiple schemas from the same parse result, see the [Batch Extraction Cookbook](../examples/batch_extraction_cookbook#parse-then-extract).

### Batch Processing

Process multiple files asynchronously:

- [Python](#tab-panel-609)
- [TypeScript](#tab-panel-610)
- [Go](#tab-panel-611)
- [Java](#tab-panel-612)
- [CLI](#tab-panel-613)

We can submit multiple files for extraction using concurrency control with a semaphore:

```
import asyncio
from llama_cloud import AsyncLlamaCloud


client = AsyncLlamaCloud(api_key="your_api_key")
semaphore = asyncio.Semaphore(5)  # Limit concurrency


EXTRACT_CONFIG = {
    "data_schema": Resume.model_json_schema(),
    "extraction_target": "per_doc",
    "tier": "agentic",
}


async def process_path(file_path: str):
    async with semaphore:
        file_obj = await client.files.create(file=file_path, purpose="extract")


        job = await client.extract.create(
            file_input=file_obj.id,
            configuration=EXTRACT_CONFIG,
        )


        while job.status not in ("COMPLETED", "FAILED", "CANCELLED"):
            await asyncio.sleep(2)
            job = await client.extract.get(job.id)


    return job.extract_result


async def main():
    file_paths = ["resume1.pdf", "resume2.pdf", "resume3.pdf"]
    results = await asyncio.gather(*(process_path(path) for path in file_paths))
    return results


asyncio.run(main())
```

We can submit multiple files for extraction using concurrency control with a semaphore:

```
import fs from 'fs';
import LlamaCloud from '@llamaindex/llama-cloud';


const client = new LlamaCloud({
  apiKey: 'your_api_key',
});


const extractConfig = {
    data_schema: z.toJSONSchema(ResumeSchema),
    extraction_target: 'per_doc',
    tier: 'agentic',
};


// npm install async-mutex for Semaphore, or use p-limit
const semaphore = new Semaphore(5);


async function processPath(filePath: string) {
  await semaphore.acquire();
  try {
    const fileObj = await client.files.create({
      file: fs.createReadStream(filePath),
      purpose: 'extract',
    });


    let job = await client.extract.create({
      file_input: fileObj.id,
      configuration: extractConfig,
    });


    while (!['COMPLETED', 'FAILED', 'CANCELLED'].includes(job.status)) {
      await new Promise((r) => setTimeout(r, 2000));
      job = await client.extract.get(job.id);
    }


    return job.extract_result;
  } finally {
    semaphore.release();
  }
}


const filePaths = ["resume1.pdf", "resume2.pdf", "resume3.pdf"];
const results = await Promise.all(filePaths.map(processPath));
```

We can submit multiple files for extraction using concurrency control with a buffered channel:

```
import (
    "sync"
)


client := llamacloud.NewClient()
sem := make(chan struct{}, 5) // Limit concurrency


extractConfig := llamacloud.ExtractConfigurationParam{
    DataSchema:       dataSchema,
    ExtractionTarget: llamacloud.ExtractConfigurationExtractionTargetPerDoc,
    Tier:             llamacloud.ExtractConfigurationTierAgentic,
}


processPath := func(filePath string) (llamacloud.ExtractV2JobExtractResultUnion, error) {
    sem <- struct{}{}
    defer func() { <-sem }()


    var empty llamacloud.ExtractV2JobExtractResultUnion


    f, err := os.Open(filePath)
    if err != nil {
        return empty, err
    }
    defer f.Close()


    fileObj, err := client.Files.New(ctx, llamacloud.FileNewParams{
        File:    f,
        Purpose: "extract",
    })
    if err != nil {
        return empty, err
    }


    job, err := client.Extract.New(ctx, llamacloud.ExtractNewParams{
        ExtractV2JobCreate: llamacloud.ExtractV2JobCreateParam{
            FileInput:     fileObj.ID,
            Configuration: extractConfig,
        },
    })
    if err != nil {
        return empty, err
    }


    for job.Status != "COMPLETED" && job.Status != "FAILED" && job.Status != "CANCELLED" {
        time.Sleep(2 * time.Second)
        job, err = client.Extract.Get(ctx, job.ID, llamacloud.ExtractGetParams{})
        if err != nil {
            return empty, err
        }
    }


    return job.ExtractResult, nil
}


filePaths := []string{"resume1.pdf", "resume2.pdf", "resume3.pdf"}
results := make([]llamacloud.ExtractV2JobExtractResultUnion, len(filePaths))


var wg sync.WaitGroup
for i, path := range filePaths {
    wg.Add(1)
    go func(i int, path string) {
        defer wg.Done()
        res, err := processPath(path)
        if err != nil {
            log.Fatal(err)
        }
        results[i] = res
    }(i, path)
}
wg.Wait()
```

We can submit multiple files for extraction using concurrency control with a fixed thread pool:

```
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;


LlamaCloudClient client = LlamaCloudOkHttpClient.fromEnv();
ExecutorService pool = Executors.newFixedThreadPool(5); // Limit concurrency


ExtractConfiguration extractConfig = ExtractConfiguration.builder()
        .dataSchema(dataSchema)
        .extractionTarget(ExtractConfiguration.ExtractionTarget.PER_DOC)
        .tier(ExtractConfiguration.Tier.AGENTIC)
        .build();


List<String> filePaths = Arrays.asList("resume1.pdf", "resume2.pdf", "resume3.pdf");
List<Future<ExtractV2Job>> futures = new ArrayList<>();


for (String filePath : filePaths) {
    futures.add(pool.submit(() -> {
        FileCreateResponse fileObj = client.files().create(
                FileCreateParams.builder()
                        .file(Paths.get(filePath))
                        .purpose("extract")
                        .build());


        ExtractV2Job job = client.extract().create(
                ExtractCreateParams.builder()
                        .extractV2JobCreate(
                                ExtractV2JobCreate.builder()
                                        .fileInput(fileObj.id())
                                        .configuration(extractConfig)
                                        .build())
                        .build());


        while (!job.status().equals("COMPLETED")
                && !job.status().equals("FAILED")
                && !job.status().equals("CANCELLED")) {
            Thread.sleep(2000);
            job = client.extract().get(ExtractGetParams.builder().jobId(job.id()).build());
        }


        return job;
    }));
}


for (Future<ExtractV2Job> future : futures) {
    System.out.println(future.get().extractResult());
}
pool.shutdown();
```

We can submit multiple files for extraction using concurrency control with background jobs:

Terminal window

```
EXTRACT_CONFIG="{\"data_schema\": $DATA_SCHEMA, \"extraction_target\": \"per_doc\", \"tier\": \"agentic\"}"


process_path() {
  FILE_ID=$(llp files create --file "$1" --purpose extract | jq -r '.id')


  JOB_ID=$(llp extract create \
    --file-input "$FILE_ID" \
    --configuration "$EXTRACT_CONFIG" \
    | jq -r '.id')


  while true; do
    JOB=$(llp extract get --job-id "$JOB_ID")
    STATUS=$(echo "$JOB" | jq -r '.status')
    case "$STATUS" in COMPLETED|FAILED|CANCELLED) break ;; esac
    sleep 2
  done


  echo "$JOB" | jq -c '.extract_result' > "results/$(basename "$1").json"
}


mkdir -p results
for path in resume1.pdf resume2.pdf resume3.pdf; do
  while [ "$(jobs -r | wc -l)" -ge 5 ]; do sleep 1; done  # Limit concurrency
  process_path "$path" &
done
wait


jq -s '.' results/*.json
```

### Schema Generation

You can use the SDK to auto-generate a JSON schema from a prompt or a sample file:

- [Python](#tab-panel-614)
- [TypeScript](#tab-panel-615)
- [Go](#tab-panel-616)
- [Java](#tab-panel-617)
- [CLI](#tab-panel-618)

```
# Generate schema from a prompt
generated = client.extract.generate_schema(
    prompt="Extract company financials including revenue, net income, and fiscal year",
)


# Generate schema from a sample file
file_obj = client.files.create(file="sample_report.pdf", purpose="extract")
generated = client.extract.generate_schema(
    file_id=file_obj.id,
    prompt="Extract key financial data",
)


# Use the generated schema in an extraction
job = client.extract.create(
    file_input=file_obj.id,
    configuration={
        "data_schema": generated.parameters.data_schema,
        "tier": "agentic",
    },
)
```

```
// Generate schema from a prompt
const schema = await client.extract.generateSchema({
  prompt: 'Extract company financials including revenue, net income, and fiscal year',
});


// Generate schema from a sample file
const fileObj = await client.files.create({
  file: fs.createReadStream('sample_report.pdf'),
  purpose: 'extract',
});
const schemaFromFile = await client.extract.generateSchema({
  file_id: fileObj.id,
  prompt: 'Extract key financial data',
});


// Use the generated schema in an extraction
let job = await client.extract.create({
  file_input: fileObj.id,
  configuration: {
      data_schema: schemaFromFile.parameters.data_schema,
      tier: 'agentic',
  },
});
```

```
import (
    "encoding/json"
)


// Generate schema from a prompt
generated, err := client.Extract.GenerateSchema(ctx, llamacloud.ExtractGenerateSchemaParams{
    ExtractV2SchemaGenerateRequest: llamacloud.ExtractV2SchemaGenerateRequestParam{
        Prompt: llamacloud.String("Extract company financials including revenue, net income, and fiscal year"),
    },
})
if err != nil {
    log.Fatal(err)
}


// Generate schema from a sample file
f, err := os.Open("sample_report.pdf")
if err != nil {
    log.Fatal(err)
}
defer f.Close()


fileObj, err := client.Files.New(ctx, llamacloud.FileNewParams{
    File:    f,
    Purpose: "extract",
})
if err != nil {
    log.Fatal(err)
}


generated, err = client.Extract.GenerateSchema(ctx, llamacloud.ExtractGenerateSchemaParams{
    ExtractV2SchemaGenerateRequest: llamacloud.ExtractV2SchemaGenerateRequestParam{
        FileID: llamacloud.String(fileObj.ID),
        Prompt: llamacloud.String("Extract key financial data"),
    },
})
if err != nil {
    log.Fatal(err)
}


// Use the generated schema in an extraction
var generatedSchema map[string]*llamacloud.ExtractConfigurationDataSchemaUnionParam
if err := json.Unmarshal([]byte(generated.Parameters.JSON.DataSchema.Raw()), &generatedSchema); err != nil {
    log.Fatal(err)
}


job, err := client.Extract.New(ctx, llamacloud.ExtractNewParams{
    ExtractV2JobCreate: llamacloud.ExtractV2JobCreateParam{
        FileInput: fileObj.ID,
        Configuration: llamacloud.ExtractConfigurationParam{
            DataSchema: generatedSchema,
            Tier:       llamacloud.ExtractConfigurationTierAgentic,
        },
    },
})
if err != nil {
    log.Fatal(err)
}
```

```
import ai.llamaindex.llamacloud.models.configurations.ConfigurationCreate;
import ai.llamaindex.llamacloud.models.extract.ExtractGenerateSchemaParams;
import ai.llamaindex.llamacloud.models.extract.ExtractV2SchemaGenerateRequest;


// Generate schema from a prompt
ConfigurationCreate generated = client.extract().generateSchema(
        ExtractGenerateSchemaParams.builder()
                .extractV2SchemaGenerateRequest(
                        ExtractV2SchemaGenerateRequest.builder()
                                .prompt("Extract company financials including revenue, net income, and fiscal year")
                                .build())
                .build());


// Generate schema from a sample file
FileCreateResponse fileObj = client.files().create(
        FileCreateParams.builder()
                .file(Paths.get("sample_report.pdf"))
                .purpose("extract")
                .build());


ConfigurationCreate schemaFromFile = client.extract().generateSchema(
        ExtractGenerateSchemaParams.builder()
                .extractV2SchemaGenerateRequest(
                        ExtractV2SchemaGenerateRequest.builder()
                                .fileId(fileObj.id())
                                .prompt("Extract key financial data")
                                .build())
                .build());


// Use the generated schema in an extraction
ExtractConfiguration.DataSchema generatedSchema = ExtractConfiguration.DataSchema.builder()
        .putAllAdditionalProperties(
                schemaFromFile.parameters().extractV2().get().dataSchema()._additionalProperties())
        .build();


ExtractV2Job job = client.extract().create(
        ExtractCreateParams.builder()
                .extractV2JobCreate(
                        ExtractV2JobCreate.builder()
                                .fileInput(fileObj.id())
                                .configuration(
                                        ExtractConfiguration.builder()
                                                .dataSchema(generatedSchema)
                                                .tier(ExtractConfiguration.Tier.AGENTIC)
                                                .build())
                                .build())
                .build());
```

Terminal window

```
# Generate schema from a prompt
llp extract generate-schema \
  --prompt "Extract company financials including revenue, net income, and fiscal year"


# Generate schema from a sample file
FILE_ID=$(llp files create --file sample_report.pdf --purpose extract | jq -r '.id')
SCHEMA=$(llp extract generate-schema \
  --file-id "$FILE_ID" \
  --prompt "Extract key financial data" \
  | jq -c '.parameters.data_schema')


# Use the generated schema in an extraction
llp extract create \
  --file-input "$FILE_ID" \
  --configuration "{\"data_schema\": $SCHEMA, \"tier\": \"agentic\"}"
```
