Skip to content
Georgia Commons
Menu

Endpoints

Every route the API serves, grouped by collection, with its parameters. All of them are public reads except the two chat routes, which are the site's own.

Machine-readable https://georgiacommons.org/api/endpoints.md · https://georgiacommons.org/index.md · MCP https://mcp.georgiacommons.org/mcp

At a glance

Every collection answers the same eight routes below https://api.georgiacommons.org/api/{collection}, where the collection is code, bills, or opinions. Learn these and the rest is each collection's own document addresses.

RouteWhat it does
``The collection's root: its routes, and its coverage sentence with the qualifications.
/metaCoverage, counts, and corpus version, computed from the store at request time.
/searchFull-text search. Add in=headings to search only headings and titles.
/items?ids=Up to 20 documents in one request.
/verifyWhether a quotation appears verbatim in the stored text. POST.
/index/markdownThe collection's map: every unit at routing depth, one line each.
/about/markdownProvenance, coverage, license, and the independence statement.
/search/markdownThe same search as Markdown, about ten hits with snippets.
/sitemap-entriesDocument ids, for enumerating the collection. Bills and opinions give the whole list with dates; the Code pages it.

Reads need no key and no account. The full rules for identifiers, caching, and rate limits are on getting started.

Bills

Bills of the Georgia General Assembly, addressed by session and number. The doubled segment in /api/bills/bills/... is not a typo: the first is the collection, the second the resource.

GET/api/{slug}

A collection's root (/api/bills, /api/opinions, /api/code, /api/meetings): its routes, and its coverage sentence with the qualifications.

GET/api/bills/meta

Coverage, counts, sessions, and corpus version.

  • lang: es for the coverage sentence and qualifications in Spanish
GET/api/bills/recent

Bills with the newest activity first.

  • limit: 1 to 100, default 20
  • offset: 0 to 10000
  • lang: es for the Spanish translations of the summaries; quotes and source fields stay in English
GET/api/bills/filtered

The same slim list, narrowed.

  • session: a session slug such as 2025-2026
  • chamber: H or S
  • bill_type: B, R, CR, or JR
  • status: a status code: 1 Introduced, 2 Engrossed, 3 Enrolled, 4 Passed, 5 Vetoed, 6 Failed
  • q: at least two characters
  • limit, offset: as above
  • lang: es for the Spanish translations of the summaries; quotes and source fields stay in English
GET/api/bills/search

Full-text search over bill text, titles, and the labeled summaries. A bare bill number is a direct lookup.

  • q: required, 1 to 300 characters
  • in: headings to search only titles, tags, and subjects
  • session, chamber, bill_type, status: as above
  • limit: 1 to 100, default 20
  • lang: es for the Spanish translations of the summaries; quotes and source fields stay in English
GET/api/bills/sessions

Every session with its bill count.

GET/api/bills/sessions/{session}

One session: counts by kind, its caption subjects, and a window of bills.

  • kind: hb, sb, hr, or sr
  • start: 0 or more
  • limit: 1 to 500, default 500
  • lang: es for the Spanish translations of the summaries; quotes and source fields stay in English
GET/api/bills/resolve

Where a written bill reference leads. Accepts HB 136, H.B. 136, hb-136, House Bill 136, with or without a session. With none, the newest regular session that has the number; also_in names the same number in other sessions.

  • q: 1 to 200 characters
GET/api/bills/resolve/markdown

A redirect to the Markdown twin of the bill a written reference leads to, chosen as /resolve chooses. The site's /bills/hb136.md answers from it.

  • q: 1 to 200 characters
  • full=1: as on the twin
GET/api/bills/bills/{session}/{number}

One bill: sponsors, status, history, and the labeled summaries. The bill text is not included.

  • lang: es for the Spanish translations of the summaries; quotes and source fields stay in English
GET/api/bills/bills/{session}/{number}/full-text

