Create Document
create_documentStarts translating a file you uploaded with POST /translation/files.
Charged in pages, when the translation finishes. Submitting costs nothing. The job spends one translation page per physical page of the document, once, on completion, and a job that fails spends nothing.
Authentication: a vq_key_ key holding translate:write. A wildcard (*)
key does not hold it: grant it by name in the dashboard.
Asynchronous
You get 202 Accepted, a documentId and a Location header. Poll
GET /translation/documents/{id} until status is completed (or failed),
then download with GET /translation/documents/{id}/content. Documents take
from seconds to several minutes depending on length.
What is checked before the job is queued
Everything refusable is refused before anything is queued: an unsupported
language (read GET /translation/languages), an unknown outputFormat,
courtStyle or engine, an unknown or foreign fileId (404) and an
insufficient balance (402).
The balance check uses the page count recorded at upload. For pdf and docx
that is exact. For images and plain text the count is not known until the job
runs, so the check only confirms you hold at least one page; if the real count
is higher than your balance the job ends failed with
INSUFFICIENT_TRANSLATION_PAGES and you are not charged.
Whether a scanned document also needs pages from the separate OCR pool is NOT
determined at submission and is not checked here. Read
GET /translation/balance, which reports both pools.
Formatting the output
courtStyle renders the translation to an Indian court's mandated paper, font,
margins and line spacing (Supreme Court and nine High Courts). Omit it for the
compact reader-friendly layout, which is about 45% fewer pages. The font mandate
applies when targetLanguage is English; an Indic target is always set in Noto
Sans, because the mandated Latin faces carry no Devanagari, while paper size,
margins and spacing still apply.
Tables, figures and document structure are preserved on every job. That is the default path, not an option, so there is no flag to set.
handwritten: true routes extraction through a vision model that reads
handwriting far better than the default OCR, at a higher cost per page to us.
Page billing is unchanged either way. Leave it false for born-digital or clean
typed documents, where the default is both cheaper and as accurate.
engine selects the translation model: omit it for gpt54 (recommended),
gpt54mini for cheaper and faster work on simple text, sarvam for Indic
languages. Billing does not change with the engine.
Removing stamps and signatures
Stamp, seal and signature images can be dropped from the rendered output. This is an ACCOUNT setting rather than a per-job field, so it applies to every job this account submits, through the API and the web app alike. Set it once in your Anuvad profile and this route honours it. Images are classified and only removed above a confidence threshold, so an unclear mark is kept rather than guessed away.
No URLs
This route does not accept a URL, only a fileId. A sourceFileUrl field is
a 422.
Duplicates
Submitting the same fileId with the same languages and format again while the
first job is still running returns that job (still 202) instead of starting a
second one. Once it has finished, the same request starts a new job.
Example
curl -X POST https://api.vaquill.ai/api/v1/translation/documents \
-H "Authorization: Bearer $VAQUILL_API_KEY" \
-H "Content-Type: application/json" \
-d '{"fileId": "3f2c9a52-8d2e-4a43-9e0b-5b6a1c7d9f10", "targetLanguage": "hi", "sourceLanguage": "en", "outputFormat": "pdf"}'{
"documentId": "9b1d5c0e-7a64-4f0a-8d3b-2c5e6f7a8b90",
"status": "pending",
"progress": 0,
"sourceLanguage": "en",
"targetLanguage": "hi",
"outputFormat": "pdf",
"pagesCharged": null,
"createdAt": "2026-11-01T12:34:56Z",
"completedAt": null,
"error": null
}Tool call template
Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.
{
"id": 1,
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"arguments": {
"fileId": "<fileId>",
"targetLanguage": "<targetLanguage>"
},
"name": "create_document"
}
}Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| engine | No | Translation engine. Omit for the default (`gpt54`), which is the balance we recommend. `gpt54mini` is cheaper and faster on simple text; `sarvam` is tuned for Indic languages. Page billing does not change with the engine. | |
| fileId | Yes | The `fileId` returned by `POST /translation/files`. | |
| courtStyle | No | Indian-court formatting profile for the rendered output. When set, the document uses that court's mandated paper, font, margins and line spacing instead of the compact reader-friendly layout. Omit it (the default) for the compact layout. An unknown value is a 422. Note: the font mandate is applied when `targetLanguage` is English. Indic targets are always rendered in Noto Sans, because the mandated Latin faces have no Devanagari coverage; paper size, margins and spacing still apply. | |
| handwritten | No | Set true for a scanned or handwritten document. Routes extraction through a vision model that reads handwriting far better than the default OCR, at a higher cost per page. Page BILLING is unchanged: pages are counted the same way either way. Leave false for a born-digital or clean typed document, where the default path is both cheaper and as accurate. | |
| outputFormat | No | Format of the translated document: `pdf` (default), `docx` or `text`. | |
| sourceLanguage | No | Language of the document, or `auto` (the default) to detect it. | auto |
| targetLanguage | Yes | Language to translate INTO. A code from `GET /translation/languages` with `target: true`. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||