The Go, Java, Kotlin and integration packages are not on any registry yet. Their pages show the intended coordinates and how to build from source.
All SDKs are MIT licensed.
The data you retrieve is covered by separate terms. See Rights and licensing.
The SDKs cover the US document only. For India, use the separate OpenAPI document directly.
Authentication
Create a key in your dashboard under API Keys. Keys start withvq_key_.
By default the client reads VAQUILL_API_KEY from the environment.
You can also pass api_key (Python) or apiKey (TypeScript) explicitly, and an explicit value wins over the environment.
The client rejects a key that does not start with vq_key_, and the key never appears in an error message or a log line.
Configuration
client.with_options(...) (Python) and client.withOptions({ ... }) (TypeScript) return a derived client that shares the key and the spend counter.
Every method also takes per-call timeout, max_retries / maxRetries, headers and idempotency_key / idempotencyKey options.
Which calls cost credits
A call is charged when the API declares theIdempotency-Key header on its operation. That is 25 of the 36 operations in the US document.
Both SDKs apply the same rule, and a test in each repo derives the list from the API contract.
Free calls: statutes.coverage, boards.list, every watch operation except the change diff (create, list, update, delete, test, changes and deliveries), credits.balance and pricing.get.
Prices are not hard-coded in the SDKs. client.pricing.get() is free and returns the live price list.
Some charged calls return 0 credits (for example a body that is not held), so read the figure from the response.
Retries and timeouts
The clients retry 408, 429 and 5xx responses, plus 409 only foridempotency_in_progress. Connection errors and timeouts are retried when it is safe.
Backoff starts at 0.5 seconds, doubles to an 8 second cap and is scaled down by 0 to 25 percent jitter. The default is 2 retries; max_retries=0 / maxRetries: 0 turns them off.
retry-after-ms wins over Retry-After, which wins over the body’s retryAfterSeconds. A wait above 120 seconds is not retried.
Never retried: a 402 insufficient_credits, daily_cap_exceeded, any other 4xx, and anything the server marks retryable: false.
Idempotency
Each charged call sends one generatedIdempotency-Key, reused on every retry of that call.
When the server honours the key it replays the stored response instead of charging again, and the response reports idempotent_replayed / idempotentReplayed.
Pass idempotency_key="..." (Python) or idempotencyKey: "..." (TypeScript) to choose your own key.
Errors
Every error derives fromVaquillError. Status errors carry the HTTP status, the request id, the parsed body, and code, retryable and a retry hint when the server sends them.
The code is checked first, then the status, so an unknown code still gives the status class.
A 422 message ends with the first validation reasons from the response’s
errors list, so you can read what was rejected without opening the body.
See Errors for the wire format.
Pagination
Pythoniter_* helpers and TypeScript *All methods hide the offset, cursor and sinceId/beforeId styles behind one iterator, with a way to read whole pages.
Listing watches, changes and boards is free.
Batch helpers
Three helpers wrap the batch endpoints and accept any number of inputs:resolve_batch_all / resolveBatchAll (500 citations per request), get_sections_all / getSectionsAll (50 section ids) and session_laws.get_batch_all / sessionLaws.getBatchAll (200 ids).
Each splits the input at the per-call cap, sends exact repeats once, returns the members of every response as one flat list in input order, and sends nothing for an empty input.
The spend guard is checked before every chunk, so a guard reached part way stops the remaining chunks.
A caller’s idempotency key is kept for the first chunk and suffixed with -<chunk number> for later ones.
These helpers are charged per item. The batch helpers are available in the Python, TypeScript, Go, Java and Kotlin clients.
Spend guard
Passmax_credits (Python) or maxCredits (TypeScript) when you create the client. Once responses on that client have reported that many credits, charged calls raise SpendGuardExceeded / throw SpendGuardExceededError before sending anything.
It checks what is already spent, not the cost of the next call. client.credits_spent / client.creditsSpent shows the running total, shared with derived clients.
While a guard is set, charged calls on the client run one at a time, from the check to the moment their credits are counted, so concurrent calls cannot all pass the check and overshoot the cap. Without a guard, calls keep full concurrency.
Logging
Python logs through the standardlogging module under the vaquill logger.
TypeScript takes a logger option (any subset of debug, info, warn and error, default console) and a logLevel option (default warn).
The API key is always redacted, and idempotency keys are logged by their first 8 characters only.
Raw responses
Python:client.with_raw_response.request(...) returns the parsed body with request_id, rate_limit and credits_charged_this_call.
TypeScript: .withResponse() on any call returns { data, response, meta }.
Both clients also have raw_request / rawRequest for endpoints newer than the SDK.
Python’s raw_request returns an APIResponse, so call .parse() for the JSON body.
TypeScript’s rawRequest returns the parsed value directly.
Webhook verification
Both SDKs verify the raw request body against the Standard Webhooks headers (webhook-id, webhook-timestamp, webhook-signature) with a 300 second tolerance, accept several signatures and a list of secrets for rotation, and treat a whsec_ secret as base64.
A whsec_ secret must be valid base64. Go, Java and Kotlin reject one that is not.
Python and TypeScript reject it from the first release after 0.2.0; version 0.2.0 of both still uses the text as the key, so check that your secret is copied in full.
Every client rejects an empty secret.
They can also read the legacy X-Vaquill-Signature: sha256=<hex> header, but only when you opt in.
Types
Python responses are Pydantic v2 models and the package shipspy.typed. TypeScript types are generated from the OpenAPI document.
Unknown enum values and extra response fields do not raise, so a new corpus type or field will not break an older SDK.
Python uses snake_case names and TypeScript uses camelCase. The SDK maps them to the wire names for you.
Versioning and support
- SDKs follow semantic versioning. Before 1.0, the API surface may change in minor versions.
- The SDK major version tracks the major version of the API contract.
- Python 0.2.0 and TypeScript 0.2.0 are the published versions. Go, Java and Kotlin are at 0.1.0 in source and unpublished.
- Python 3.11 and later are supported. Node 20 and later are supported, and the TypeScript client is tested on Node 20, 22 and 24.
- Breaking changes are listed in the release notes.
- Report bugs on the issue tracker of the vaquill-sdks repository. For account or billing questions, email support.
Next steps
Python
Install, quickstart, async and error handling
TypeScript
Install, quickstart and error handling
Integrations
LangChain, LlamaIndex and Vercel AI SDK tools. Not yet published
CLI
Search and resolve from the shell
API Reference
Every endpoint and schema

