Ridgeway Legislature
Public API
Read-only JSON access to the 2026 Ridgeway Code of Statutes — including every chargeable offense of the Ridgeway Criminal Code (R.C.C., “penal codes”) and the Ridgeway Vehicle Code (R.V.C., “VCC”) — built for CAD/MDT systems, bots, and department tools.
Overview
Base URL:
https://legislature.rummytech.org/api/v1
Every endpoint returns JSON in a stable envelope. Lists return
{ "data": [...], "meta": { total, count, limit, offset } }; single resources return
{ "data": {...} }; failures return { "error": { code, message } } with a
matching HTTP status. Append ?pretty to any URL for indented JSON.
A machine-readable OpenAPI 3.1 specification is served alongside
the API — point your client generator or Postman/Insomnia import at it. Start exploring at
GET /api/v1, which links every endpoint.
/api/v1 contract is stable. Fields may be
added to responses at any time; existing fields will not be renamed, retyped, or removed
within v1. Breaking changes would ship as /api/v2 with v1 kept alive.
Quick start
Pull the complete penal charge list
# All ~110 chargeable R.C.C. offenses, in book order
curl "https://legislature.rummytech.org/api/v1/penal/charges"
Pull every VCC (vehicle code) charge
curl "https://legislature.rummytech.org/api/v1/vcc/charges"
Look up one charge from JavaScript
// Works from any origin — the API is CORS-open
const res = await fetch("https://legislature.rummytech.org/api/v1/charges/RCC%201.01");
const { data } = await res.json();
console.log(data.name); // "Treason"
console.log(data.class); // "felony"
console.log(data.jail_minutes); // 120
Search charges for an arrest report
curl "https://legislature.rummytech.org/api/v1/charges?q=murder"
Authentication & API keys
The API is readable without any credentials — anonymous requests get the shared per-IP rate limit (240/min). For apps that are formally connected, an administrator can issue an API key in the Senate Portal under Administrator → Developer API. A key:
- identifies your app — usage is tracked per key, and keys can be revoked individually without affecting anyone else;
- raises your rate limit — each key has its own requests-per-minute tier (default 1000/min) instead of sharing the anonymous IP bucket;
- can be scoped — a full-access key reaches every endpoint, while a
scoped key is restricted to the granted groups:
penal(/penal/…),vcc(/vcc/…), and/orstatutes(/statutes/…). The combined/chargesendpoints span both books, so they require bothpenalandvcc. Meta endpoints (/,/health,/meta,/openapi.json) are always reachable with any valid key.
Send the key either way:
curl -H "Authorization: Bearer rk_0123abcd…" "https://legislature.rummytech.org/api/v1/penal/charges"
curl -H "X-API-Key: rk_0123abcd…" "https://legislature.rummytech.org/api/v1/penal/charges"
A malformed, unknown, or revoked key gets 401 invalid_api_key (omit the header
entirely to fall back to anonymous access). A valid key calling outside its scopes gets
403 insufficient_scope with error.required and
error.granted. Keys are shown once at creation and stored only as
hashes; revocation takes effect within 30 seconds.
CAD / MDT integration guide
If you are syncing charges into another application, follow these rules:
-
Key charges by
type+code(e.g.penal1.01) or bycitation(R.C.C. § 1.01). The numericidis an internal database key that resets whenever the registry is re-imported — never store it. -
Sync with ETags. Every data response carries a registry-wide
ETag. Re-fetch withIf-None-Match; while nothing has changed you get an empty304in a few milliseconds. Poll/api/v1/meta(last_updated) if you prefer timestamps. -
Fetch whole books, not pages. The books are small (110 penal, 56 active VCC).
Omitting
limitreturns the complete book in one response — the intended sync pattern. -
Batch-resolve charge lists with
?codes=1.01,2.05,3.01(up to 50) when validating charges attached to a report. -
Handle duplicate bare codes. Penal
1.01(Treason) and VCC1.01(Speeding) both exist./api/v1/charges/1.01returns409 ambiguous_codewith both candidates; include the book (RCC 1.01) or use the per-book endpoints to stay unambiguous. -
Repealed charges disappear by default. Only
activeentries are returned unless you passinclude_inactive=true— on lists and on single-charge lookups, where a repealed charge answers404with a message noting it exists but is inactive. If a synced charge stops appearing, it was repealed or deactivated — retire it in your app too.
Recommended sync loop
// Runs on your app's schedule (e.g. every 10 minutes)
let etag = store.get("charges_etag");
const res = await fetch(base + "/charges", {
headers: etag ? { "If-None-Match": etag } : {}
});
if (res.status === 304) return; // nothing changed
const { data } = await res.json();
store.replaceAllCharges(data); // keyed by type + code
store.set("charges_etag", res.headers.get("ETag"));
Conventions
| Topic | Rule |
|---|---|
| Jail time | jail_minutes is minutes of in-game imprisonment. null means the charge carries no jail time. |
| Fines | fine is the maximum fine in dollars as a number. null means no monetary fine — but check penalty: some charges carry non-monetary penalties such as “Forfeiture of All Assets”. |
| Penalty text | penalty is the registry's human-readable penalty line, verbatim (e.g. Felony · Imprisonment: 120 minutes · …). Display it when you need exact published wording. |
| Offense classes | Exactly three: felony, misdemeanor, infraction. |
| Charge codes | Unique within each book; usually N.NN, occasionally with a subsection suffix like 4.01(a). Case-insensitive lookups; §, spaces, dashes, and book prefixes (RCC/R.V.C.) are all tolerated. |
| Encoding | URL-encode citations in paths: /charges/RCC%201.01. Responses are UTF-8. |
| Timestamps | ISO-8601 UTC (2026-07-21T02:25:49.521Z). |
| HTTP | GET/HEAD/OPTIONS only; anything else is 405. HEAD returns headers (including ETag) without a body. |
Errors & rate limits
Errors always use this shape:
{ "error": { "code": "not_found", "message": "No penal charge found with code \"99.99\"." } }
| HTTP | error.code | Meaning |
|---|---|---|
| 400 | invalid_parameter | A parameter failed validation; error.param names it (omitted when the whole request is malformed, e.g. NUL bytes). |
| 401 | invalid_api_key | An API key was presented but is malformed, unknown, or revoked. Anonymous requests never see this — omit the header to go anonymous. |
| 403 | insufficient_scope | The presented key lacks the scope for this endpoint; error.required and error.granted spell it out. |
| 404 | not_found | No resource matches; unknown paths also 404 with a pointer to this page. |
| 409 | ambiguous_code / ambiguous_citation | The identifier matches multiple resources; error.candidates lists up to 10 of them (error.total_matches gives the full count on citation lookups). |
| 405 | method_not_allowed | The API is read-only. |
| 429 | rate_limited | Over the applied limit — 240/min per IP anonymous, or the key's own tier. Honor Retry-After. |
| 500 / 503 | internal_error / degraded health | Server-side problem — retry with backoff. |
Every response except CORS preflights (OPTIONS, which are exempt from rate
limiting) includes X-RateLimit-Limit, X-RateLimit-Remaining, and
X-RateLimit-Reset (seconds until the window resets). Well-behaved integrations that
cache with ETags will never approach the limit.
Penal charges (R.C.C.)
limit, returns the complete book (~110 charges) in book order.
| Param | Type | Description |
|---|---|---|
q | string | Substring search over code, name, and description — e.g. q=murder. |
class | string | Filter by offense class; comma-separate for multiple: class=felony,misdemeanor. |
category | string | Chapter number: category=X.2 or bare category=2. |
codes | string | Batch resolve up to 50 codes: codes=1.01,2.05. Unparseable entries are a 400; well-formed codes that don't exist are simply absent from the result. |
sort / order | string | code (default) · name · class · fine · jail; asc/desc. Null fines/jail always sort last. |
include_inactive | bool | true to include repealed/inactive charges. |
limit / offset | int | Pagination (limit ≤ 500). Omit to fetch the whole book. |
Example response
{
"data": [
{
"id": 1480, // internal — do not persist
"type": "penal",
"code": "1.01",
"citation": "R.C.C. § 1.01",
"name": "Treason",
"description": "Whoever levies war against the State of Ridgeway, …",
"class": "felony",
"fine": null, // see penalty: forfeiture, not a fine
"jail_minutes": 120,
"penalty": "Felony · Imprisonment: 120 minutes · Fine: Forfeiture of All Assets · Punishable by conviction",
"category": { "number": "X.1", "name": "Crimes Against the State Government" },
"book": { "abbr": "R.C.C.", "name": "Ridgeway Criminal Code (R.C.C.)", "title_number": "X" },
"status": "active",
"updated_at": "2026-07-21T02:25:49.521Z"
}
],
"meta": { "total": 110, "count": 1, "limit": 1, "offset": 0 }
}
1.01, 4.01(a), or a full citation such as R.C.C. § 1.01 (URL-encoded).
VCC charges (R.V.C.)
Identical interface to the penal endpoints, over the vehicle code. All list parameters above apply.
include_inactive=true).
7.01 (Grand Theft Auto).
Combined charges
type (penal | vcc). Adds ?type= to every charge-list filter. With ?category=, use full chapter numbers (X.2, XI.7).
RCC 1.01, R.V.C. § 2.03, rvc-2.03, or a bare code plus ?type=. Bare codes that exist in both books return 409 ambiguous_code with candidates.
Statutes registry
The complete Code of Statutes — including the non-chargeable structural titles — as a titles → chapters → sections hierarchy. Charges are sections too, so R.C.C./R.V.C. entries also appear here with their full statutory context.
PEN/CIV/VEH/null) and chapter/section counts.
6.1, X.2, …), in order. Supports limit/offset/include_inactive.
2.38 → R.C.C. § 2.38); ambiguous suffixes return 409 with total_matches and up to 10 candidates.
classifier (PEN/CIV/VEH), title, include_inactive; default limit 25, max 100. Results include a highlighted snippet (<b> tags around matches).
application/pdf, typeset in the style of the official United States Code annual edition. Served inline; add ?download for an attachment. Shares the ETag/304 cache contract; rebuilt only when the registry changes. X-PDF-Source is compiled or prebuilt.
Service endpoints
penal_charges and vcc_charges), and last_updated — poll this to detect registry changes.
200 ok or 503 degraded. Never cached.
Reference: the Charge object
| Field | Type | Description |
|---|---|---|
type | string | penal (R.C.C.) or vcc (R.V.C.). Together with code, the stable key. |
code | string | Bare charge code, unique within its book — 1.01, 4.01(a). |
citation | string | Full legal citation — R.C.C. § 1.01. Also a stable key. |
name | string | Charge name — Treason, Grand Theft Auto. |
description | string? | The statutory text of the offense. |
class | string | felony · misdemeanor · infraction. |
fine | number? | Max fine in dollars; null if none or non-monetary (see penalty). |
jail_minutes | integer? | Max imprisonment in in-game minutes; null if none. |
penalty | string? | Published penalty line, verbatim. |
category | object | { number, name } — the book chapter. |
book | object | { abbr, name, title_number } — R.C.C. or R.V.C. |
status | string | active unless include_inactive=true was requested. |
updated_at | datetime | Last edit to this entry. |
id | integer | Internal. Resets on registry re-imports — do not persist. |
Reference: the Section object
Returned by the statutes endpoints. Same penalty fields as charges
(offense_class, fine, jail_minutes — null on
non-chargeable sections), plus body, history (source bills),
notes, and full { chapter, title } context objects. The stable key is
number (the citation).
Try it live
Requests run from your browser against this deployment.
Press Send — the response appears here.
Ridgeway State Senate