Skip to navigation

How to extract fields from a document

View as Markdown

Extract is schema-based key-value extraction. You define the fields you want and Sarvam Vision returns them as structured data. Use it for KYC, invoices, forms, and other structured data capture where you want specific fields, not the whole page.

You provideA document + a schema (or a saved config_id)
EndpointPOST /doc-ai/v1/job/extract
OutputThe fields you define, as JSON, CSV, or XLSX
Page limit20 pages per PDF or ZIP

Quick start

Extract takes the same document input, plus a schema describing the fields you want (or a saved config_id). The result is structured JSON with the field values you defined.

1

Submit the job

Send the document with a schema describing the fields you want (or a saved config_id). You get a job_id back right away.

import json, os
from sarvamai import SarvamAI
client = SarvamAI(api_subscription_key=os.environ["SARVAM_API_KEY"])
# Define the fields you want back
schema = {
"type": "object",
"properties": {
"policy_number": {"type": "string", "description": "Insurance policy number"},
"insured_name": {"type": "string", "description": "Name of the insured person"},
"sum_insured": {"type": "number", "description": "Total sum insured, in INR"},
},
}
with open("./insurance-policy.pdf", "rb") as f:
job = client.doc_ai.extract(
file=[("insurance-policy.pdf", f, "application/pdf")],
schema=json.dumps(schema), # or: config_id="cfg_abc123"
language="en-IN",
output_format="json",
)
print(job.job_id, job.status) # status starts as "pending"
2

Wait for it to finish

Poll get_status() every few seconds until the job reaches a terminal state.

import time
TERMINAL = {"completed", "partially_completed", "failed", "rejected"}
while True:
st = client.doc_ai.get_status(job_id=job.job_id)
print(f"status={st.status} pages={st.usage.pages_processed}/{st.usage.pages_total}")
if st.status.lower() in TERMINAL:
break
time.sleep(5)
3

Get the extracted fields

When the job is completed or partially_completed, fetch the field values.

if st.status.lower() in ("completed", "partially_completed"):
results = client.doc_ai.get_results(job_id=job.job_id)
print(results.result) # {"policy_number": ..., "insured_name": ..., "sum_insured": ...}
else:
print("job did not complete:", st.status)

Submit, wait, and get the output in one script. Save it next to your document and run it.

import json, os, time
from sarvamai import SarvamAI
from sarvamai.core.api_error import ApiError
client = SarvamAI(api_subscription_key=os.environ["SARVAM_API_KEY"])
# Define the fields you want back
schema = {
"type": "object",
"properties": {
"policy_number": {"type": "string", "description": "Insurance policy number"},
"insured_name": {"type": "string", "description": "Name of the insured person"},
"sum_insured": {"type": "number", "description": "Total sum insured, in INR"},
},
}
try:
# 1. Submit the job
with open("./insurance-policy.pdf", "rb") as f:
job = client.doc_ai.extract(
file=[("insurance-policy.pdf", f, "application/pdf")],
schema=json.dumps(schema), # or: config_id="cfg_abc123"
language="en-IN",
output_format="json",
)
print(job.job_id, job.status) # status starts as "pending"
# 2. Wait until it 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} pages={st.usage.pages_processed}/{st.usage.pages_total}")
if st.status.lower() in TERMINAL:
break
time.sleep(5)
# 3. Get the output
if st.status.lower() in ("completed", "partially_completed"):
results = client.doc_ai.get_results(job_id=job.job_id)
print(results.result) # {"policy_number": ..., "insured_name": ..., "sum_insured": ...}
else:
print("job did not complete:", st.status)
except FileNotFoundError:
print("Document file not found: ./insurance-policy.pdf")
except ApiError as e:
print(f"API error {e.status_code}: {e.body}")

For a one-page invoice and a schema with invoice_number, customer_name, and total_due, results.result is a flat object of your fields:

{
"invoice_number": "2001",
"customer_name": "Asha Rao",
"total_due": 4500
}

Parameters

ParameterRequiredDefaultDescription
fileYesThe document to process. See Languages, formats & limits.
schemaOne of schema / config_idThe fields to extract, as a JSON string. See Schema rules.
config_idOne of schema / config_idA saved schema to reuse. See Reuse a schema.
languageNoIndicA BCP-47 code such as en-IN or hi-IN. Always pass the correct code for best accuracy.
output_formatNojsonjson, csv, or xlsx.

Provide exactly one of schema or config_id. Sending both, or neither, returns a 400.

Common gotchas

  • schema is a JSON string, not an object. It is sent as a multipart form field. Use json.dumps(schema) in Python and JSON.stringify(schema) in JavaScript. Passing a dict in Python raises AttributeError: 'dict' object has no attribute 'read'.
  • The JavaScript SDK uses wire names, not camelCase. Parameters and response fields are output_format, job_id, and pages_processed.
  • file takes an array in both SDKs.
  • job_id is positional in JavaScript: getStatus(job_id), not getStatus({ job_id }).

Schema rules

The inline schema is a JSON object with these constraints:

  • Root must be type: "object" with a non-empty properties map.
  • Every field needs a type and a non-empty description. The description guides the model, so make it specific.
  • Supported field types: string, number, integer, boolean, object, array.
  • An optional enum may be supplied to constrain values.
  • Maximum nesting depth is 4.

Write specific descriptions

Each field’s description guides the model. A specific description outperforms a generic one:

WeakStrong
policy numberInsurance policy number, top-right, format ABC-1234
dateDate the policy was issued, as YYYY-MM-DD
amountTotal sum insured, in INR, digits only

Reuse a schema

To reuse the same fields across many calls without re-sending the schema, save it as a Config and pass its config_id in place of schema.

  1. In the Doc Agents dashboard at indus.sarvam.ai, start an Extract project, upload a document, and describe the fields you want.
  2. When the project finishes, open the Config tab, adjust the schema, and click Save.
  3. Copy the config_id shown on the saved Config (a UUID). Alternatively, click Deploy as API endpoint for a ready-made cURL command with the config_id filled in.

Then send it with your document:

job = client.doc_ai.extract(
file=[("insurance-policy.pdf", f, "application/pdf")],
config_id="019ff577-91b7-7dde-b128-c5f418d06881",
language="en-IN",
output_format="json",
)

Output formats

Formatoutput_format valueDescription
JSONjsonStructured field values (default)
CSVcsvFlat tabular output, one row per document
XLSXxlsxSpreadsheet output

Page limit: PDF and ZIP uploads are limited to 20 pages for Extract. Exceeding the limit returns a 400 Bad Request with code invalid_request_error. Split larger documents into batches before uploading.

Next steps