Vaquill
io.github.Vaquill-AI/vaquill-mcpVersion 0.5.0Search US and Indian statutes, regulations, constitutions, and court rules.
Status
Responds171 msAnswered our handshake without sign-in.- Last checked
- Nov 14, 2026, 14:44 UTC
- Latency
- 171 ms
- Remotes responding
- 3 of 3
- Sign-in
- OAuth sign-in, API key, No sign-in
- Hosting
- Hosted outside the EU (detected)
- Registry data as of
- Nov 14, 2026, 22:14 UTC
Data from the official MCP Registry, checked by run.zero. How we check
Connect
Streamable HTTP
https://mcp.vaquill.ai/in/mcpResponds356 msNo sign-in
Claude Code
claude mcp add --transport http vaquill-mcp https://mcp.vaquill.ai/in/mcp --header 'Authorization: Bearer <YOUR_TOKEN>'Replace <YOUR_TOKEN> before running.
Claude Desktop and claude.ai
Settings > Connectors > Add custom connector
Name: vaquill-mcp
Remote MCP server URL: https://mcp.vaquill.ai/in/mcp
This server expects the header Authorization.Cursor
{
"mcpServers": {
"vaquill-mcp": {
"url": "https://mcp.vaquill.ai/in/mcp",
"headers": {
"Authorization": "Bearer <YOUR_TOKEN>"
}
}
}
}Replace <YOUR_TOKEN> before running.
VS Code
code --add-mcp '{"name":"vaquill-mcp","type":"http","url":"https://mcp.vaquill.ai/in/mcp","headers":{"Authorization":"Bearer <YOUR_TOKEN>"}}'Replace <YOUR_TOKEN> before running.
Streamable HTTP
https://mcp.vaquill.ai/mcpSign-in required171 msOAuth sign-in
Claude Code
This server asks for sign-in. Your client opens the sign-in when it connects.
claude mcp add --transport http vaquill-mcp https://mcp.vaquill.ai/mcpClaude Desktop and claude.ai
Settings > Connectors > Add custom connector
Name: vaquill-mcp
Remote MCP server URL: https://mcp.vaquill.ai/mcpCursor
{
"mcpServers": {
"vaquill-mcp": {
"url": "https://mcp.vaquill.ai/mcp"
}
}
}VS Code
code --add-mcp '{"name":"vaquill-mcp","type":"http","url":"https://mcp.vaquill.ai/mcp"}'Streamable HTTP
https://reg-mcp.vaquill.ai/mcpResponds338 msNo sign-in
Claude Code
claude mcp add --transport http vaquill-mcp https://reg-mcp.vaquill.ai/mcpClaude Desktop and claude.ai
Settings > Connectors > Add custom connector
Name: vaquill-mcp
Remote MCP server URL: https://reg-mcp.vaquill.ai/mcpCursor
{
"mcpServers": {
"vaquill-mcp": {
"url": "https://reg-mcp.vaquill.ai/mcp"
}
}
}VS Code
code --add-mcp '{"name":"vaquill-mcp","type":"http","url":"https://reg-mcp.vaquill.ai/mcp"}'Built your own server? run.zero hosts MCP servers on European infrastructure.
Tools
53 tools
Read-only | Idempotent | Open world | ||
|---|---|---|---|---|
create_documentStarts translating a file you uploaded with `POST /in/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 includes it.
## Asynchronous
You get `202 Accepted`, a `documentId` and a `Location` header. Poll
`GET /in/translation/documents/{id}` until `status` is `completed` (or `failed`),
then download with `GET /in/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 /in/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.
Reading a scanned document is included in those translation pages: this route
never spends pages from the separate OCR pool.
## 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 p | No | No | Not declared | No |
fetchFetch one Indian enactment by the `id` from a `search` result, returning `{id, title, text, url, metadata}`. Also accepts a source URL or a bare path. NOTE: the India corpus serves an enactment as publisher links rather than inline text, so `text` carries the title and `metadata` carries the PDF, HTML and plain-text URLs to read. Prefer `get_act_text` if you can call it. | No | Yes | Not declared | No |
get_act_amendmentsThe amendment history recorded against one enactment: substitutions, insertions and omissions, each with the amending Act and its effective date (e.g. 'Subs. by Act 22 of 2023, s. 44 (w.e.f. 13-11-2025)'). Use to check whether a provision still reads as enacted before relying on its text. An empty list means no amendment was recorded, NOT that the Act was never amended. Cost: 5 credits. | No | Yes | Not declared | No |
get_act_sectionMetadata for one provision, including its citation, position in the act, structural features and references. Use when identifying or inspecting a provision without fetching its wording. Text is not included. Use get_act_section_body to read it. wordCount covers all passages, and actsReferenced normalizes whitespace before deduplication so publisher line breaks do not create duplicate acts. Cost: 2 credits. | No | Yes | Not declared | No |
get_act_section_bodyThe publisher's full text for one provision, taken directly from the act document without synthesized search headers. Use when reading, quoting or citing the provision's wording rather than its metadata. Amendments are not applied to this text. Check get_section_history for recorded changes before treating the wording as current law. Cost: 3 credits. | No | Yes | Not declared | No |
get_act_statusAn act's standing in three separate fields, publisherStatus for India Code's label, servedStatus for API availability and repealClaim for the publisher's sourced repeal record. Use when assessing whether an act remains law or why it is unavailable. These are not one verdict. A repealClaim does not verify that the repealing instrument was brought into force. Cost: 1 credit. | No | Yes | Not declared | No |
get_act_structureAn act's table of contents, with chapters and parts where the publisher supplies them and provisions listed beneath. Use when locating a section or planning a traversal of the act. hasHierarchy is false for most acts, where nodes is a flat section list rather than an error. Section numbers sort numerically with alphabetic suffixes attached. Cost: 2 credits. | No | Yes | Not declared | No |
get_act_textSource links for one enactment: the plain-text, PDF and HTML renderings, plus how many sections it holds. Use when the user wants to read or cite the Act itself rather than a matched section. Cost: 3 credits. | No | Yes | Not declared | No |
get_act_versionsEvery state of an act's text that the weekly corpus sync has recorded, oldest
first, with the one served today marked `isCurrent`.
**Cost: 1 credit.** Refunded when the act is unknown or the version archive
cannot be read.
Pass a `versionId` to `?version=` on `GET /acts/{actId}/sections/{n}` or
`GET /acts/{actId}/sections/{n}/body` to read the provision as it stood in that
version.
**`observedFrom` and `observedTo` are NOT legal effective dates.** They are when
the corpus sync observed the publisher's text in that state. A provision may
have been in force long before we first saw it, and a change we observed on a
Sunday may have commenced months earlier.
An act the sync has not yet recorded a history for returns one version,
`initial`, built from the passages we hold today: `observedFrom` is the earliest
time any of them was ingested and `observedTo` is null. `source` says which case
you are looking at. | No | Yes | Not declared | No |
get_changesThe act-level change feed of the weekly corpus sync: which acts were newly
loaded, had their text replaced, or had their amendment record or metadata
updated, run by run, oldest first.
**Cost: 1 credit.** Refunded when the feed cannot be read, and when no run has
published one yet.
Page with `cursor`: pass the `nextCursor` of one page as the `cursor` of the
next, unchanged. Store the last one you processed and you will see every change
exactly once. `since` (YYYY-MM-DD) starts the feed at the first run swept on or
after that date.
Each `changes` row carries the act's `versionId` after the change; read the
prior text with `GET /acts/{actId}/versions` and `?version=`.
`withdrawnCandidates` are items the publisher no longer lists. They are
reported, never applied: the act is still served until a person decides.
Dates are when the sync observed the publisher's text, not legal effective
dates. | No | Yes | Not declared | No |
get_corresponding_provisionsMap a repealed Indian criminal code to the 2023 code that replaced it, section by section: IPC to BNS and CrPC to BNSS, in force from 1 July 2024. Pass either side ('ipc' or 'bns' both work). Use whenever a source, a pleading or the user cites an old section number, so you answer under the provision actually in force rather than the repealed one. 'iea'/'bsa' return 404 until that mapping lands. Cost: 1 credit. | No | Yes | Not declared | No |
get_coverageIndia corpus counts for acts and provisions, broken down by jurisdiction, regulator and status, plus coverage depth. Use when checking whether the corpus supports a question before searching or interpreting an empty result. The depth block distinguishes text coverage from much thinner parsed amendment coverage. actsClaimingAmendmentsWithoutEvents marks missing records, not an absence of amendments. Free. | No | Yes | Not declared | No |
get_documentReturns the status of a document translation job.
**Free.** Never charged, so poll as often as the rate limit allows. A sensible
cadence is every 2 to 5 seconds.
**Authentication:** a `vq_key_` key holding `translate:read`.
## Status
| `status` | Meaning |
| --- | --- |
| `pending` | Queued, not started. |
| `processing` | Being translated. `progress` runs from 0 to 100. |
| `completed` | Done. Download it from `/content`. `pagesCharged` is set. |
| `failed` | Not translated and not charged. See `error.code`. |
`pagesCharged` is `null` until the job completes, because pages are charged
once, on completion.
## Errors
`error.code` is `INSUFFICIENT_TRANSLATION_PAGES` (your balance did not cover the
document when it was processed) or `TRANSLATION_FAILED`. Neither charges you.
## Example
```bash
curl https://api.vaquill.ai/api/v1/in/translation/documents/$DOCUMENT_ID \
-H "Authorization: Bearer $VAQUILL_API_KEY"
``` | No | Yes | Not declared | No |
get_document_contentDownloads the translated file once the job has completed.
**Free.** Never charged, and downloading again never charges again.
**Authentication:** a `vq_key_` key holding `translate:read`.
## Bytes, not a link
The file is streamed through this API. The response body IS the file: there is
no URL to follow, nothing that expires, and nothing to forward. Send the same
`Authorization` header you use for every other call.
## Which file you get
By default, the format you asked for in `outputFormat`. A job submitted with
`outputFormat=pdf` also produces a Word copy when one could be generated; add
`?format=docx` to download it. `?format=pdf` asks for the PDF explicitly. If the
format you ask for does not exist for this job the answer is 404.
`Content-Type` and `Content-Disposition` (an attachment with a filename) are set
from the file. `ETag` is supported (`If-None-Match` gives `304`) and so is
`Range` (`206`) for plain, unencrypted files, so an interrupted download can
resume.
## Not finished
While `status` is not `completed` this is a 404. Poll the status route first.
## Example
```bash
curl -o translated.pdf \
https://api.vaquill.ai/api/v1/in/translation/documents/$DOCUMENT_ID/content \
-H "Authorization: Bearer $VAQUILL_API_KEY"
``` | No | Yes | Not declared | No |
get_india_case_bodyThe judgment's full text, stitched from its stored passages. The header each
passage carries is removed and the overlap between adjacent passages appears once.
**Cost: 3 credits.** Refunded when no such judgment exists, when a backend fails,
and when the text is served with `complete: false`. A malformed `caseId` is a 422
and is not charged.
`complete` is checked against the number of passages the judgment should have.
When any are missing the text is still returned, `complete` is false,
`missingChunkIndexes` lists them, and the call costs nothing: a judgment with a gap
in it is not what you ordered. Send `include=segments` to get the offset of each
passage in `text`. | No | Yes | Not declared | No |
get_india_case_detailThe case-level record of one judgment: title, court, decision date, case number,
reporter citations, bench, disposition, parties, and whether the full text and an
archived source file are held.
**Cost: 1 credit.** Refunded when no such judgment exists or a backend fails. A
malformed `caseId` is a 422 and is not charged.
`links` are relative API paths for the other routes on this judgment. `reportedYear`
is the year of the reporter volume and can differ from the year of `decisionDate`.
A 404 means neither source holds the judgment. When a source was down and the other
did not find it, the answer is a 503, never a 404, because a miss cannot be trusted
while a source is unreachable. | No | Yes | Not declared | No |
get_india_case_fileThe judgment's archived source document, usually a PDF, as an attachment. Returns
the bytes, not JSON. The storage location is never revealed.
**Cost: 1 credit.** Refunded when no such judgment exists, when none is archived
(404 `case_file_unavailable`), and when the archive cannot be read right now (503).
A malformed `caseId` is a 422 and is not charged.
Check `hasFile` on `GET /cases/{caseId}/detail` first. | No | Yes | Not declared | No |
get_india_credit_balanceThe account-wide spendable credit balance shared by the India and United States APIs. Use for pre-flight checks or low-balance alerts from an India workflow. This returns the same balance as get_credit_balance, not a separate India allowance. Check bySource before assuming credits will last. Subscription credits expire at the period end. Free. | No | Yes | Not declared | No |
get_india_similar_casesJudgments whose text is semantically closest to this one, best first. The judgment
itself is never in the list.
**Cost: 2 credits.** Refunded when the source judgment does not exist (404) or a
backend fails (503). A malformed `caseId` or an unknown court is a 422 and is not
charged.
Similarity is of meaning only. It is not a statement that one judgment relies on,
follows or departs from another. `meta.partial` is true when one of the two judgment
collections failed and the list was built from the other; a partial list is charged.
Narrow with `court`, `courtType`, `decidedFrom` and `decidedTo`. | No | Yes | Not declared | No |
get_india_tribunal_matterEverything held about one matter: title, parties, bench, members, case number, decision date and
its quality, document availability, the forum's own link, and the order list where the forum has
one.
**Cost: 1 credit.** Refunded when no such matter exists in that forum or a backend fails. An
unknown forum code is a free 400.
**This route is the authority on `decisionDate`, and it can differ from the same matter's date in
a list or search response.** For NCLT it re-reads the forum's own table, which carries
`date_of_filing` and `disposal_date` where the shared view does not, and applies the rule those
columns make possible: prefer a real disposal date, and withhold a "decision date" that is merely
the filing date repeated. 36.8% of NCLT matters are that case. `dateQuality` and `dateBasis` tell
you which answer you are holding; a list row says `decision_date` because the view it came from
cannot see the difference.
It makes **no claim about whether the matter is still good law** and none about treatment: this is
a record of what a forum published, not a citator. | No | Yes | Not declared | No |
get_india_tribunal_matter_fileThe matter's document, as an attachment. Returns the bytes, not JSON. The storage location is
never revealed and this route never redirects.
**Cost: 1 credit.** Refunded when no such matter exists, when no document is held for it (404
`matter_file_unavailable`), and when the document cannot be read right now (503).
Check `hasFile` on the matter first. "Not held" is routine for one forum and rare elsewhere:
27,407 of NCLT's 63,487 matters have no document, against 3.5% across the whole corpus. `GET
/forums` gives the per-forum figure.
One document per matter, in every forum, including the two that also publish an order list. A
`fileSource` of `publisher` does not mean we lack a copy; it records where the scraper found the
document. | No | Yes | Not declared | No |
get_india_tribunal_order_fileOne **order's own** document, as an attachment. Returns the bytes, not JSON. The storage location
is never revealed and this route never redirects.
**Cost: 1 credit.** Refunded when no such matter exists, when the index names no order, when that
order has no document (404 `matter_file_unavailable`), and when the document cannot be read right
now (503).
**Why this exists.** `GET /file` serves ONE document per matter. On CAT CIS a matter has about
seven orders, each a separate PDF: 1,261,877 of them across 181,429 matters, every one held in our
archive. DRT adds 55,945. Before this route those documents could be listed but not fetched, and
`/file` returned a single order sheet with no way to ask for the others.
`index` is the `index` field on an order from `GET /orders`, 0-based. Get the list first and read
`hasFile` on the order you want: it is false on 886,208 of DRT's 942,153 order rows, and false on
every NCLT order, whose inline history records an encrypted token this service cannot address. The
twelve forums with no order list answer 404 here.
The index is stable for a matter, because the order list is built by one deterministic clause
(newest first) and a truncated list drops the oldest, so low indexes are the stable end. It is a
position in a list, not a permanent document id: if a forum publishes a new order, indexes shift. | No | Yes | Not declared | No |
get_page_balanceReturns the translation and OCR pages this API key's account can spend now.
**Free.** Never charged, so you can poll it to drive alerting or a pre-flight
check without the check itself costing you anything. Like the credit balance,
it is designed to still answer when the answer is "nothing": at a zero balance
a metered call 402s and tells you nothing, which is the moment the number
matters most.
**Authentication:** a `vq_key_` key holding `translate:read`.
## Pages, not characters
This product bills physical pages. A page of text is 2,000 characters; a page
of a document is a page of that document. Nothing here is counted in tokens.
## Two pools, and which one this API spends
`translation` and `ocr` are separate balances, not two views of one number.
**Translating a document, scanned or not, spends translation pages only.**
Reading a scan is included in that price: this API does not charge you OCR
pages for it. Budget from the `translation` pool.
The `ocr` pool exists for standalone text extraction, which is a separate
operation this API surface does not currently expose. It is reported here so
the figure is visible to an account that holds OCR pages, not because a
translation call will draw on it.
## Your free allowance applies here too
Pages are pooled per ACCOUNT, not per credential, so the monthly free allowance
your account holds is spendable through the API as well. A charge draws on
`free` before `paid`, which means the first pages of a month can cost nothing
and leave `paid` untouched.
Budget from `pagesRemaining`, which is `free` plus `paid`. Budgeting from `paid`
alone understates what you can spend.
## Separate from API credits
Translation pages and API credits are different currencies on different
ledgers. `GET /credits/balance` reports credits for the primary-law endpoints
and says nothing about pages; this endpoint reports pages and says nothing
about credits. Neither pays for the other.
## Pages are pooled per organization
If your key b | No | Yes | Not declared | No |
get_pricing_inCredit-to-price conversion and per-endpoint costs for the India legislation API, billed in US dollars. Use when estimating a workflow or comparing endpoint charges. Set region to US for United States primary-law pricing instead. Both surfaces use the same API key and account-wide credit balance. No authentication is required. | No | Yes | Not declared | No |
get_regulatory_coverageRead this before trusting an empty result anywhere else. A search returns nothing
both when the publisher published nothing and when we have not reached that
publisher for a fortnight, and only this route tells those apart.
**Cost: free.** It lists the valid `publisherId` and `sourceId` values for every
other `/reg` route.
Monitoring began 2026-08-23, so nothing earlier exists here, and coverage is not uniform across publishers: read an empty result together with `GET /reg/sources` rather than as 'nothing was published'. Nothing returned states whether a document is in force or superseded. A null `sourceCheckedAt` means the source has not been checked yet,
never that it was checked and is fine. | No | Yes | Not declared | No |
get_regulatory_documentThe full record for one document. The body, the capture history and the diff are
each opt in with `include`, because a body averages about 8,400 characters and most
callers do not want it.
**Cost: 1 credit**, whichever `include` values are asked for. Refunded when the call
fails, and when the id names no document.
`include=diff` compares the two most recent captures. When one side has no
extracted text, `delta.bodyComparable` is false and the line counts are null: a
diff of nothing is not a diff of zero changes. | No | Yes | Not declared | No |
get_regulatory_document_fileThe publisher's original file as we archived it: usually a PDF, sometimes HTML or
an image. Returns the bytes, not JSON, as an attachment.
**Cost: 1 credit.** Refunded when the call fails, including when no file was ever
archived.
Check `fileAvailability` on the document first. `available` means this route serves
the file. `not_archived` means we only ever read the listing, and this route answers
404 `content_not_archived`: do not retry it. A 502 `archive_unavailable` is a
different fact: we hold the file and cannot read it right now, so retrying may help.
Where we hold no copy, `publisherFileUrl` on the document is the publisher's own
link. | No | Yes | Not declared | No |
get_section_historyRecorded amendments to one provision, including the changing Act and section, effective dates and replaced wording where published. Use when tracing changes or checking whether published text reflects later amendments. An empty history can mean no changes or no parsed records, as coverage explains. Read appliedStatus on every event. Amendments are not applied to served text. Cost: 2 credits. | No | Yes | Not declared | No |
india_act_cited_byPaged inbound citations from provisions elsewhere in the corpus that name an act. Use when finding provisions that mention the act, rather than following its outbound references. Matching uses the act's title, not its identifier, so title variants and line breaks can be missed. Read matchBasis and treat results as a floor. total counts distinct citing provisions across all pages. Cost: 2 credits. | No | Yes | Not declared | No |
india_act_definitionsExtracted defined terms and their defining provisions, plus a separate definitionSections list. Use when a question turns on an act's own meaning of a term. Extraction covers only a minority of acts, so an empty result does not mean the act defines nothing. definitionSections identifies provisions to read even without extracted terms. terms is paged, but definitionSections is not. Cost: 2 credits. | No | Yes | Not declared | No |
india_act_subordinatePaged rules, regulations, notifications and orders the publisher records as made under an act. Use when looking beyond the parent statute to its subordinate instruments. Matching uses the parent's title, not parent_act_id, which is an India Code identifier that does not address this corpus. Check matchBasis. total counts distinct instruments across all pages, while returned counts rows on this page. Cost: 2 credits. | No | Yes | Not declared | No |
india_section_referencesOutbound citations from a provision to other enactments and sections of its own act. Use when following references outwards, not finding citations to the act. actId identifies served targets, while resolved false marks coverage gaps rather than parse failures. Results are not paged. totalActs and totalSections give full counts, so check truncated before treating returned references as complete. Cost: 2 credits. | No | Yes | Not declared | No |
list_act_filtersSelf-describing filter vocabulary: every category, state, department and status the acts corpus actually holds, with counts. Call this before filtering, so a query uses a value that exists instead of returning empty because the spelling was wrong. | No | Yes | Not declared | No |
list_actsBrowse and filter enactments rather than searching their text: by jurisdiction (central or a state), issuing regulator, year and status. Use when the user wants to know WHAT exists in an area before asking what it says, or to confirm an Act's exact title before citing it. Cost: 1 credit. | No | Yes | Not declared | No |
list_india_casesBrowse judgments by court and decision date, with no query. Newest first unless
`order` says otherwise.
**Cost: 1 credit.** Refunded when the call fails. A request we refuse as malformed
is not charged.
Only judgments whose full text is held and whose court and decision date are known
are listed, and a decision date that is implausible (later than today or before
1800) never leads a page. Paging is keyset based, so a page cannot repeat or skip a
judgment while the corpus is written to. There is no `total`: counting 13 million
rows would time out, so `meta.hasMore` and `meta.nextCursor` are the contract. | No | Yes | Not declared | No |
list_india_courtsThe canonical court registry: every `courtId` you can pass as `court`, with its name,
type, state, the raw court strings that mean it (`aliases`), and how many judgments
and which decision dates the corpus holds for it.
**Cost: free.**
Counts and dates are measured, not live: `countedAt` says when. A court with no
count has not been measured yet, which is not the same as holding nothing. | No | Yes | Not declared | No |
list_india_tribunal_forumsThe fifteen forums whose matters we hold, each with its record count, the span of decisions, how
many of its matters are judgments, and how many of its documents we actually have.
**Free.** Call it first: it carries the `code` every other route on this surface takes.
Four of the fifteen entries are not tribunals. The CCI is a regulator, the IBBI a board, RERA an
authority and the GST AAR an advance-ruling body; `forumType` says which is which, and the path
is `/tribunals` for all of them because splitting it would mean a caller has to know a body's
constitutional character before they can look up a matter.
`recordCount` is live from the publisher's own statistics table for the forums that have a row
there, and our measured figure, with `countedAt` null, for the forums that do not. If that table
cannot be read at all this endpoint answers `503` rather than serving the measured figures as if
they were live. `files` is per forum on purpose:
document coverage ranges from complete to 43% missing depending on the forum, so one
corpus-wide number would mislead every caller it reached. | No | Yes | Not declared | No |
list_india_tribunal_matter_ordersThe individual orders a forum recorded against one matter, newest first. A truncated list
drops the oldest.
**Cost: 1 credit.** Refunded when no such matter exists or a backend fails.
**Only three of the fifteen forums keep an order list** (`hasOrderList` on `GET /forums` says
which: CAT CIS, DRT and NCLT). For the other twelve this answers `200` with
`status: not_applicable` and an empty list. That is an answer, not an error: the matter exists
and the forum simply does not publish orders separately.
`status` is the field to read before the list:
- `listed`: the lookup ran. `orders` is the result, and may legitimately be empty.
- `not_applicable`: this forum publishes no order list.
- `unjoinable`: the key needed to find the orders is missing from this matter, so whether orders
exist is **unknown**. 2,694 DRT matters store an empty case number and land here. It is never
reported as "no orders", because that would assert something the lookup never established.
There is deliberately **no per-order file route**: `GET /file` serves the one document held for
the matter, in every forum, so that "the file" never silently means "the first of N orders" for
three forums and "the document" for the other twelve. | No | Yes | Not declared | No |
list_india_tribunal_mattersMatters by forum, bench, year, decision date or exact case number, newest decision first, paged
with a cursor.
**Cost: 1 credit per page.** Refunded when a backend fails. An unknown forum, a contradictory
filter or a bad cursor is refused for free, before the charge.
There is deliberately **no `total`**: counting 813,168 rows per request to produce a number
nobody pages to the end of is the defect this surface's sibling was built to avoid. Use
`hasMore` and `nextCursor`, and `GET /forums` for per-forum counts.
Order is `decisionDate` descending, then `caseId`, with undated matters last. **Do not sort on
`scrapedAt`**: it is when we collected the record, not when the matter was decided, and APTEL
matters decided in 2011 are all stamped 2026-03-13.
`caseNumber` matches exactly. It is not a free-text target: there is no index supporting a
substring match on it, so the term search covers `title`, `petitioner` and `respondent` instead. | No | Yes | Not declared | No |
list_languagesReturns every language this API can translate from and to.
**Free.** Never charged, so you can call it at start-up or on a schedule to
keep your own list current. It is rate limited like every other
key-authenticated route.
**Authentication:** a `vq_key_` key holding `translate:read`.
## Read this instead of hard-coding the list
A code you invent is refused with a 422 before any page is charged, and the
error names what is supported. Reading the list means a language we add works
on your side with no change, and it means you never pay to discover a typo.
Regional tags are accepted and narrowed to the language, so `hi-IN` is read as
`hi`. You do not need to strip them yourself.
## Scope
English plus the 22 languages of the Eighth Schedule to the Constitution of
India. These are the languages Indian courts and governments work in, and each
one is backed by script support in rendered output.
`auto` appears in this list as a SOURCE only. There is no translating into an
undetermined language, so sending it as `targetLanguage` is a 422 that says so.
## Direction is not decoration
`direction` is `rtl` for Urdu, Sindhi and Kashmiri. Honour it when you render
a language's own name and when you display translated output, or a correct
translation is shown wrongly.
## Example
```bash
curl https://api.vaquill.ai/api/v1/in/translation/languages \
-H "Authorization: Bearer $VAQUILL_API_KEY"
``` | No | Yes | Not declared | No |
list_page_packsReturns the page packs you can buy, and what they cost.
**Free.** Never charged, so you can poll it to keep your own price list current.
**Authentication:** a `vq_key_` key holding `translate:read`.
## Pages are sold in INR only
Translation pages are bought in Indian rupees with GST, through Razorpay. There
is no USD price for a page, which is why the translation rows in
`GET /api/v1/api-credits/pricing` carry `usdCost: 0` and `unit: "page"`. That
zero means "not priced in dollars", not "free". This route is where the real
price lives.
Pages are also a separate ledger from API credits. Credits do not buy pages and
pages do not pay for primary-law calls.
## Every money field is in paise
`priceInr`, `baseInr` and `gstInr` are in paise, 1/100 of a rupee, which is the
unit the payment is charged in. `priceInr` is GST-inclusive and is the amount
you pay. Only `pricePerPageInr` is in rupees, and it is a display figure.
Read this list rather than hard-coding a price. Larger packs are cheaper per
page, and both pools (`translation` and `ocr`) have their own packs.
## Example
```bash
curl https://api.vaquill.ai/api/v1/in/translation/packs \
-H "Authorization: Bearer $VAQUILL_API_KEY"
``` | No | Yes | Not declared | No |
list_regulatory_changesAn append only feed of corpus events: a document we had not seen (`new`), a new
capture of one we had (`rechanged`, carrying the current text), or one the publisher
removed from its listing (`retracted`).
**Cost: 1 credit.** Refunded when the call fails.
To follow this feed, call once with `since` (or with neither), then pass the previous
response's `nextCursor` as `cursor` from then on. Do not resume from `observedAt`:
timestamps here are not monotonic, so a timestamp resume can skip rows for good.
`cursor` together with `since` is a 400.
`total` is always `null` on this feed. It is walked, not sized, and null is not zero.
Monitoring began 2026-08-23, so nothing earlier exists here, and coverage is not uniform across publishers: read an empty result together with `GET /reg/sources` rather than as 'nothing was published'. Nothing returned states whether a document is in force or superseded. | No | Yes | Not declared | No |
list_regulatory_documentsOne route for searching and listing. With `q` it runs a full text search over
titles and extracted bodies and returns a marked `excerpt`. Without `q` it lists in
date order. Scope filters apply with or without `q`.
**Cost: 1 credit.** Refunded when the call fails. Fetch several known documents in
one call with a repeated `id`.
`total` is one of three things: a number (measured), `null` (not measured), or `0`
(genuinely empty). Null is not zero. Walk with `nextCursor` until `hasMore` is
false.
Send a list as a repeated key (`?publisherId=4&publisherId=7`). A comma separated
value is a 400 and is not charged.
Monitoring began 2026-08-23, so nothing earlier exists here, and coverage is not uniform across publishers: read an empty result together with `GET /reg/sources` rather than as 'nothing was published'. Nothing returned states whether a document is in force or superseded. | No | Yes | Not declared | No |
resolve_india_caseTurn a case id, a Supreme Court Reports citation or a case number within a court
into the judgment it names. Exact matches only.
**Cost: 2 credits.** A malformed input and a citation form the corpus does not carry
(`(2017) 10 SCC 1`, `AIR 1973 SC 1461`, `2019 SCC OnLine Del 1234`) are a 422 and are
not charged. A backend failure is a 503 and is refunded. Every other outcome is
charged, including `not_found`: a confident negative is the answer.
Give exactly one of `citation` or `caseNumber`. `caseNumber` needs `court`. A
`citation` is a case id (`2020_INSC_548`) or an SCR citation in any common spelling:
`[1982] 2 S.C.R. 186`, `(1982) 2 SCR 186`, `1982 2 SCR 186`.
Read `status` before `case`. `found` is exactly one judgment. `ambiguous` means
several judgments match exactly and all are in `candidates`: case numbers repeat
across case types, so this is common, and the route does not choose for you. | No | Yes | Not declared | No |
resolve_india_cases_batchThe same resolver over a list, for when you would otherwise loop.
**Cost: 2 credits per DISTINCT input.** Batching buys a round trip, never a
discount. Repeats are folded into one and charged once. An input we refuse
(`unsupported_citation_form`, `unknown_court`, `invalid_input`) is answered in its own
slot and is not charged. An input that fails on our side is `unavailable` and is
refunded on its own; it never voids the others.
Up to 100 distinct inputs, and up to 500 before repeats are removed. Each is
`{"citation": ...}` or `{"caseNumber": ..., "court": ...}`. Unknown fields on the body
are refused rather than ignored. | No | No | Not declared | No |
resolve_india_citationThe provision named by an Indian legal citation, accepting common abbreviations and flexible element order. Use when a user provides a citation rather than a research topic, such as s.302 IPC, O. 39 R. 1 CPC or Art. 21 of the Constitution. Subsection and clause references are supported. Malformed citations are rejected rather than reported as not found. Cost: 2 credits. | No | Yes | Not declared | No |
resolve_india_citations_batchProvision resolutions for a list of Indian legal citations, using the same resolver as resolve_india_citation. Use when several citations need resolving without individual calls. Accepts up to 50 distinct citations and 500 entries before deduplication. One citation failing does not invalidate the others. Unknown request fields are rejected rather than ignored. Cost: 2 credits. | No | Yes | Not declared | No |
searchGeneric corpus search over Indian Central and State legislation, returning `{id, title, url}` records for citation. Present so this server works in clients that require the standard search/fetch pair. Prefer `search_acts` if you can call it: it filters by category, state, year and status. Pair with `fetch` to read a result. | No | Yes | Not declared | No |
search_actsSearch Indian legislation down to the individual section: Central and State Acts plus the instruments of the principal regulators (SEBI, RBI, MCA, IRDAI, TRAI, DGFT). Use for any 'what does Indian law say' question. Supports boolean and phrase queries; filters by category, state, year and status. Returns sections with title, chapter and a sourceUrl pointing at the publisher's own document. The returned actId (e.g. 'IND_central_2065') feeds every acts tool. Cost: 2 credits. | No | Yes | Not declared | No |
search_india_casesSearch Supreme Court and High Court judgments by meaning and by words.
**Cost: 2 credits.** Refunded when the call fails. A request we refuse as
malformed (an unknown court, an inverted date range, a bad cursor) is not charged.
Each result is a judgment, not a passage: the passage that matched best is the
`snippet`. The query is embedded and matched as given: there is no query rewriting
and no mapping between old and new statute names.
Paging is honest about its depth. One query pages through at most 200 results
(`meta.searchDepthLimit`); a cursor beyond that is a 400 `search_depth_exceeded`
that asks you to narrow the query. There is no `total`: `meta.hasMore` and
`meta.nextCursor` are the whole contract. A cursor belongs to the query and filters
that produced it.
`meta.partial` is true when one of the two judgment collections failed and the page
was built from the other. A partial page is charged and may be missing judgments. | No | Yes | Not declared | No |
search_india_tribunal_mattersFind matters whose **title, petitioner or respondent** contains your term, narrowed by the same
filters as the browse route, paged with a cursor.
**Cost: 2 credits per page.** Refunded when a backend fails. A malformed query is refused for
free, before the charge.
🔴 **This searches metadata, not judgment text.** No extracted text exists anywhere in this
corpus: there is no `full_text`, `body`, `content`, `ocr` or `markdown` column on any relation
behind this API. A matter that does not match your term may still discuss it at length in a
document we hold and serve through `GET /file`. Every response states this in `searchScope` and
names the exact fields matched in `searchedFields`, so a client can branch on it rather than
inferring it from this paragraph.
`searchedFields` is three fields, not the four the public tribunals site searches: `caseNumber`
is excluded because no index supports a substring match on it (measured: 5.4-6.0s against
1.5-1.7s). Filter on it exactly with `GET /matters?caseNumber=` instead. | No | Yes | Not declared | No |
translate_textTranslates a piece of text and returns it in the same response.
**Charged in pages.** See the cost rules below. A failed translation is
refunded in full.
**Authentication:** a `vq_key_` key holding `translate:write`. A wildcard (`*`)
key includes it.
## Pages, not characters
This product bills pages. A page of text is 2,000 characters, and the cost is
`ceil(characters / 2000)`.
| Characters | Pages |
| --- | --- |
| 1 to 2,000 | 1 |
| 2,001 to 4,000 | 2 |
| 50,000 | 25 |
**Any non-empty text costs at least 1 page.** Unlike the dashboard, there is no
free floor on SIZE here: a 10-character request spends a page. Empty or
whitespace-only text is a 422 and costs nothing.
That is about size, not about your allowance. Your account's monthly free pages
are spendable through the API, and a charge draws on them first, so a short
request can still cost you nothing out of pocket.
## When you are charged and when you are not
Everything that can be checked up front is checked BEFORE the charge, and a
refusal costs nothing: an unsupported language (read `GET /in/translation/languages`
instead of hard-coding it), text over 50,000 characters (a 422, never a
truncation) and empty text.
If your balance cannot cover the pages you get a 402 and nothing is translated.
Once charged, if the translation fails or comes back empty the pages are
refunded and you get an error. You are never billed for a translation you did
not receive.
## Retries
Send an `Idempotency-Key` header. A retry of the same request with the same key
returns the original response and does not charge again.
## Limits
Text is at most 50,000 characters, because this route holds the connection open
while the translation runs. Anything longer belongs on the document routes.
## Example
```bash
curl -X POST https://api.vaquill.ai/api/v1/in/translation/translations \
-H "Authorization: Bearer $VAQUILL_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"text": "The | No | No | Not declared | No |
upload_fileUploads a source file and returns a `fileId` to translate it with.
**Free.** Never charged: pages are spent when a translation finishes, not on
upload or retrieval, so a file you never translate costs nothing.
**Authentication:** a `vq_key_` key holding `translate:write`. A wildcard (`*`)
key includes it.
## Why this route exists
`POST /in/translation/documents` does not accept a URL. It accepts the `fileId`
returned here, which refers to a file this API stored for your account. That is
deliberate: the API never fetches an address you name, so it cannot be pointed
at an internal service or at someone else's document. A `fileId` from another
account is a 404.
## Limits
- Types: `pdf`, `docx`, `txt`, `jpg`, `jpeg`, `png`, `tif`, `tiff`, `webp`, `bmp`.
- Size: at most 150 MB, and not empty.
- A `fileId` is valid for 24 hours. You can translate one file into several
languages by posting `/documents` more than once with the same `fileId`.
## `pageCount`
Physical pages for `pdf` and `docx`, which is what you will be charged. For
images and plain text it is `null`: their page count is only known when the job
runs, and `POST /documents` can then only check you hold at least one page.
## Example
```bash
curl -X POST https://api.vaquill.ai/api/v1/in/translation/files \
-H "Authorization: Bearer $VAQUILL_API_KEY" \
-F "file=@petition.pdf"
```
```json
{
"fileId": "3f2c9a52-8d2e-4a43-9e0b-5b6a1c7d9f10",
"filename": "petition.pdf",
"sizeBytes": 482113,
"pageCount": 12,
"expiresAt": "2026-11-02T12:34:56Z"
}
``` | No | No | Not declared | No |
Details
- Registry status
- Active
- Published
- Nov 13, 2026
- Updated
- Nov 13, 2026
- Website
- Not given
- Categories (suggested)
- Knowledge and notesDocumentsFiles and storageSuggested categories are assigned automatically from the registry text and may be wrong. Verified operators can correct them.
- GDPR
- Not declared