> ## Documentation Index
> Fetch the complete documentation index at: https://vaquill.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# CLI

> Search statutes, resolve citations and check credits from the shell

The `vaquill` command line tool wraps the Python SDK for quick lookups and scripts.
It uses the same `VAQUILL_API_KEY` variable as the SDKs.

## Install

```bash theme={"theme":"github-light"}
pip install vaquill
```

The CLI ships inside the `vaquill` package and adds no dependencies.

## Commands

```bash theme={"theme":"github-light"}
export VAQUILL_API_KEY=vq_key_...

vaquill search "adverse possession" --corpus-type USC --limit 5
vaquill resolve "42 U.S.C. 1983"
vaquill section <act_id> --body
vaquill credits
vaquill pricing
```

Output is a compact table by default. Add `--json` for the response as JSON on stdout, with the API's camelCase keys, so you can pipe it to `jq`.
Messages and `credits used: N` go to stderr, and a failure sets a non-zero exit code (see the table below).

`search`, `resolve`, `section`, the `statutes` and `session-laws` groups and `watches diff` spend credits. `credits`, `pricing`, `coverage`, `boards` and the other `watches` commands are free.
Set `--max-credits N` to refuse a charged call once N credits have been used in this run.
See the [SDKs overview](https://vaquill.ai/docs/api-guide/sdks/overview.md) for retry and credit behavior, which is the same as the Python client.

## Global options

The key comes from `--api-key` or the `VAQUILL_API_KEY` variable.
It is never stored on disk and never printed: error text and `--debug` logs have any `vq_key_` value replaced with `vq_key_[redacted]`.

| Option | Meaning |
| - | - |
| `--api-key KEY` | API key. Prefer the variable, because a flag is visible in the process list. |
| `--base-url URL` | API host. Defaults to `VAQUILL_BASE_URL`, then `https://api.vaquill.ai`. |
| `--timeout SECONDS` | Per-request timeout. |
| `--max-retries N` | Retries after the first attempt (default 2). |
| `--max-credits N` | Spend guard: a charged call is refused once N credits have been used in this run. |
| `--json` | Print the response as JSON on stdout. |
| `--no-color` | Never use colour. |
| `--debug` | Log requests to stderr and show a traceback on failure. |

Global options work before or after the command name, and the last one given wins.
Run `vaquill COMMAND --help` for the flags of any command.

## All commands

| Command | What it does | Cost |
| - | - | - |
| `search QUERY [--corpus-type T ...] [--state S] [--limit N] [--offset N]` | Search statutes, regulations and rules | charged |
| `resolve CITATION` | Resolve a citation to its section | charged |
| `section ACT_ID [--body]` | A section's metadata, or its text with `--body` | charged |
| `coverage` | What the corpus holds per jurisdiction | free |
| `credits` | Your credit balance | free |
| `pricing` | The credit price of every endpoint | free |
| `watches list [--limit N] [--offset N]` | List watches | free |
| `watches create CORPUS_TYPE [--state S] [--channel C] [--webhook-url U] [--webhook-secret S] [--email E]` | Create a watch | free |
| `watches delete WATCH_ID` | Delete a watch | free |
| `watches changes WATCH_ID [--limit N] [--since-id N] [--before-id N] [--order asc\|desc]` | Changes a watch recorded | free |
| `watches deliveries WATCH_ID [--limit N]` | Recent deliveries and delivery health | free |
| `webhook verify --secret S --id I --timestamp T --signature SIG [--file F] [--tolerance N]` | Verify a Standard Webhooks signature offline | none |
| `watches update WATCH_ID [--webhook-url U] [--webhook-secret S] [--email E] [--scope JSON]` | Change a watch. Only the options you pass change. | free |
| `watches test WATCH_ID` | Send a test event to the watch's channel | free |
| `watches diff WATCH_ID CHANGE_ID` | The before and after text of one change | charged |
| `boards [--corpus-type T] [--state S] [--limit N] [--offset N]` | The sources a watch can follow | free |
| `version` | Print the SDK and Python versions | none |
| `api METHOD PATH [--query K=V ...] [--data JSON] [--limit N] [--charged]` | Call any endpoint and print the JSON | see below |

Prices are not repeated here: run `vaquill pricing` for the live table.

## Command groups

Two groups cover the rest of the API. Every command in them is charged.
`search`, `resolve`, `section` and `coverage` also exist inside `statutes`.

| Command | What it does |
| - | - |
| `statutes resolve-batch` | Resolve many citations (charged per citation) |
| `statutes sections` | Fetch many sections at once (charged per section) |
| `statutes count [QUERY]` | Count sections in a scope or matching a query |
| `statutes divisions CORPUS_TYPE [--cursor C]` | Browse one level of a corpus hierarchy |
| `statutes changes ACT_ID` | List observed changes to a section |
| `statutes neighbors ACT_ID [--limit N]` | Sections related to a section |
| `statutes enactments ACT_ID` | The session laws that enacted a section |
| `statutes rulemaking ACT_ID` | Rulemaking for a section |
| `statutes part-rulemaking TITLE PART [--years N]` | Rulemaking for a CFR part |
| `statutes cited-by ACT_ID [--limit N]` | Sections that cite a section |
| `statutes definitions ACT_ID` | The terms a section defines or uses |
| `statutes cross-state ACT_ID [--limit N]` | Comparable sections in other states |
| `statutes extract-citations [TEXT] [--file PATH]` | Find and resolve the citations in a text |
| `session-laws search QUERY [--offset N]` | Search session laws by topic or wording |
| `session-laws list JURISDICTION [--cursor C]` | List a state's session laws with filters |
| `session-laws get ID [--jurisdiction S]` | One session law's record, without text |
| `session-laws body ID` | One page of a session law's text |
| `session-laws versions ID` | Every version of a session law |
| `session-laws batch` | Fetch many session laws at once |
| `session-laws changes [--since-id N] [--jurisdiction S] [--limit N]` | Changes since a cursor, oldest first |

Each command accepts the same global options.
The batch commands (`statutes resolve-batch`, `statutes sections`, `session-laws batch`) take their inputs as arguments or with `--file PATH` (one per line, `-` for stdin).
Run `vaquill statutes --help` or `vaquill session-laws --help` for the full flag list of each.

## Pages and cost

By default the CLI does not paginate or loop.
`search`, `watches list` and `watches changes` make exactly one request.
When the server reports more results, a notice on stderr names the flag that continues (`--offset N`, `--before-id N`, `--since-id N`).
Each continued search call is charged again.
Add `--all` to `search` to fetch every page, or `--max-pages N` or `--max-items N` (each implies `--all`) to stop early.
Every page is charged, so set a limit or `--max-credits` before you use `--all`.

## The `api` command

`vaquill api GET /api/v1/watches --query limit=5` sends one request and prints the JSON body.
`--query` can repeat, and a repeated key becomes a repeated query parameter.
`--data` takes a JSON string, or `-` to read it from stdin.
`--limit N` sets the `limit` query parameter.
The CLI cannot know which paths are charged, so pass `--charged` for one that is.
That adds an idempotency key, applies `--max-credits` and counts the credits in `credits used`.
When the body says `hasMore`, a notice names the next page value if the body has one (`nextCursor` or `nextOffset`).

## Webhook verification

```bash theme={"theme":"github-light"}
vaquill webhook verify --secret "$WEBHOOK_SECRET" \
  --id "$WEBHOOK_ID" --timestamp "$WEBHOOK_TIMESTAMP" --signature "$WEBHOOK_SIGNATURE" \
  --file body.json
```

It makes no network call and needs no API key.
The body must be the exact bytes received: a trailing newline added by `echo` makes the signature fail, so use `--file`, a redirect (`< body.json`) or `printf %s`.
`--secret` falls back to the `VAQUILL_WEBHOOK_SECRET` variable.
Timestamps more than `--tolerance` seconds (default 300) from the current time are rejected.
Only Standard Webhooks headers are accepted; the legacy header has no replay protection.
The signature is checked before the body is parsed, so a body that is not a Vaquill event still passes with `"event": null`.

## Exit codes

| Code | Meaning |
| - | - |
| 0 | Success |
| 1 | Any other error, including a failed webhook verification |
| 2 | Usage error (bad flag, unreadable file, invalid JSON) |
| 3 | Authentication: missing or malformed key, HTTP 401 or 403 |
| 4 | Insufficient credits (HTTP 402) or the `--max-credits` guard |
| 5 | Rate limited, including the daily cap (HTTP 429) |
| 6 | Not found (HTTP 404) |
| 7 | Network failure or timeout |

A failure prints one line to stderr, `error: MESSAGE (status N, code C, request id R)`, and no traceback unless `--debug` is set.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.