> ## 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.

# Resolve and verify a statute citation

> Take a statute or regulation citation string, resolve it to the governing section, and check a whole document's citations in one batch call

**What this gets you:** a way to catch a fabricated or wrong citation before it ships, whether it came from an LLM, a user, or your own database - one call tells you if a citation is real, and hands you the verified text if it is.

Given a Bluebook citation string like `42 U.S.C. § 1983`, `16 C.F.R. § 444.1`, or
`Del. Code Ann. tit. 13, § 1301`, resolve it to the exact section and get back the
section metadata with an official source link.
One route does the whole job: `/us/statutes/resolve` parses the citation
server-side and tells you whether it is real.
Use the `GET` form for a single citation and the `POST` form for up to 50 at
once, which is what you want when you are checking the citations in a document
rather than looking one up.

<Tip>
  Bluebook-formatted citations resolve most precisely. These all resolve, on
  either form of `/us/statutes/resolve`:

  * Federal statute: `42 U.S.C. § 1983` (annotated `42 U.S.C.A. § 1983` /
    `42 U.S.C.S. § 1983` and `Title 42 U.S.C. § 1983` also resolve)
  * Federal regulation: `16 C.F.R. § 444.1`
  * State statute: `Del. Code Ann. tit. 13, § 1301`
  * US Constitution: `U.S. Const. art. I, § 8`, `U.S. Const. amend. XIV, § 1`
  * State constitution: `Cal. Const. art. I, § 7`
  * Federal court rule: `Fed. R. Civ. P. 12`, `Fed. R. Evid. 702`
  * Federal Acquisition Regulation / DFARS: `FAR 52.219-14`, `DFARS 252.225-7001`
    (with or without periods, and with a pinpoint like `FAR 52.219-14(b)`),
    resolving straight into the existing CFR Title 48 records, no separate corpus

  The form a state's own courts print resolves too, not just the Bluebook form:
  `O.C.G.A. § 51-1-6`, `RCW 59.18.060`, `R.C. 2305.10`, `§ 292.290, RSMo`.
  The safest string to send is the `citation` value we returned to you.

  Agency guidance resolves as well, and it has no Bluebook form at all. Send
  its citation exactly as we printed it: `NY Insurance Circular Letter No. 4
      (2022)`, `TDI Commissioner's Bulletin B-0004-22`, `IL Company Bulletin
      2021-03`. This covers `STATE_AGENCY_GUIDANCE` (state insurance bulletins and
  circular letters) and `AGENCY_GUIDANCE` (IRS Notices, OCC Bulletins, CFTC
  staff letters and the rest). Because these are matched on the published
  string rather than parsed, the `citation` we returned is not merely the
  safest input here, it is the only one guaranteed to work.

  Scope `corpusType` (and `state`) when the citation names the corpus, so a
  same-numbered section in another corpus cannot rank first. Scope is a
  **constraint, not a hint**: a citation naming a different jurisdiction
  returns `resolved: false` rather than being forced into the scope, so leave
  the scope off unless you are disambiguating.

  See [Citation Formats](/docs/api-guide/concepts/citation-formats) for every form
  that resolves, the shared acronyms refused on purpose, and how `state`
  unlocks them.
</Tip>

<Warning>
  This recipe covers **statutes and regulations only** (USC, CFR, state codes,
  state regulations, constitutions, court rules, and other statute-corpus types).
  It is not for case law citations. Case law is not part of the Vaquill Developer
  API.
</Warning>

**Endpoints used:** `GET /us/statutes/resolve` for one citation, `POST /us/statutes/resolve` for up to 50 at a time.

## Resolve in one call

`GET /us/statutes/resolve` does the whole thing for you: it parses the Bluebook citation, resolves it to the exact section, and returns the section metadata with an official source link. The `resolved` flag tells you whether the citation is real, which is exactly the signal you want when verifying a citation an LLM produced.

