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

# Asynchronous Extraction (Extract Jobs)

> Extract from large Markdown documents asynchronously with Extract Jobs v2, then poll for results.

export const dpt3 = 'DPT-3';

export const extractDpt3 = 'Extract';

Use Extract Jobs v2 to extract structured data asynchronously. Instead of waiting for a single request to finish, you create a job, receive a `job_id` immediately, and retrieve the result when the job completes.

Use Extract Jobs for long-running extractions, such as extracting from long documents or with large, complex schemas.

## Endpoints

The request fields are the same as the synchronous Extract API. See [Extract Input Parameters](./extract-input).

Extract Jobs uses these endpoints:

| Method | Endpoint                    | Purpose                             |
| ------ | --------------------------- | ----------------------------------- |
| POST   | `/v2/extract/jobs`          | Create an extract job.              |
| GET    | `/v2/extract/jobs/{job_id}` | Get the status and result of a job. |

## Workflow

1. Build your extraction schema. See [Extraction Schema (JSON)](./ade-extract-schema-json).
2. Submit the Markdown and schema to `POST /v2/extract/jobs`.
3. Get the `job_id` from the response.
4. Poll `GET /v2/extract/jobs/{job_id}` until `status` is `completed`.
5. Read the extracted fields from the job's `result`, or from `output_url` if you saved the output to a URL. See [Extract API Response](./extract-response).

## Create a Job

