Skip to navigation

How to classify documents

View as Markdown

Classify labels a whole document, or each page, against the categories you define. Without categories, it suggests a document type. Use it to route or triage documents before processing them.

You provideA document (+ categories, optional)
EndpointPOST /doc-ai/v1/job/classify
OutputA document type (or one per page), with evidence and a review flag
InputPDF, PNG, JPEG, TIFF; up to 500 pages and 512 MB per document

Quick start

Classify takes the same document input, plus the categories you want to choose between. It labels the whole document, or each page. Without categories, it suggests a document type.

import os, time
from sarvamai import SarvamAI
from sarvamai.core.api_error import ApiError
client = SarvamAI(api_subscription_key=os.environ["SARVAM_API_KEY"])
try:
# Create and submit a classify job in one call
with open("./sample-document.pdf", "rb") as f:
job = client.doc_ai.classify(
file=[("sample-document.pdf", f, "application/pdf")],
request={
"config": {
"scope": "page",
"categories": [
{"type": "Invoice", "description": "A supplier bill with totals and payment details."},
{"type": "Receipt", "description": "Proof of a completed payment."},
],
},
},
)
print("job created:", job.job_id, "| status:", job.status)
# Poll until the job reaches a terminal state
TERMINAL = {"completed", "partially_completed", "failed", "rejected"}
while True:
st = client.doc_ai.get_status(job_id=job.job_id)
print(f"status={st.status} phase={st.phase}")
if st.status.lower() in TERMINAL:
break
time.sleep(5)
# Fetch the decisions
if st.status.lower() in ("completed", "partially_completed"):
results = client.doc_ai.get_results(job_id=job.job_id)
for d in results.result.decisions:
print(d.input_page, d.type, d.classification_status, "review:", d.review_required)
except FileNotFoundError:
print("Document file not found: ./sample-document.pdf")
except ApiError as e:
print(f"API error {e.status_code}: {e.body}")

Classify options

  • config.scope: document (one decision for the file, the default) or page (one decision per page, returned in decisions).
  • config.categories: up to 20 entries, each with a type and a description. Names are yours to choose and must be unique. Omit them to let the API suggest a document type.
  • config.unmatched_behavior: suggest_type (the default) returns a suggested_type when no category fits; other returns type: "other" instead.
  • config.prompt: your own instruction text, up to 8,000 characters.
  • output.include_evidence: true returns the pages, text blocks, and region that support each decision.
  • language: a BCP-47 code such as en-IN. Omit it for the Indic default, as for Digitise.
  • reasoning_input: auto (the default) or text_only.

Write each category description so it separates that category from the others, for example “A supplier bill with totals and payment details” rather than “financial document”.

Choose which pages to read

Use one of config.max_pages (the first N pages), config.target_pages (such as [1, 6, 8]), or config.inspection. Combining them is rejected.

inspection.policyReadsExample
firstThe first N pages{"policy": "first", "count": 2}
lastThe last N pages{"policy": "last", "count": 2}
head_tailThe beginning and the end{"policy": "head_tail", "head_pages": 2, "tail_pages": 1}
explicitPage ranges you choose{"policy": "explicit", "ranges": [{"start": 1, "end": 2}]}
allEvery selected page{"policy": "all"}
adaptiveStarts with a selection, expands if needed{"policy": "adaptive", "initial": {"policy": "first", "count": 2}, "max_pages": 10}

count must be at least 1. Page ranges are 1-based and inclusive. For adaptive, initial can be first, last, head_tail, or explicit, and max_pages must cover the initial selection.

Reading only some pages is faster, but a bundle of several documents can look like one. In testing, a PDF holding an invoice followed by two receipts classified as Invoice when only the first page was read, and as mixed when every page was read. Use all, or split the file first.

Classify results

{
"job_id": "01a17998-120b-73dc-ad42-5cd66e0fe0ff",
"type": "classify",
"status": "completed",
"result": {
"scope": "document",
"type": "Invoice",
"classification_status": "matched",
"confidence": 1,
"reasoning": "The document is explicitly titled 'INVOICE #2001' and contains a total amount due.",
"review_required": false,
"review_reasons": [],
"suggested_type": null
},
"usage": {"pages_processed": 2, "pages_source": 2}
}
FieldMeaning
typeThe matching category. null when the status is unknown or mixed; other when nothing matched and unmatched_behavior is other
classification_statusmatched (a category fits), unknown (none fits), or mixed (the file holds several documents)
reason_codeOn unknown: no_matching_type, or insufficient_evidence when the pages were not enough to tell
confidenceA token-based score from 0 to 1, or null. It is not a measured probability of being correct
review_requiredWhether a person should check the answer. Low or missing confidence and unresolved answers require review
review_reasonsFor example NO_MATCHING_TYPE, MODEL_SCORE_UNAVAILABLE, or MULTIPLE_DOCUMENTS_DETECTED
suggested_typeA type you did not supply, with its name and supporting evidence. null when there is nothing to suggest

When no category matches, the job still completes: you get classification_status: "unknown" and reason_code: "no_matching_type", and, with suggest_type, the document’s own type in suggested_type. With scope: "page", result holds a decisions list with one entry per page instead of a single decision.

Results are short by default. Add ?include=details to the results request for the inspected pages and provenance.

Split, then classify

Classify reads the pages you point it at, so a bundle of several documents can look like one. Split first, then classify each child document by its document_ref. To classify one child document, send a JSON body instead of a file:

curl -X POST https://api.sarvam.ai/doc-ai/v1/job/classify \
-H "api-subscription-key: $SARVAM_API_KEY" \
-H "Content-Type: application/json" \
-d '{"input": {"document_ref": "doc_..."}, "config": {"scope": "document", "categories": [{"type": "Invoice", "description": "A supplier bill."}]}}'

Classify shares its request behaviours (multiple documents, Idempotency-Key, execution: "auto", capabilities) with Split. See Request behaviours.

Next steps