Skip to navigation

How to digitise a document

View as Markdown

Digitise runs full-document OCR. It extracts all the text, keeps layout and reading order, and parses tables into HTML, Markdown, or JSON. Use it when you want the whole document as clean, structured content: archival, search, RAG ingestion, or reading-order-faithful conversion.

If you only need specific fields (an invoice total, a policy number), extract them instead of post-processing a full digitise.

You provideA document
EndpointPOST /doc-ai/v1/job/digitise
OutputA ZIP with the primary file (HTML, Markdown, or JSON), per-page metadata, and a manifest
Page limit30 pages per PDF or ZIP

Quick start

API parameter names: Document AI uses language and output_format values "md", "html", or "json". Do not use language_code (it’s ignored) or "markdown" (it returns 400; use "md" instead). This differs from STT, translate, and LID endpoints.

JavaScript SDK: as of sarvamai 1.1.12, digitise() does not send output_format, so JavaScript always returns HTML. Use the Python SDK or cURL for Markdown or JSON.

1

Submit the job

Create and submit the job in one call. You get a job_id back right away.

import os
from sarvamai import SarvamAI
client = SarvamAI(api_subscription_key=os.environ["SARVAM_API_KEY"])
with open("./sample-document.pdf", "rb") as f:
job = client.doc_ai.digitise(
file=[("sample-document.pdf", f, "application/pdf")],
language="en-IN",
output_format="md",
)
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

Download the output

When the job is completed or partially_completed, ask for the download link and save the ZIP. It holds your Markdown, HTML, or JSON file. See Read the output.

import urllib.request
if st.status.lower() in ("completed", "partially_completed"):
dl = client.doc_ai.get_download_url(job_id=job.job_id)
urllib.request.urlretrieve(dl.url, "output.zip")
print("saved output.zip")
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 os, time
import urllib.request
from sarvamai import SarvamAI
from sarvamai.core.api_error import ApiError
client = SarvamAI(api_subscription_key=os.environ["SARVAM_API_KEY"])
try:
# 1. Submit the job
with open("./sample-document.pdf", "rb") as f:
job = client.doc_ai.digitise(
file=[("sample-document.pdf", f, "application/pdf")],
language="en-IN",
output_format="md",
)
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"):
dl = client.doc_ai.get_download_url(job_id=job.job_id)
urllib.request.urlretrieve(dl.url, "output.zip")
print("saved output.zip")
else:
print("job did not complete:", st.status)
except FileNotFoundError:
print("Document file not found: ./sample-document.pdf")
except ApiError as e:
print(f"API error {e.status_code}: {e.body}")

Parameters

ParameterRequiredDefaultDescription
fileYesThe document to process. See Languages, formats & limits for accepted types and size limits.
languageNoIndicA BCP-47 code such as en-IN or hi-IN. Always pass the correct code for best accuracy, and set en-IN for English documents.
output_formatNohtmlhtml, md, or json.

Output formats

The output_format parameter controls the primary content format. Choose html (the default), md (Markdown), or json.

Formatoutput_format valueDescription
HTMLhtmlRich HTML output for web rendering (default)
MarkdownmdHuman-readable Markdown output
JSONjsonStructured JSON with blocks containing text, tag, and bounding box

Read the output

The ZIP you saved in the last step holds the primary file, a metadata/page_NNN.json per page, and a manifest.json:

manifest.json
sample-document.pdf/
├── sample-document.md # primary file (.html or .json for those formats)
└── metadata/
└── page_001.json # one file per page

The folder and file names follow your uploaded file name. The download link is a plain GET and needs no API key header. To read the Markdown file straight from the ZIP:

import zipfile
with zipfile.ZipFile("output.zip") as z:
print(z.namelist())
markdown = next(z.read(n).decode() for n in z.namelist() if n.endswith(".md"))
print(markdown)

Match on .html or .json instead if you chose another output_format.

Limits

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

For ZIP files, include only JPG and PNG document pages in a flat structure (no nested folders). The API processes all pages in the archive and maintains page order based on filename.

Next steps