curl --request GET \
--url https://api.vaquill.ai/api/v1/us/session-laws/{session_law_id}/versions \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.vaquill.ai/api/v1/us/session-laws/{session_law_id}/versions"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.vaquill.ai/api/v1/us/session-laws/{session_law_id}/versions', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.vaquill.ai/api/v1/us/session-laws/{session_law_id}/versions"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}List every served version of a state session law
Every version of one state session law that we served or adopted, newest first, and which of them is
current. A law’s text can be corrected after we first serve it (a better extraction of the same
source, a re-collection), so the version you read yesterday may not be the one a plain call returns
today. This route lists each version with what identifies it (when we recorded it, its length, its
hash, how the text was taken) and how its text can be read. It carries no text: read one version with
GET /us/session-laws/{sessionLawId}/body?version=N.
Cost: 1 credit per call, however many versions the law has. A law with a single version answers a list of one and is charged: “this law has never changed” is the answer you paid for. Reading a version’s text is a separate call at the body price (6 credits per page), the same as the current text. A request that fails validation (422) is never charged. A law that is not found (404) is never charged. A failure on our side (500, 503) is refunded.
Edge cases. A law that is in the registry but has no version row (its current version is not set,
or it was withdrawn or merged into another law) answers 200 with versions: [], count: 0 and a
note, and is not charged; it is never the 404 “no law carries this id”. One answer lists at most
100 versions, newest first; truncated: true says older versions exist that it does not show.
Id only. This route takes a sessionLawId, not a citation: resolve a citation once with
GET /us/session-laws/{sessionLawId} and use the id it returns. A federal id (SAL_...) is a 404
(federal_session_law), as on /body.
What a version says. version is the number to send as version on /body. Numbers can have
gaps: a version we recorded and never served or adopted is not listed. Exactly one listed version has
isCurrent: true, and currentVersion repeats its number: it is the text a plain /body call
serves. recordedAt dates our copy of the text, not the act (approvedDate on the law does that).
totalChars and textSha256 identify the text: two versions with the same hash have the same text.
citation, title and approvedDate are as that version recorded them, so a correction that fixed
a title shows here.
textAccess | Reading that version’s text |
|---|---|
served | A plain call to /body?version=N. |
includeUnverified | The law is held back (textStatus: withheld); the text is readable only with includeUnverified=true, labelled by textReliability and reasonCode (it may show deleted or vetoed law as if it were enacted). |
none | There is no text for this version, or the law’s text may not be published (a licence that bars use, or text that failed our own validation). |
The law-level textStatus, textReliability and reasonCode are the same fields, with the same
meaning, as on /body. textReliability is omitted when no text of the law may be read, and
reasonCode when the law is served and verified. To check that nothing changed under you, compare
textSha256 here with the one you read; the cursor rules for an older version are on /body.
Example
curl "https://api.vaquill.ai/api/v1/us/session-laws/SSL_MN_2025S1_G_Y2025_C1/versions" \
-H "Authorization: Bearer $VAQUILL_API_KEY"
# then read the first version's text, one page at the body price
curl "https://api.vaquill.ai/api/v1/us/session-laws/SSL_MN_2025S1_G_Y2025_C1/body?version=1" \
-H "Authorization: Bearer $VAQUILL_API_KEY"
const id = "SSL_MN_2025S1_G_Y2025_C1";
const res = await fetch(`https://api.vaquill.ai/api/v1/us/session-laws/${encodeURIComponent(id)}/versions`, {
headers: { Authorization: `Bearer ${process.env.VAQUILL_API_KEY}` },
});
const { versions, currentVersion } = await res.json();
const older = versions.filter((v) => !v.isCurrent && v.textAccess === "served");
Related endpoints
GET /us/session-laws/{sessionLawId}/bodyreads the text of the current version, or of the one you name withversion. It also takesincludeUnverified=truefor a law we hold back.GET /us/session-laws/{sessionLawId}is the law’s record (dates, sources, code sections affected, whether its text is held); it always describes the current version.GET /us/session-laws/changesis the registry’s change feed: acorrectedentry there is how you learn that a copy of a law you hold may be stale, and this route is where you see what changed.GET /us/statutes/coveragesays which sessions we hold and how complete each is, under each jurisdiction’ssessionLawsblock.- Federal session laws (the Statutes at Large,
SAL_ids) are not served here. Read them withGET /us/statutes/section/{actId}.
Nulls. A field of a version with no value (citation, title, approvedDate, totalChars,
textSha256, textMethod, amendatoryMarkup, markupConvention) is null. textReliability and
reasonCode on the law are absent, not null, when they do not apply. The examples here leave the
nulls out.
Rate limits. Calls count against your key’s per-minute budget like every Data API route; a 429
carries Retry-After.
curl --request GET \
--url https://api.vaquill.ai/api/v1/us/session-laws/{session_law_id}/versions \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.vaquill.ai/api/v1/us/session-laws/{session_law_id}/versions"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.vaquill.ai/api/v1/us/session-laws/{session_law_id}/versions', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.vaquill.ai/api/v1/us/session-laws/{session_law_id}/versions"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}Authorizations
Headers
Optional. 16 to 255 visible ASCII characters (a UUIDv4 works). Repeating the same request with the same key replays the original 2xx response for 24 hours without charging again. The same key on a different request is rejected. With the account's cacheQueryDerivedData retention setting off, no body is stored and a retry answers 409 idempotency_replay_unavailable, still without a second charge.
16 - 255^[\x21-\x7e]+$"3f9c2a1e-7b44-4d0a-9c1e-5a6b7c8d9e0f"
Path Parameters
A state session law's id, for example SSL_MN_2025S1_G_Y2025_C1, from a /us/session-laws/list result.
A citation also works here on GET /us/session-laws/{sessionLawId}, and resolvedFrom says what your input matched. Name the state in the citation: Minn. Laws 2025, ch. 1, 2025 Minn. Laws ch. 1, Ch. 1, Laws of Minnesota 2025, Ch. 2025-12, Laws of Fla., 2025 Wash. Sess. Laws ch. 12, La. Acts 2025, No. 12, Pa. Act 12 of 2025, Minn. S.F. 1552 (2025), MN: Laws 2025, ch. 1. A form only one state uses needs no state: P.A. 104-0001 (Illinois), Pub. Act No. 26-151 (Connecticut), S.L. 2025-12 (North Carolina), Stats. 2025, ch. 12 (California), D.C. Law 25-713. The publisher's printed form (CHAPTER 2025-12, S.F.No. 1552) and the citation we print on every law also work. A form several states share (Laws 2025, ch. 1, HB 123, Act 12 of 2025) is a 404 with reason: needs_jurisdiction, the states it exists in and one candidate per state: we never guess the state. A citation naming several laws of one state (Minnesota 2025 has two Chapter 1s) is a 404 listing all of them, candidateCount and truncated saying whether the list is complete, and defaultSessionLawId the regular session's law where there is exactly one conventional reading. An id or citation that matches nothing in a session we have only partly collected is a 404 with reason: session_not_fully_collected and that session's coverage: the law may exist and not be held yet, so it is never charged, the resolve price included. A citation costs the route's price PLUS the /us/statutes/resolve price (2 credits), the second kept whether or not it resolves (an unresolved citation is a charged verdict) and refunded on an ambiguous citation (several laws carry it and none is chosen, so nothing resolved), on a partly collected session, on a citation we could not read as a state session-law citation at all (its detail lists the accepted forms) or on a failure. URL-encode the citation; one containing / cannot travel in a path segment.
Federal session laws (SAL_..., Pub. L. 118-5, the Statutes at Large) are served by /us/statutes/section, not here, and code citations (26 U.S.C. § 1) by /us/statutes/resolve.
1 - 300"SSL_MN_2025S1_G_Y2025_C1"
Response
The law's versions, newest first, exactly one of them current. A law with a single version answers a list of one, which is charged.
Response for GET /us/session-laws/{sessionLawId}/versions.
Whether we serve this law's text. held: the text is served by /us/session-laws/{sessionLawId}/body. withheld: we hold the text but a measured defect keeps it from being served, and withheldReason says what. not_held: we know the act exists and do not hold its text. pending: collected and not yet verified.
held, withheld, not_held, pending "held"
How far to trust the CURRENT text of this law, the same field as on /body: verified when the text passed our strike-through check, unverified when that check has not been completed, known_issue when we have evidence the text shows deleted law as if enacted. A served law can be any of the three (its text is still served); a held-back law is unverified or known_issue and its text is read with includeUnverified=true. Omitted when no text of this law may be read.
verified, unverified, known_issue "verified"
Set only when the law exists but the registry lists no version of its text for it (versions is empty, count is 0): the answer is free, nothing is charged. Omitted otherwise.
"The registry holds this law but lists no version of its text for it (its current version is not set: the law may be withdrawn, merged into another law, or its text not yet recorded). There is nothing to read, so nothing was charged."
Was this page helpful?