The stored bill text with minimal metadata, as JSON. paragraphs is the same text joined into paragraphs for display; only line breaks change. has_marks says whether the text carries amendment marks.

GET/api/bills/bills/{session}/{number}/text

The bill text alone as text/plain. The page and its twin are named in the Link header.

GET/api/bills/bills/{session}/{number}/markdown

The bill's Markdown twin: frontmatter, the text as filed, then the labeled summaries.

  • full=1: add history, votes, and amendments
GET/api/bills/items

Several bills at once, with their text. Up to 20 a call; the response names the rest in next_ids.

  • ids: a comma-separated list, 1 to 2000 characters
  • lang: es for the Spanish translations of the summaries; quotes and source fields stay in English
GET/api/bills/votes/{vote_id}

One floor vote on a stored bill: its totals, with vacant seats counted apart from members not voting, the bills it covered, and how each member voted, with party, chamber, and district. The id is a vote's roll_call_id in a bill's votes_json, whose detail_url points here. A 404 when the vote is not stored.

POST/api/bills/verify

Whether a quotation appears verbatim in the stored bill, after the same normalization the ingestion quote filter uses. in names the reading that matched: text (the words as printed), text_as_amended (struck passages left out), or text_before_amendment (added passages left out).

  • body: {"id": ..., "quote": ...}
  • quotes shorter than 12 characters are refused with a 422
GET/api/bills/index/markdown

The map: sessions with their counts, kinds, and caption subjects.

GET/api/bills/about/markdown

Provenance, coverage, license, and the independence statement.

GET/api/bills/search/markdown

The same search as Markdown: about ten hits with an id, a title, a status, a snippet, and a URL.

  • q: the words; with none, the twin says how to search
  • session, in: as above
  • limit: 1 to 40, default 10
GET/api/bills/sessions/{session}/markdown

One session as Markdown, 250 bills a page.

  • type: hb, sb, hr, or sr
  • start: where the page begins
GET/api/bills/sitemap-entries

Every bill id with its date. No ETag on this one.

POST/api/bills/bills/{bill_id}/askSite only

The grounded question answering behind the chat panel on a bill page, streamed. This one route holds a server-side key and is not part of the public API.

Opinions

