ALPHARETTAINTEL
THE DATA

Take the files.

Every figure on this site is read from a file, and every one of those files is published here at a URL that does not change. There is no key, no quota and no rate limit. If you want to check the arithmetic, disagree with a count, or build something else on top of it, this is the door — and checking the arithmetic is the point of publishing records at all.

Start at /api

13 DATASETS · 3.9 MB · AS OF 2026-07-31

GET /api returns an index of everything below: what each file is, how large it is, how many rows it holds, where it came from and what license it carries. It is the only URL you need to hard-code.

Each dataset is served at two addresses, and the difference matters:

  • /api/<name>.json is stable. It always resolves to the current file and revalidates on every request. Use this in a script.
  • /data/<name>.<hash>.json is immutable. The hash is of the contents, so that URL will serve the same bytes forever and can be cached for a year. Use this when you want to pin a version, or cite one.

A data refresh moves the second and never the first. Both are listed in the index, as url and immutable_url.

And as a spreadsheet. The JSON files are nested documents — every figure carries the production, page and sha256 it was read from, and that structure is the point of them. It is also the wrong shape if you work in Excel or Sheets, which is most people who want this. So the parts that genuinely are tables are published as CSV too: 6 tables, 11,688 rows, at /api/<name>.csv, listed under the file each one came out of. Every column is named in the index with a line saying what it means. They are RFC 4180 with CRLF endings and a UTF-8 byte-order mark, so Excel opens them correctly on a double-click instead of turning every dash into a question mark.

What is published

EVERY MACHINE-READABLE FILE THIS SITE SERVES
File What it is Size
usage.jsonHotlist alerts by year and topic Every figure chapter 03 states: 10,742,367 alerts across 7 years, by topic, each year's row carrying the produced document, page and sha256 it was read from.as a spreadsheet: alerts-by-year.csv 7 rows, 18 columns · alerts-by-topic-year.csv 75 rows, 4 columns21 KB
procurement.jsonPayments to Flock Group Inc. The check register and the produced check images: $1,061,482.88 documented across 27 checks.as a spreadsheet: payments.csv 25 rows, 10 columns95 KB
records.jsonThe document manifest Every produced document this site publishes — 99 of them, 398 pages — with its sha256, byte length, production and extraction method. This is the list the site itself is built from; it is not a directory listing, and one production is deliberately absent.as a spreadsheet: documents.csv 99 rows, 10 columns62 KB
metro-cameras.jsonMapped plate readers in the metro window 726 ALPR-tagged cameras as GeoJSON, 134 of them inside Alpharetta's boundary.391 KB
sharing-partners.jsonSharing partners, located The 1,389 of 1,562 partner agencies the Census gazetteer can place, as GeoJSON, with direction of exchange and distance.506 KB
states.jsonMapped cameras and Flock agencies, per state The national join behind chapter 01's United States view: 128,855 mapped plate readers against 2,685 agencies the EFF Atlas records as Flock customers.as a spreadsheet: states-table.csv 51 rows, 7 columns8 KB
doctext.jsonExtracted text of every published document One array, in manifest order, of the text extracted from all 99 documents. Personal names are withheld from this text where the site says so; the originals under /records/ are byte-identical to what the custodian produced and are what the published sha256 verifies against.1.2 MB
roads.jsonMetro road geometry Arterial and secondary roads under chapter 01's map, simplified and delta-encoded. Drawn, not authoritative.237 KB
roads-local.jsonMetro residential streets The z14 road tier, split out so a reader who never zooms in never fetches it.599 KB
boundary.jsonAlpharetta city limit The three rings of the corporate boundary, simplified for drawing. Every in-the-city classification on this site is computed against the unsimplified polygon, not this.4 KB
districts.jsonCounty lines and neighboring city limits What chapter 01's map reveals as it is zoomed in: the six counties and sixteen other municipalities sharing its window, with a label point for each.41 KB
us-states.jsonUS state outlines Outer rings only, generalized to about 900 m, keyed by postal code so the national view can fill them. For orientation, not for measurement.96 KB
streets.jsonEvery street in the window, and the cameras near it 11,431 named streets across 19 municipalities and counties, each with the camera sites standing within 250 feet of it and the distance to the closest one. 756 have a camera in range; for the rest the nearest is a median 1,970 feet away. A distance test, not a claim about which road a camera watches.as a spreadsheet: streets-table.csv 11,431 rows, 11 columns693 KB

Sizes are uncompressed; everything here is served brotli-compressed and is a good deal smaller over the wire. Licenses differ per file and are named on each row in the index — the produced records are public records, the mapping is OpenStreetMap under ODbL, the boundaries are US Census and public domain, and the joins this project computed are CC-BY.

The documents themselves

99 FILES · 398 PAGES · BYTE-IDENTICAL

The produced records ship exactly as the custodian handed them over — not recompressed, not linearized, not re-saved. The sha256 published beside each one is the chain back to that file, and optimizing a PDF for a few hundred kilobytes would break it.

GET /api/records.json is the manifest: one entry per document, with its path under /records/, its sha256, its byte length, which production it arrived in and how its text was extracted. GET /api/doctext.json is that extracted text, one array in the same order.

/records/ is not a browsable directory, and that is deliberate rather than an oversight: one production is withheld from this site because it concerns named individuals rather than the program, its files sit on the same disk, and a directory listing would publish them. The manifest is the index — it is what the site builds itself from, and it cannot list what it does not contain.

One difference between the originals and the extracted text is worth stating plainly, because a silent edit to a record would be worse than no publication at all: personal names are withheld from the extracted text in the 11 documents where they appeared, marked in place, and each affected page says so. The originals under /records/ are untouched and still verify against their published hash.

The two endpoints that are not files

POST /api/tip · POST /api/where · NO DATABASE

POST /api/tip takes a correction, a records tip or a note. It accepts application/json or an ordinary form encoding, with message required and email and about optional — leave the address blank to stay anonymous. It answers JSON to a JSON request and a redirect to a page otherwise, because the form works without JavaScript and that is the default rather than the fallback.

There is no read side. Nothing sent through it is stored in a database; the notification is the record. If it cannot be delivered you are told so rather than thanked.

POST /api/where takes {"q": "an address"} and answers with the geocoded point, how many cameras and camera sites stand within 250 feet of it, and how far away the nearest one is. It is what the map’s lookup falls back to when a street is not in this window — and it is the only thing on this site that sends anything anywhere, which is why it happens when you choose it and never while you type.

The split is deliberate. The address goes to the US Census geocoder — public domain, no key, no billing, the same agency whose boundaries this site already draws — and a coordinate comes back. The cameras are counted here, against all 115,103 sites this project holds, so what is near an address is worked out on this side and asked of nobody. The cost of choosing Census over a commercial geocoder is that it does not forgive typos; the street list on the map is the forgiving half and answers first.

Rate-limited, cached, and nothing is stored. It sends no CORS headers, so another site cannot call it from your browser — though anyone can call it directly, as they can any endpoint a public page uses, and the honest protection is that the upstream is free: there is no bill here to run up.

Using it

ATTRIBUTION YES · PERMISSION NO

Republish it, chart it, argue with it. Attribution is required by the licenses and is the only thing asked for. If you find an error, say so — a corrected figure is worth more to this project than an uncorrected one is to anybody.

Two things this data is not. It is not a register of deployed cameras: OpenStreetMap is a volunteer survey and records what somebody walked past, so every camera count here is a floor. And it is not the city’s publication — this is an independent project, not affiliated with, endorsed by, or operated by the City of Alpharetta, the Alpharetta Police Department, Flock Safety, or any government agency.