<CodeGroup>
  ```bash cURL theme={"theme":"github-dark"}
  curl -G https://api.vaquill.ai/api/v1/us/statutes/resolve \
    -H "Authorization: Bearer vq_key_..." \
    --data-urlencode "cite=42 U.S.C. § 1983"
  ```

  ```python Python theme={"theme":"github-dark"}
  import requests

  resp = requests.get(
      "https://api.vaquill.ai/api/v1/us/statutes/resolve",
      headers={"Authorization": "Bearer vq_key_..."},
      params={"cite": "42 U.S.C. § 1983"},
  )
  data = resp.json()
  if data["resolved"]:
      sec = data["section"]
      print(sec["citation"], "->", sec["actId"])
  else:
      print("Unverified citation:", data["inputCitation"])
  ```

  ```javascript JavaScript theme={"theme":"github-dark"}
  const url = new URL("https://api.vaquill.ai/api/v1/us/statutes/resolve");
  url.searchParams.set("cite", "42 U.S.C. § 1983");
  const data = await (
    await fetch(url, { headers: { Authorization: "Bearer vq_key_..." } })
  ).json();
  if (data.resolved) {
    console.log(data.section.citation, "->", data.section.actId);
  } else {
    console.warn("Unverified citation:", data.inputCitation);
  }
  ```
</CodeGroup>

A resolved response carries the full section (the same shape as `/us/statutes/section/{actId}`), plus `subsection` when the citation had a pinpoint like `42 U.S.C. § 1983(b)(2)`. When `resolved` is `false`, treat the citation as **unverified**, not current.

<Note>
  `/us/statutes/resolve` is charged whether or not the citation resolves, because a confident "this does not resolve" is the answer you want when checking an LLM's output. Only server errors are refunded.
</Note>

<Note>
  **A guidance citation can be ambiguous, and we would rather answer nothing
  than guess.** Some regulators reuse one citation across several documents:
  Delaware reissues `DE Domestic/Foreign Bulletin No. 113` five times, Vermont
  twice, and Massachusetts has three separate documents citing `MA Bulletin
      1991-01`. Where the publisher's own citation does not identify a single
  document, `resolved` is `false` rather than one of the candidates picked
  arbitrarily. Reach those documents by `actId`, or with a
  `corpusType=STATE_AGENCY_GUIDANCE` search scoped to the state.
</Note>

## Resolve a whole document's citations at once

A brief, a memo, or a model's output typically carries dozens of citations, and
checking them one at a time is dozens of round trips.
`POST /us/statutes/resolve` takes up to 50 citations in one call and returns the
same verdict per citation.

<CodeGroup>
  ```bash cURL theme={"theme":"github-dark"}
  curl -X POST https://api.vaquill.ai/api/v1/us/statutes/resolve \
    -H "Authorization: Bearer vq_key_..." \
    -H "Content-Type: application/json" \
    -d '{"citations": ["42 U.S.C. 1983", "16 C.F.R. 444.1", "Cal. Civ. Code 1950.5"]}'
  ```

  ```python Python theme={"theme":"github-dark"}
  import requests

  resp = requests.post(
      "https://api.vaquill.ai/api/v1/us/statutes/resolve",
      headers={
          "Authorization": "Bearer vq_key_...",
          "Content-Type": "application/json",
      },
      json={
          "citations": [
              "42 U.S.C. 1983",
              "16 C.F.R. 444.1",
              "Cal. Civ. Code 1950.5",
          ]
      },
  )
  resp.raise_for_status()
  data = resp.json()

  print(f"{data['resolvedCount']}/{data['count']} resolved, "
        f"{data['creditsConsumed']} credits")
  for item in data["results"]:
      if item["resolved"]:
          print("OK  ", item["inputCitation"], "->", item["section"]["actId"])
      else:
          print("FLAG", item["inputCitation"])
  ```

  ```javascript JavaScript theme={"theme":"github-dark"}
  const resp = await fetch(
    "https://api.vaquill.ai/api/v1/us/statutes/resolve",
    {
      method: "POST",
      headers: {
        Authorization: "Bearer vq_key_...",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        citations: ["42 U.S.C. 1983", "16 C.F.R. 444.1", "Cal. Civ. Code 1950.5"],
      }),
    },
  );
  if (!resp.ok) throw new Error(`resolve failed: ${resp.status}`);
  const data = await resp.json();
  for (const item of data.results) {
    console.log(item.resolved ? "OK" : "FLAG", item.inputCitation);
  }
  ```
</CodeGroup>

A trimmed response:

```json theme={"theme":"github-dark"}
{
  "results": [
    {
      "resolved": true,
      "inputCitation": "42 U.S.C. 1983",
      "section": {
        "actId": "USC_T42_C21_S1983",
        "citation": "42 U.S.C. § 1983",
        "title": "Civil action for deprivation of rights"
      },
      "subsection": null
    },
    {
      "resolved": false,
      "inputCitation": "42 U.S.C. 19833",
      "section": null,
      "subsection": null
    }
  ],
  "resolvedCount": 1,
  "count": 2,
  "creditsConsumed": 4
}
```

