Pipelines

Save, version, and reuse extraction configurations.

A pipeline bundles OCR model, LLM model, JSON Schema, and extraction options for reuse across documents. Pipelines are tenant-scoped, identified by oppl_… ids, and versioned on each update. In-flight and completed jobs keep their admit-time snapshot when you patch a pipeline later.

Field definitions live in the Pipelines API reference.

List pipelines

GET /pipelines returns active (non-deleted) pipelines for your organization, newest updates first.

curl -s 'https://api.openparser.dev/pipelines' \
  -H 'Authorization: Bearer YOUR_API_KEY'
openparser pipelines list --json
const { items } = await client.pipelines.list();
pipelines = client.pipelines.list()

Get a pipeline

GET /pipelines/{id} returns one active pipeline including its current version. Deleted, missing, and cross-tenant ids return 404 pipeline_not_found.

curl -s 'https://api.openparser.dev/pipelines/oppl_...' \
  -H 'Authorization: Bearer YOUR_API_KEY'
openparser pipelines get oppl_... --json
const pipeline = await client.pipelines.get('oppl_...');
pipeline = client.pipelines.get("oppl_...")

Create a pipeline

POST /pipelines persists a validated extraction configuration. Names and slugs must be unique within your organization; duplicates return 409 pipeline_name_conflict.

curl -X POST 'https://api.openparser.dev/pipelines' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Invoice fields",
    "slug": "invoice-fields",
    "ocr_model": "paddleocr-vl-1.6",
    "llm_model": "openai/gpt-6-luna",
    "schema": {
      "type": "object",
      "properties": {
        "invoice_number": { "type": "string" }
      },
      "required": ["invoice_number"],
      "additionalProperties": false
    }
  }'
openparser pipelines create \
  --name "Invoice fields" \
  --slug invoice-fields \
  --ocr-model paddleocr-vl-1.6 \
  --llm-model openai/gpt-6-luna \
  --schema-json '{"type":"object","properties":{"invoice_number":{"type":"string"}},"required":["invoice_number"],"additionalProperties":false}'
const pipeline = await client.pipelines.create({
  name: 'Invoice fields',
  slug: 'invoice-fields',
  ocr_model: 'paddleocr-vl-1.6',
  llm_model: 'openai/gpt-6-luna',
  schema: {
    type: 'object',
    properties: {
      invoice_number: { type: 'string' },
    },
    required: ['invoice_number'],
    additionalProperties: false,
  },
});
pipeline = client.pipelines.create({
    "name": "Invoice fields",
    "slug": "invoice-fields",
    "ocr_model": "paddleocr-vl-1.6",
    "llm_model": "openai/gpt-6-luna",
    "schema": {
        "type": "object",
        "properties": {
            "invoice_number": {"type": "string"},
        },
        "required": ["invoice_number"],
        "additionalProperties": False,
    },
})

Update a pipeline

PATCH /pipelines/{id} merges one or more fields, re-validates the effective configuration, and increments version. Send only the fields you want to change.

curl -X PATCH 'https://api.openparser.dev/pipelines/oppl_...' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"name": "Invoice fields v2"}'
openparser pipelines update oppl_... --name "Invoice fields v2" --json
const updated = await client.pipelines.update('oppl_...', {
  name: 'Invoice fields v2',
});
updated = client.pipelines.update(
    "oppl_...",
    {"name": "Invoice fields v2"},
)

Delete a pipeline

DELETE /pipelines/{id} soft-deletes the pipeline. New extract admissions with that id return 404 pipeline_not_found; historical jobs retain their snapshotted configuration.

curl -X DELETE 'https://api.openparser.dev/pipelines/oppl_...' \
  -H 'Authorization: Bearer YOUR_API_KEY'
openparser pipelines delete oppl_... --json
await client.pipelines.delete('oppl_...');
client.pipelines.delete("oppl_...")

Use a pipeline on extract

Pass pipeline_id in extract admission instead of inline ocr_model, llm_model, and schema. The two shapes are mutually exclusive. OpenParser records the pipeline version at admit time.

curl -X POST 'https://api.openparser.dev/extract/async' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H "Idempotency-Key: $(uuidgen 2>/dev/null || openssl rand -hex 16)" \
  -F 'request={"pipeline_id":"oppl_..."};type=application/json' \
  -F 'file=@./document.pdf'
openparser extract async ./document.pdf --pipeline-id oppl_... --json
const accepted = await client.extract.async(
  { pipeline_id: 'oppl_...' },
  file,
);
from pathlib import Path

accepted = client.extract.async_(
    {"pipeline_id": "oppl_..."},
    file=Path("document.pdf"),
)

You can also set pipeline_id on individual items in POST /extract/batch.

On this page