Send the same fields you would send to the synchronous endpoint. Replace `YOUR_API_KEY` with your [API key](./agentic-api-key) and `parse-output.md` with the path to your Markdown file.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST 'https://api.ade.landing.ai/v2/extract/jobs' \
    -H 'Authorization: Bearer YOUR_API_KEY' \
    -F 'markdown=@parse-output.md' \
    -F 'schema={"type":"object","properties":{"revenue":{"type":"string","description":"Q1 2024 revenue"}}}'
  ```

  ```python Python theme={null}
  from pathlib import Path
  from landingai_ade import LandingAIADE

  client = LandingAIADE()

  job = client.v2.extract_jobs.create(
      markdown=Path("parse-output.md").read_text(),
      schema={
          "type": "object",
          "properties": {
              "revenue": {"type": "string", "description": "Q1 2024 revenue"}
          },
      },
  )
  print(job.job_id)
  ```

  ```typescript TypeScript theme={null}
  import fs from "fs";
  import LandingAIADE from "landingai-ade";

  const client = new LandingAIADE();

  const job = await client.v2.extractJobs.create({
    markdown: fs.readFileSync("parse-output.md", "utf8"),
    schema: {
      type: "object",
      properties: {
        revenue: { type: "string", description: "Q1 2024 revenue" },
      },
    },
  });
  console.log(job.job_id);
  ```
</CodeGroup>

The request returns a `202` response with the `job_id` and the initial status:

```json theme={null}
{
  "job_id": "extract-01k04h6t8rw2xq9v3m5npbsd4f",
  "status": "pending",
  "created_at": "2026-07-16T18:03:12Z"
}
```

### Choose a Service Tier

Set the optional `service_tier` form field to control the job's turnaround time and credit consumption.

If you omit `service_tier`, the job runs on the `standard` tier.

For how the tiers compare, see [Sync vs Async Processing](./sync-async). For credit consumption by tier, see [Credit Consumption](./credit-consumption#extract).

| Tier       | Behavior                                                                                                                     |
| ---------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `standard` | Consumes half the credits of the `priority` tier, with a slower turnaround. Best for cost-sensitive or non-urgent workloads. |
| `priority` | Consumes credits at the full rate, the same as Extract, with a faster turnaround. Best for time-sensitive jobs.              |

**Set the tier.**

Include the `service_tier` field in your create-job request:

<CodeGroup>
  ```bash cURL highlight={5} theme={null}
  curl -X POST 'https://api.ade.landing.ai/v2/extract/jobs' \
    -H 'Authorization: Bearer YOUR_API_KEY' \
    -F 'markdown=@parse-output.md' \
    -F 'schema={"type":"object","properties":{"revenue":{"type":"string","description":"Q1 2024 revenue"}}}' \
    -F 'service_tier=priority'
  ```

  ```python Python highlight={14} theme={null}
  from pathlib import Path
  from landingai_ade import LandingAIADE

  client = LandingAIADE()

  job = client.v2.extract_jobs.create(
      markdown=Path("parse-output.md").read_text(),
      schema={
          "type": "object",
          "properties": {
              "revenue": {"type": "string", "description": "Q1 2024 revenue"}
          },
      },
      service_tier="priority",
  )
  print(job.job_id)
  ```

  ```typescript TypeScript highlight={14} theme={null}
  import fs from "fs";
  import LandingAIADE from "landingai-ade";

  const client = new LandingAIADE();

  const job = await client.v2.extractJobs.create({
    markdown: fs.readFileSync("parse-output.md", "utf8"),
    schema: {
      type: "object",
      properties: {
        revenue: { type: "string", description: "Q1 2024 revenue" },
      },
    },
    service_tier: "priority",
  });
  console.log(job.job_id);
  ```
</CodeGroup>

## Get a Job

Poll the job with its `job_id`:

<CodeGroup>
  ```bash cURL theme={null}
  curl 'https://api.ade.landing.ai/v2/extract/jobs/JOB_ID' \
    -H 'Authorization: Bearer YOUR_API_KEY'
  ```

  ```python Python theme={null}
  from landingai_ade import LandingAIADE

  client = LandingAIADE()

  # Fetch the job once. Use client.v2.extract_jobs.wait("JOB_ID") to poll until it finishes.
  job = client.v2.extract_jobs.get("JOB_ID")
  print(job.status)
  if job.status == "completed":
      print(job.result.extraction)
  ```

  ```typescript TypeScript theme={null}
  import LandingAIADE, { type V2ExtractResult } from "landingai-ade";

  const client = new LandingAIADE();

  // Fetch the job once. Use client.v2.extractJobs.wait("JOB_ID") to poll until it finishes.
  const job = await client.v2.extractJobs.get("JOB_ID");
  console.log(job.status);
  if (job.status === "completed") {
    console.log((job.result as V2ExtractResult).extraction);
  }
  ```
</CodeGroup>

The response includes the job status and, once the job finishes, the result:

| Field          | Description                                                                                                                                                                                                                                                                                                                             |
| -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `job_id`       | The unique identifier for the job.                                                                                                                                                                                                                                                                                                      |
| `status`       | The current state of the job. See [Job Statuses](#job-statuses).                                                                                                                                                                                                                                                                        |
| `created_at`   | When the job was created.                                                                                                                                                                                                                                                                                                               |
| `completed_at` | When the job finished. Present once the job reaches a final state.                                                                                                                                                                                                                                                                      |
| `progress`     | An estimate of how close the job is to completion, between `0` and `1`, updated on each poll. Present only while the job is processing, and never reaches `1`. To detect completion, check for a `status` of `completed` instead.                                                                                                       |
| `result`       | The extraction result, present when `status` is `completed` and you did not save the output to a URL. This object has the same shape as a synchronous response. See [Extract API Response](./extract-response).                                                                                                                         |
| `output_url`   | The location of the saved output, present only when you supplied `output_save_url`. When set, the output is delivered to the URL instead of returned in `result`. See [Save Extraction Output to a URL](#save-extraction-output-to-a-url).                                                                                              |
| `metadata`     | The job's `metadata` block, including `billing`. Present on completed jobs that saved their output to a URL, so you can confirm the model version and charge without fetching the file. For inline results, this information is in `result.metadata` instead. See [Extract API Response](./extract-response#request-metadata-metadata). |
| `error`        | Present when `status` is `failed`. Contains a `code` and a `message`.                                                                                                                                                                                                                                                                   |

## Job Statuses

| Status       | Description                                                          |
| ------------ | -------------------------------------------------------------------- |
| `pending`    | The job is accepted and queued, but has not started.                 |
| `processing` | The job is running.                                                  |
| `completed`  | The job finished. Read the extraction from `result` or `output_url`. |
| `failed`     | The job did not finish. See the `error` field for details.           |

## Save Extraction Output to a URL

To write the extraction result to your own storage instead of retrieving it inline, pass the optional `output_save_url` parameter when you create the job. The result (the same shape as a synchronous response, including `metadata` with `billing`) is delivered to that URL, and the poll response reports `output_url` instead of `result`. The completed poll response also carries the job's `metadata`, so billing information is available without fetching the file.

The `output_save_url` parameter is accepted only on job creation; the synchronous `/v2/extract` endpoint rejects it with a 422 error. The URL must be a presigned URL that grants time-limited write access to a single object, with the same requirements as Parse Jobs; see [URL Requirements](./parse-async#url-requirements).

<CodeGroup>
  ```bash cURL highlight={5} theme={null}
  curl -X POST 'https://api.ade.landing.ai/v2/extract/jobs' \
    -H 'Authorization: Bearer YOUR_API_KEY' \
    -F 'markdown=@parse-output.md' \
    -F 'schema={"type":"object","properties":{"revenue":{"type":"string","description":"Q1 2024 revenue"}}}' \
    -F 'output_save_url=YOUR_PRESIGNED_URL'
  ```

  ```python Python highlight={14} theme={null}
  from pathlib import Path
  from landingai_ade import LandingAIADE

  client = LandingAIADE()

  job = client.v2.extract_jobs.create(
      markdown=Path("parse-output.md").read_text(),
      schema={
          "type": "object",
          "properties": {
              "revenue": {"type": "string", "description": "Q1 2024 revenue"}
          },
      },
      output_save_url="YOUR_PRESIGNED_URL",
  )
  print(job.job_id)
  ```

  ```typescript TypeScript highlight={14} theme={null}
  import fs from "fs";
  import LandingAIADE from "landingai-ade";

  const client = new LandingAIADE();

  const job = await client.v2.extractJobs.create({
    markdown: fs.readFileSync("parse-output.md", "utf8"),
    schema: {
      type: "object",
      properties: {
        revenue: { type: "string", description: "Q1 2024 revenue" },
      },
    },
    output_save_url: "YOUR_PRESIGNED_URL",
  });
  console.log(job.job_id);
  ```
</CodeGroup>

## Rate Limits

Extract Jobs submissions are always accepted (HTTP 202) and never return a rate-limit error; jobs are paced internally instead. There is no input size cap. See [Rate Limits](./rate-limits#extract-v2-api).