Four things about the batch route are worth knowing before you build on it.

* **Every input gets an entry.**
  An unresolved citation comes back with `resolved: false`, never as an omission, so you can tell WHICH of thirty citations failed.
  The `results` array lines up with your de-duplicated input, in order.
* **Duplicates are collapsed** before pricing and before the response is built, so the same citation sent twice costs once and returns one entry.
* **Cost is per citation**, the same as resolving them one at a time.
  Batching buys a round trip and latency, not a discount.
  Read `creditsConsumed` rather than multiplying: citations we failed to process because of a backend error are refunded.
* **Scope the whole batch** with `state` or `corpusType` when every citation belongs to one jurisdiction or corpus.
  `22 CCR 76227` is California and `8 CCR 1206-2` is Colorado, and the acronym alone cannot say which.
  Omit both for a batch that spans jurisdictions and let each citation name its own.

<Note>
  `POST /us/statutes/resolve` accepts at most 50 citations, and rejects an empty
  list or a longer one with `422`. Chunk a longer document into batches of 50.
</Note>

## If you need your own match tolerance

Both resolve routes run the server-side citation parser, which knows every form
in [Citation Formats](/docs/api-guide/concepts/citation-formats), including the ones
a state's own courts print and the agency-guidance strings that have no Bluebook
form at all.

You only need to build your own matcher if you want tolerance the parser does
not offer, for example accepting a citation whose section number is off by a
digit and reporting it as a near miss.
In that case, send the citation as the `query` on `POST /us/statutes/search`,
compare the top result's `citation` and `citationShort` against your input under
your own rules, and call `GET /us/statutes/section/{actId}/body` when you are
satisfied.

Do the arithmetic before you commit to it.
That path bills a search plus a body where `/resolve` bills one cheaper call,
and a substring comparison is a weaker matcher than the parser you just
skipped.
It is the right call only when the tolerance itself is the point.

## Flagging what you cannot resolve

<AccordionGroup>
  <Accordion title="Return an unresolved flag, not a guess" icon="triangle-exclamation">
    `resolved: false` means **unverified**, not "not current". Do not fall
    through to a loosely related section, and do not present a near match as the
    answer. If you are checking a citation an LLM produced, an unresolved flag is
    exactly the signal that the model may have fabricated it.
  </Accordion>

  <Accordion title="Scope by corpus to cut false matches" icon="filter">
    The corpus token is usually right there in the citation. `... CFR ...` means
    `corpusType: "CFR"`; `... U.S.C. ...` means `"USC"`; a state code section
    means `"STATE"` with the two-letter `state`. Scope is a **constraint, not a
    hint**: a citation naming a different jurisdiction returns `resolved: false`
    rather than being forced into the scope, so leave the scope off unless you
    are disambiguating. `FAR`/`DFARS` citations live in CFR Title 48, so they are
    `corpusType: "CFR"`; add `source: "far"` or `source: "dfars"` to exclude
    every other CFR title from the ranking.
  </Accordion>

  <Accordion title="Text unavailable on a resolved citation" icon="rotate-left">
    A citation can resolve while its full text is not yet ingested. In that case
    `GET /us/statutes/section/{actId}/body` responds with `available: false` and
    `creditsConsumed: 0`. Treat it as resolved-without-text: you have a confirmed
    `actId`, citation and source link, but nothing you can quote yet.
  </Accordion>

  <Accordion title="Picking the official source link" icon="link">
    A resolved section carries several optional source URL fields and any of them
    may be null. Use the canonical preference order in
    [Text Formats and Source URLs](/docs/api-guide/concepts/formats#picking-the-best-available-format)
    rather than writing your own, so every surface in your product links the same
    reader to the same official page.
  </Accordion>
</AccordionGroup>

## Related

<CardGroup cols={2}>
  <Card title="Ground an LLM answer (RAG)" icon="brain" href="/docs/api-guide/recipes/rag-grounding">
    Use verified citations as grounding sources for an LLM answer.
  </Card>

  <Card title="Map a requirement to the law" icon="clipboard-check" href="/docs/api-guide/recipes/compliance-mapping">
    Go from a plain-language obligation to the governing sections.
  </Card>

  <Card title="Grounding LLMs" icon="shield-check" href="/docs/api-guide/grounding-llms">
    Why citation verification belongs in every legal AI pipeline.
  </Card>

  <Card title="Statute lookup chatbot" icon="comments" href="/docs/api-guide/recipes/statute-chatbot">
    A conversational front end over the same lookups.
  </Card>
</CardGroup>


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