Ridgeway State Senate seal Ridgeway State Senate DEVELOPER API v1

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.

No auth required · optional API keys CORS enabled — any origin ETag caching 240 req/min per IP GET / HEAD only OpenAPI 3.1

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.

Versioning promise: the /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/or statutes (/statutes/…). The combined /charges endpoints span both books, so they require both penal and vcc. 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. penal 1.01) or by citation (R.C.C. § 1.01). The numeric id is 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 with If-None-Match; while nothing has changed you get an empty 304 in 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 limit returns 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 VCC 1.01 (Speeding) both exist. /api/v1/charges/1.01 returns 409 ambiguous_code with both candidates; include the book (RCC 1.01) or use the per-book endpoints to stay unambiguous.
  • Repealed charges disappear by default. Only active entries are returned unless you pass include_inactive=true — on lists and on single-charge lookups, where a repealed charge answers 404 with 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

TopicRule
Jail timejail_minutes is minutes of in-game imprisonment. null means the charge carries no jail time.
Finesfine 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 textpenalty is the registry's human-readable penalty line, verbatim (e.g. Felony · Imprisonment: 120 minutes · …). Display it when you need exact published wording.
Offense classesExactly three: felony, misdemeanor, infraction.
Charge codesUnique 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.
EncodingURL-encode citations in paths: /charges/RCC%201.01. Responses are UTF-8.
TimestampsISO-8601 UTC (2026-07-21T02:25:49.521Z).
HTTPGET/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\"." } }
HTTPerror.codeMeaning
400invalid_parameterA parameter failed validation; error.param names it (omitted when the whole request is malformed, e.g. NUL bytes).
401invalid_api_keyAn API key was presented but is malformed, unknown, or revoked. Anonymous requests never see this — omit the header to go anonymous.
403insufficient_scopeThe presented key lacks the scope for this endpoint; error.required and error.granted spell it out.
404not_foundNo resource matches; unknown paths also 404 with a pointer to this page.
409ambiguous_code / ambiguous_citationThe identifier matches multiple resources; error.candidates lists up to 10 of them (error.total_matches gives the full count on citation lookups).
405method_not_allowedThe API is read-only.
429rate_limitedOver the applied limit — 240/min per IP anonymous, or the key's own tier. Honor Retry-After.
500 / 503internal_error / degraded healthServer-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.)

GET/api/v1/penal/charges List chargeable criminal offenses. Without limit, returns the complete book (~110 charges) in book order.
ParamTypeDescription
qstringSubstring search over code, name, and description — e.g. q=murder.
classstringFilter by offense class; comma-separate for multiple: class=felony,misdemeanor.
categorystringChapter number: category=X.2 or bare category=2.
codesstringBatch 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 / orderstringcode (default) · name · class · fine · jail; asc/desc. Null fines/jail always sort last.
include_inactivebooltrue to include repealed/inactive charges.
limit / offsetintPagination (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 }
}
GET/api/v1/penal/charges/{code} One charge by code — accepts 1.01, 4.01(a), or a full citation such as R.C.C. § 1.01 (URL-encoded).
GET/api/v1/penal/categories The book's chapters (“charge categories”) with per-class counts — ideal for CAD dropdowns.

VCC charges (R.V.C.)

Identical interface to the penal endpoints, over the vehicle code. All list parameters above apply.

GET/api/v1/vcc/charges List chargeable traffic offenses (56 active; 57 with include_inactive=true).
GET/api/v1/vcc/charges/{code} One VCC charge by code — e.g. 7.01 (Grand Theft Auto).
GET/api/v1/vcc/categories Vehicle-code chapters with per-class counts.

Combined charges

GET/api/v1/charges Both books in one list, discriminated by type (penal | vcc). Adds ?type= to every charge-list filter. With ?category=, use full chapter numbers (X.2, XI.7).
GET/api/v1/charges/{citation} Resolve a citation in any reasonable format: 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.

GET/api/v1/statutes/titles All 11 titles with classifier (PEN/CIV/VEH/null) and chapter/section counts.
GET/api/v1/statutes/titles/{number} One title (roman numeral, case-insensitive) with its chapter list.
GET/api/v1/statutes/chapters/{number}/sections Full section texts for a chapter (6.1, X.2, …), in order. Supports limit/offset/include_inactive.
GET/api/v1/statutes/sections/{number} One section by citation, whitespace/§-insensitive. A suffix matching exactly one section resolves too (2.38R.C.C. § 2.38); ambiguous suffixes return 409 with total_matches and up to 10 candidates.
GET/api/v1/statutes/pdf The entire code as a print-ready 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

GET/api/v1/meta Dataset edition, entity counts (including penal_charges and vcc_charges), and last_updated — poll this to detect registry changes.
GET/api/v1/health Liveness + database connectivity and latency. 200 ok or 503 degraded. Never cached.

Reference: the Charge object

FieldTypeDescription
typestringpenal (R.C.C.) or vcc (R.V.C.). Together with code, the stable key.
codestringBare charge code, unique within its book — 1.01, 4.01(a).
citationstringFull legal citation — R.C.C. § 1.01. Also a stable key.
namestringCharge name — Treason, Grand Theft Auto.
descriptionstring?The statutory text of the offense.
classstringfelony · misdemeanor · infraction.
finenumber?Max fine in dollars; null if none or non-monetary (see penalty).
jail_minutesinteger?Max imprisonment in in-game minutes; null if none.
penaltystring?Published penalty line, verbatim.
categoryobject{ number, name } — the book chapter.
bookobject{ abbr, name, title_number } — R.C.C. or R.V.C.
statusstringactive unless include_inactive=true was requested.
updated_atdatetimeLast edit to this entry.
idintegerInternal. 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.