Opinions of the Supreme Court of Georgia, addressed by docket number. A record id (a CourtListener cluster id, or ga- and the docket for a record read from the court's own website) or a lower-case docket redirects to the docket address.

GET/api/opinions/meta

Coverage, counts, years, and corpus version.

  • lang: es for the coverage sentence and qualifications in Spanish
GET/api/opinions/recent

Opinions with the newest filing date first.

  • limit: 1 to 100, default 20
  • offset: 0 to 10000
  • lang: es for the Spanish translations of the summaries; quotes and source fields stay in English
GET/api/opinions/filtered

The same slim list, narrowed.

  • year: a comma-separated list
  • case_type: a comma-separated list
  • q: at least two characters
  • limit, offset: as above
  • lang: es for the Spanish translations of the summaries; quotes and source fields stay in English
GET/api/opinions/search

Full-text search over opinion text, case names, and the labeled summaries. A bare docket or reporter citation is a direct lookup.

  • q: required, 1 to 300 characters
  • in: headings to search only names, legal areas, and case type
  • year: 1900 to 2100
  • case_type
  • limit: 1 to 100, default 20
  • lang: es for the Spanish translations of the summaries; quotes and source fields stay in English
GET/api/opinions/search-by-name

Search case names alone. Prefix matches rank first.

  • q: at least two characters
  • limit: 1 to 100, default 20
GET/api/opinions/years

Every year with its opinion count.

GET/api/opinions/years/{year}

One year: counts by case type and a window of opinions.

  • case_type
  • start: 0 or more
  • limit: 1 to 400, default 400
  • lang: es for the Spanish translations of the summaries; quotes and source fields stay in English
GET/api/opinions/resolve

Where a written reference leads. Accepts a docket in any case, a reporter citation in 883 S.E.2d 746, 883 SE2d 746, or 308 Ga. 283 form, a record id, or a case name.

  • q: 1 to 200 characters
GET/api/opinions/cases/{ref}

One opinion by docket, citation, record id, or case name. The opinion text is not included. record_source says whether CourtListener or the court's website wrote the record.

  • lang: es for the Spanish translations of the summaries; quotes and source fields stay in English
GET/api/opinions/cases/{docket}/{cluster_id}

One opinion at its stable address, for the 77 dockets that carry more than one row.

  • full: add the summarized reasoning and the checked quotes
  • lang: es for the Spanish translations of the summaries; quotes and source fields stay in English
GET/api/opinions/cases/{docket}/{cluster_id}/text

The opinion text alone as text/plain.

GET/api/opinions/cases/{docket}/{cluster_id}/markdown

The opinion's Markdown twin: frontmatter, the court's text, then the labeled summaries.

  • full=1: add the reasoning, the checked quotes, and the upstream opinion records
  • start: one part of a long opinion's text, 60,000 characters at a time; a twin longer than that lists its parts
GET/api/opinions/cases/{docket}/{cluster_id}/full-text

The stored opinion text with its metadata, as JSON. paragraphs is the same text joined into paragraphs for display; only line breaks change.

GET/api/opinions/items

Several opinions at once, with their text. Up to 20 a call.

  • ids: a comma-separated list, 1 to 2000 characters
  • lang: es for the Spanish translations of the summaries; quotes and source fields stay in English
POST/api/opinions/verify

Whether a quotation appears verbatim in the stored opinion.

  • body: {"id": ..., "quote": ...}
  • quotes shorter than 12 characters are refused with a 422
GET/api/opinions/index/markdown

The map: years with their counts and case types.

GET/api/opinions/about/markdown

Provenance, coverage, license, and the independence statement.

GET/api/opinions/search/markdown

The same search as Markdown, about ten hits with snippets.

  • q: the words; with none, the twin says how to search
  • year, case_type, in: as above
  • limit: 1 to 40, default 10
GET/api/opinions/years/{year}/markdown

One year as Markdown, 400 opinions a page.

  • case_type
  • start: where the page begins
GET/api/opinions/sitemap-entries

Every opinion id with its date. No ETag on this one.

POST/api/opinions/clusters/{cluster_id}/askSite only

The grounded question answering behind the chat panel on an opinion page, streamed. This one route holds a server-side key and is not part of the public API.

The Code

The Official Code of Georgia Annotated, addressed by citation. Source text only: there is no chat route here, and no model anywhere in this path.

GET/api/code/meta

Coverage sentence and its qualifications, counts, corpus version, release date, and the bulk download addresses.

GET/api/code/tree

Every title with its headings and counts, plus both constitutions.

GET/api/code/sections/{ref}

One section by citation, written any of the ways people write it. Returns every version, whether it is in force now, and the neighboring sections. A range or a list redirects to /items?ids=.

  • version: one stored version rather than the current one
GET/api/code/sections/{ref}/text

The statute text alone as text/plain.

  • version
GET/api/code/sections/{ref}/markdown

The section's Markdown twin.

  • version
  • notes=all: the printed notes in pages of 60,000 characters instead of the 12,000-character cap
  • start: with notes=all, where the page of notes begins; each page names the next
  • subsection: one subsection, such as a-1
GET/api/code/titles/{title}

One title's chapters, with its articles, parts, and subparts.

GET/api/code/titles/{title}/markdown

The title's map as Markdown.

GET/api/code/titles/{title}/chapters/{chapter}

One chapter's sections, slim.

GET/api/code/titles/{title}/chapters/{chapter}/markdown

The chapter as Markdown.

  • full=1: inline the section text, under a 200,000-character cap
  • start: where the page begins
GET/api/code/search

Full-text search of the Code. A bare citation is a direct lookup; an act's short title returns the section that states it.

  • q: required, 1 to 300 characters
  • in: headings to search only catchlines and headings
  • title: 1 to 99
  • chapter
  • status: active (the default), repealed, reserved, redesignated, superseded, note_only, or all
  • scheme: ocga (the default), ga, or us
  • limit: 1 to 100, default 20
GET/api/code/acts

The short-title index: every name a statute gives itself, with the section that states it.

  • q
  • limit: 1 to 100, default 25
GET/api/code/items

Several sections at once. Up to 20 ids, or a range of up to 40 sections, under a 300,000-character budget.

  • ids: a comma-separated list; 44-7-30..44-7-35 for a range
POST/api/code/verify

Whether a quotation appears verbatim in the stored text.

  • body: {"id": ..., "quote": ...}
  • id is a citation, or ga-const:{slug} or us-const:{slug}
GET/api/code/index/markdown

The map: 53 titles with their chapters, about 50 KB.

GET/api/code/about/markdown

Provenance, coverage, license, and the independence statement.

GET/api/code/acts/markdown

Every short title, alphabetically, as Markdown, 300 a page.

  • start: where the page begins
GET/api/code/search/markdown

The same search as Markdown, about ten hits with snippets.

  • q: the words; with none, the twin says how to search
  • title, chapter, status, scheme, in: as above
  • limit: 1 to 40, default 10
GET/api/code/bulk

A JSON listing of the download bundle: the release page, the checksum file, and each asset with its address. Always a listing, never a redirect.

GET/api/code/bulk/{filename}

One asset of the bundle.

GET/api/code/sitemap-entries

Section ids, a page at a time.

  • page: 0 or more; omit it for the list of pages

The constitutions

The Georgia and United States constitutions as printed in the Code, under the same collection. {scheme} is ga or us.

GET/api/code/constitution/{scheme}

The articles and sections, plus any standalone provisions.

GET/api/code/constitution/{scheme}/index/markdown

Every provision, one line each.

GET/api/code/constitution/{scheme}/{citation}

One provision, by slug (art-i-sec-i-para-i) or by citation.

GET/api/code/constitution/{scheme}/{citation}/markdown

The provision's Markdown twin.

  • notes=all
  • start
  • subsection
GET/api/code/constitution/{scheme}/{citation}/text

The provision's text alone as text/plain.

Meetings

Machine transcripts of Georgia House and Senate floor sessions, standing committee meetings, and Rules Committee meetings, with the summaries Georgia Commons wrote. A meeting is addressed by its date and body: {day} is 2026-02-05 and {name} is house-rules, senate-judiciary, or house-floor-am for a meeting recorded in parts. Transcripts are not official records, speakers are not identified, and the video on the General Assembly's Vimeo channel is the record. The doubled segment in /api/meetings/meetings/... is the collection, then the resource.

GET/api/meetings/meta

Coverage, counts, years, the bodies, and corpus version, computed from the store.

  • lang: es for the coverage sentence and qualifications in Spanish
GET/api/meetings/recent

The newest published meetings first, each with its summary.

  • limit: 1 to 100, default 20
  • offset: 0 to 10000
  • chamber: house or senate
  • kind: floor, committee, or rules
  • lang: es for the Spanish summaries; transcripts stay in English
GET/api/meetings/search

Full-text search over the transcripts, the summaries, and the meetings' titles and committees, grouped by meeting. Each hit carries up to three moments of the transcript with their timestamps. A bill number alone (HB 629) lists the meetings that took the bill up, in direct.

  • q: required, 1 to 300 characters
  • in: headings to search only titles and committee names
  • chamber, kind: as above
  • body: a body such as senate-judiciary
  • limit: 1 to 50, default 20
  • lang: as above
GET/api/meetings/resolve

Where a written meeting reference leads: an address (2026-02-05/house-rules), the General Assembly's video id or Vimeo URL, a date, a body, or a body and a date (House Rules 2/5/2026). Answers one meeting, the meetings to choose from, or a body.

  • q: 1 to 300 characters
GET/api/meetings/meetings/{day}/{name}

One meeting: its body, date, the video address and the player to embed, the agenda, the session, the summary and the bill discussions (each bill named, each discussion with its moment in the video and the official record that confirms it), the official records of the meeting, and the meetings before and after. The transcript is not included. An address the meeting had before redirects.

  • lang: es for the Spanish summaries; record quotes stay in English
GET/api/meetings/meetings/{day}/{name}/transcript

The machine transcript as turns: seq, start_seconds, end_seconds, timestamp, the moment's video_url, and text.

  • start: the first turn, default 0
  • limit: 1 to 5000, default 2000; next_start names the next window
GET/api/meetings/meetings/{day}/{name}/text

The machine transcript alone as text/plain, one paragraph a turn led by its timestamp. The page and its twin are named in the Link header.

GET/api/meetings/meetings/{day}/{name}/markdown

The meeting's Markdown twin: frontmatter, the transcript notice, the labeled summary and bill discussions with one heading per bill, the bills read aloud, the official records, then the timestamped transcript.

  • start: one part of a long transcript, from this character; the frontmatter lists the parts
GET/api/meetings/bills/{bill_id}

The published meetings that took up a bill (the General Assembly's bill_id, as /api/bills gives it), oldest first, each with the moment in its video, the summary of the discussion, and the record that confirms it. Empty when none did.

  • lang: as above
GET/api/meetings/items

Several meetings at once, as the meeting route gives them. Up to 20 a call; missing names any not found.

  • ids: comma-separated addresses or video ids
  • lang: as above
POST/api/meetings/verify

Whether a quotation appears verbatim in a meeting's machine transcript, after the normalization the ingestion quote filter uses. A quote found is in the transcript; the video is what was said.

  • body: {"id": ..., "quote": ...} with the meeting's address or video id
  • quotes shorter than 12 characters are refused with a 422
GET/api/meetings/years

Every year with published meetings: its count, first and last dates, and hours of video.

GET/api/meetings/years/{year}

One year: its days with their counts, and a window of its meetings in date order.

  • chamber, kind: as above
  • start: 0 or more
  • limit: 1 to 500, default 100
  • lang: as above
GET/api/meetings/years/{year}/markdown

One year as Markdown, 400 meetings a page.

  • start: where the page begins
GET/api/meetings/days/{day}

One day's published meetings, each with its summary.

  • lang: as above
GET/api/meetings/days/{day}/markdown

One day as Markdown, each meeting with its summary.

GET/api/meetings/bodies

Every body with published meetings (each chamber's floor, its Rules Committee, its standing committees): its slug, name, count, and dates.

GET/api/meetings/bodies/{body}

One body's published meetings in date order.

  • start: 0 or more
  • limit: 1 to 500, default 100
  • lang: as above
GET/api/meetings/bodies/{body}/markdown

One body's meetings as Markdown, 400 a page.

  • start: where the page begins
GET/api/meetings/index/markdown

The map: the coverage, every body, and every year with its days.

GET/api/meetings/about/markdown

Where the meetings come from, how the transcripts and summaries are made, coverage, and the independence statement.

GET/api/meetings/search/markdown

The same search as Markdown: about ten meetings with their summary snippets and matching moments.

  • q: the words; with none, the twin says how to search
  • in, chamber, kind, body: as above
  • limit: 1 to 40, default 10
GET/api/meetings/sitemap-entries

Every published meeting's address with its last change. No ETag on this one.

The API itself

Two routes that describe the service rather than a document.

GET/

The API's own index: its version, the collections it serves, and where the MCP server is mounted.

GET/health

Whether the process is up and which collections are loaded, with each one's count and corpus version.