Skip to main content

Classify + Extract in One Call

Classify a document and extract its data in a single API call. Instead of calling Classify Document to get a label, picking a template yourself, and then running a separate extract, you create a Classifier whose labels are mapped to extraction templates, then submit the document once with a classifier_id. DocumentPro classifies the document, automatically selects the mapped template, and extracts — all in one request, with no pre-OCR or pre-classify step.

When to use it

Use this flow when you receive mixed document types — invoices, purchase orders, remittances, etc. — and want each one automatically routed to the right extraction template without deciding up front which template applies.

If you only need a label (no extraction), use Classify Document or Run Classification instead.

Prerequisites

  1. An extraction template (Workflow) for each document type you expect. See Create Workflow.
  2. A saved Classifier whose classes map each label to a template_id.

Step 1 — Create a Classifier with template mappings

Each item in classes can include a template_id — the extraction template to run when a document is classified with that label. You can also set default_template_id and min_confidence as fallbacks (see Fallbacks below).

curl -X POST "https://api.documentpro.ai/v1/classifiers" \
-H "x-api-key: $API_KEY" -H "Content-Type: application/json" \
-d '{
"name": "Inbound Doc Router",
"classes": [
{ "label": "invoice", "description": "A commercial invoice or bill", "template_id": "tmpl_invoice" },
{ "label": "purchase_order", "description": "A purchase order", "template_id": "tmpl_po" }
],
"default_template_id": "tmpl_generic",
"min_confidence": 0.6
}'
# -> { "classifier_id": "clf_9a1…", "name": "Inbound Doc Router", "configs": { … } }

See Create Classifier for the full field reference — the request body is flat (not nested under configs); the response nests the saved settings under configs.

Step 2 — Submit a document with classifier_id

There are two equivalent ways to submit — pick whichever fits your integration. Both call the same underlying classify-and-route logic and both are fully supported in production.

Modern: POST /v1/extract

Pass classifier_id instead of template_id. Accepts it as a JSON body field, a multipart form field, or a query param:

# JSON body with a previously uploaded document
curl -X POST "https://api.documentpro.ai/v1/extract" \
-H "x-api-key: $API_KEY" -H "Content-Type: application/json" \
-d '{ "document_id": "3f2c…", "classifier_id": "clf_9a1…" }'

# JSON body with a public/presigned URL
curl -X POST "https://api.documentpro.ai/v1/extract" \
-H "x-api-key: $API_KEY" -H "Content-Type: application/json" \
-d '{ "url": "https://…/invoice.pdf", "classifier_id": "clf_9a1…" }'

# multipart file upload
curl -X POST "https://api.documentpro.ai/v1/extract?classifier_id=clf_9a1…" \
-H "x-api-key: $API_KEY" -F "file=@invoice.pdf"

Response (async): { "request_id": "req_…" }.

Classic: run_parser

If you're already using Run Extract, pass classifier_id as a query param instead of template_id:

curl --location "https://api.documentpro.ai/v1/documents/{document_id}/run_parser?classifier_id=clf_9a1…" \
--header 'x-api-key: YOUR_API_KEY'

Both paths require the document to already be uploaded (or provided via url/file) — no pre-OCR or pre-classify step is required, unlike the standalone POST /v1/classify endpoint. If both template_id and classifier_id are supplied, classifier_id takes precedence. Only saved classifiers are supported here — the inline classification_schema used by standalone Classify Document is not accepted in the combined call.

Step 3 — Poll for the result

Poll with GET /files?request_id=… (the same endpoint used by Poll Extract) or GET /v1/extract?request_id=… — both return the same result object.

The envelope follows how the request was submitted, not which poll endpoint you call:

// Submitted via POST /v1/extract -> extracted data at results.data
{
"request_id": "req_…",
"request_status": "completed",
"classification": "invoice",
"confidence_scores": { "invoice": 0.95, "purchase_order": 0.05 },
"classify_credits": 1,
"credits_used": 3,
"total_credits": 4,
"results": {
"num_pages": 1,
"data": { /* extracted fields */ }
}
}
// Submitted via classic run_parser -> extracted data at response_body.result_json_data
{
"request_id": "req_…",
"request_status": "completed",
"classification": "invoice",
"confidence_scores": { "invoice": 0.95, "purchase_order": 0.05 },
"classify_credits": 1,
"credits_used": 3,
"total_credits": 4,
"response_body": {
"template_id": "tmpl_invoice", // auto-selected by the classifier
"result_json_data": { /* extracted fields */ }
// semantic-chunking results use response_body.chunks instead
}
}

classification, confidence_scores, classify_credits, and total_credits are always top-level, regardless of submission method. A request created via POST /v1/extract always returns the results.data shape (even if you poll GET /files); a request created via run_parser always returns the response_body.result_json_data shape.

Fallbacks

  • default_template_id: used when the winning label has no template_id mapped, or its confidence is below min_confidence.
  • min_confidence (0.0–1.0): if the winning label's confidence is below this threshold, routing falls back to default_template_id instead of that label's mapped template.

If neither applies — the winning label has no template_id and no default_template_id is set — the request fails. See Failure modes below.

Failure modes

If a document classifies to a label with no template_id mapped, and the classifier has no default_template_id, the request ends with request_status: "failed" and a message like:

"Document classified as '<label>' but no extraction template is mapped to that category. Configure a template_id for this label (or a default_template_id on the classifier)."

The classify credit is refunded when this happens. To avoid it, either map every label to a template_id or set a default_template_id on the classifier.

Standard extract errors (invalid file, insufficient credits, etc.) apply as usual.

Pricing

The combined call charges a flat 1 credit per document for classification, plus normal extraction credits for the auto-selected template. The result itemizes both:

  • classify_credits — flat 1 credit/document
  • credits_used — extraction credits (unchanged pricing)
  • total_creditsclassify_credits + credits_used

Standalone Classify Document and Run Classification are also a flat 1 credit/document. Extraction pricing is unchanged.

Backward compatibility

  • POST /v1/extract / run_parser calls with a template_id and no classifier_id behave exactly as before.
  • The classification-related result fields are additive — null/0 for ordinary extract requests, so existing integrations are unaffected.
  • Standalone POST /v1/classify still requires an OCR'd document and still returns 400 if the document hasn't been processed yet — that caveat applies only to the standalone endpoint, not to this combined flow.

Full end-to-end example

# 1) Create a Classifier that maps each label to an extraction template
curl -X POST "https://api.documentpro.ai/v1/classifiers" \
-H "x-api-key: $API_KEY" -H "Content-Type: application/json" \
-d '{
"name": "Inbound Doc Router",
"classes": [
{ "label": "invoice", "description": "A commercial invoice", "template_id": "tmpl_invoice" },
{ "label": "purchase_order", "description": "A purchase order", "template_id": "tmpl_po" }
],
"default_template_id": "tmpl_generic",
"min_confidence": 0.6
}'
# -> { "classifier_id": "clf_9a1…", "name": "Inbound Doc Router", "configs": { … } }

# 2) Submit a document for combined classify + extract
curl -X POST "https://api.documentpro.ai/v1/extract" \
-H "x-api-key: $API_KEY" -H "Content-Type: application/json" \
-d '{ "url": "https://…/some-document.pdf", "classifier_id": "clf_9a1…" }'
# -> { "request_id": "req_…" }

# 3) Poll for the result
curl "https://api.documentpro.ai/files?request_id=req_…" -H "x-api-key: $API_KEY"
# -> classification + auto-selected template + extracted data + itemized credits

Next Steps