CityScroll
NYC’s public record, linked

API and feeds

← Back to CityScroll

Every view on CityScroll has a machine-readable twin. No key and no account are required. Endpoints are rate-limited and cached, and none touches a paid service. Base URL: https://api.cityscroll.org.

Capability API contracts

This list uses the runtime registry. The JSON catalog has schemas, limits, examples, source, freshness, and delivery details.

See the JSON catalog for contracts. HTTP, feeds, bulk exports, and model tools use separate paths.

Feeds — any search as RSS / JSON / calendar

GET /feed.xml (Atom) · GET /feed.json (JSON Feed 1.1) · GET /feed.ics (subscribable calendar — one event per dated notice). Edge-cached 15 minutes.

ParamMeaning
lensmoney · land · property · rules · meetings · entity
qkeywords (up to 4)
agencyagency name as printed in the record
minminimum award $ (money lens → award feed)
kind + nameentity lens: kind=vendor|agency, name=… — vendor names are matched by normalized stem, so suffix/case variants are included
https://api.cityscroll.org/feed.xml?lens=rules&agency=Buildings
https://api.cityscroll.org/feed.ics?lens=meetings&q=community%20board
https://api.cityscroll.org/feed.json?lens=entity&kind=vendor&name=Sinergia%20Inc

Property locations

GET /property-locations returns the latest Property Disposition notices with extracted site addresses, boroughs, tax lots, BBLs, and resolved map geometry where available. The daily view is cached at the edge for 30 minutes. City Record Online remains the source of truth.

JSON

Agency-name crosswalk

GET /agencies lists each agency name as written in City Record Open Data and connects it to one name used by this site. Add ?format=csv for CSV. The endpoint needs no key, allows cross-site requests, and is cached for one day.

JSON · CSV

ParamMeaning
raw_stringexact text in agency_name. One row for each distinct source string
canonical_idstable text id assigned by the crosswalk
canonical_namename this site uses for the group
variantsevery source spelling connected to the same id

Matches use case, punctuation, known short forms, and administrative families. New spellings may start with their own id until the crosswalk is updated. The crosswalk helps connect records. It is not an official agency registry.

Batch cross-reference

POST /batch with {"names": ["…", …]} (≤10 names/request, 30 requests/day/IP). For each name, awards means award/intent notices naming that vendor (name-stem matched, all years). Mentions means full-text hits in the last two years of editions. Entity means the vendor-profile permalink when awards exist.

Permalinks

Everything on the site has a stable address you can link or cite:

/#notice/<request_id>one notice — at-a-glance summary, flags, Checkbook dollars, full text
/vendors/<stem>/vendor profile (name variants resolved by stem)
/agencies/<id>/agency profile
/#matter/<pin>a procurement matter as a timeline, Checkbook payments included
/#money?agency=…&q=…&m=…any filtered view — the URL is the state

Shared investigations

POST /inv stores a pin-list snapshot (structured fields only, ≤32KB, 90-day TTL, 10/day/IP) and returns an id. GET /inv/<id> reads it back. The site renders these at /#investigation/shared/<id>.

Public stats

GET /stats — served-product coverage as aggregate counts (record sets by section, each with its record type, counting rule and its own evidence date). It's cached about 15 minutes. Human-readable version: stats. Related: digest emails link notices via GET /r/<kind>/<request_id>, which checks the id against known notices, redirects to the matching permalink, and records a per-day count.

Subscribe by email

Email [email protected] describing what you want in plain English — for example, "construction contract awards over $500k" or "rezoning notices in Brooklyn". The watch starts as soon as the request is processed. A welcome email states exactly what it follows and includes manage and one-click unsubscribe links. Daily ceilings apply.

MCP — for AI assistants

POST /mcp (Streamable HTTP, JSON-RPC) — point an MCP client at https://api.cityscroll.org/mcp. The generated catalog below is the authoritative tool inventory. It distinguishes each tool's name, read, and mutation class. Created watches start immediately and send a welcome email stating their scope. Watch management stays behind the emailed manage and unsubscribe links — knowing an address never reveals or controls its subscriptions. Per-IP and daily model-call ceilings apply. Machine-readable catalog: JSON.

Available tools (generated from the runtime declarations):

  • search_federated read — Search the registered public CityScroll lenses in one bounded result set. Optional scope selects only allowlisted registered lenses. Preserves per-lens coverage, source observations, exact object routes, and federated ranking. It does not expose a raw store or arbitrary query language.
  • search_notices read — Search NYC City Record notices (the daily-refreshed mirror). Keyword terms are OR-matched. Add structured filters to narrow. Amounts are validity-filtered (data-entry errors excluded). Rolling placeholder deadlines are labeled, never shown as dates.
  • get_notice read — Get one public City Record notice by its exact RequestID. The result preserves materialized-source freshness and distinguishes a missing public notice from a read that cannot be served.
  • get_entity_dossier read — Get the bounded public dossier for one exact canonical CityScroll entity. Preserves attributed disagreements, availability, provenance, and public redaction.
  • get_entity_relationships read — Traverse bounded, evidence-bearing public relationships from one exact canonical CityScroll entity. Only the closed node and edge vocabularies are returned.
  • retrieve_cited_passages read — Retrieve source passages with stable citations and exact source joins. Returns source text only. It does not generate an answer or infer civic relationships.
  • get_contract read — Get one public contract by its exact ID. Uses the same Contracts record as CityScroll. Includes source links, coverage, freshness, amount validity, and lifecycle facts when available.
  • browse_contracts read — List public Contracts records with bounded filters and pages. Results keep exact contract IDs separate, including records that share a PIN.
  • analyze_contracts read — Rank groups by agency, vendor, fiscal year, or amount band. Uses the registered-contract population. Reports registered value or contract count, a scope denominator, and coverage. Each group lists the exact contributing registration IDs in contract_ids and, at the same index in contract_procurement_ids, the canonical procurement ID get_contract accepts, or null when that contract is not individually retrievable. Does not report payments or spending.
  • get_person_or_organization read — Get one exact typed person or organization row from the published People and organizations read model. Display names never create identity. Relation states and source fields are preserved.
  • browse_organizations read — Browse the bounded typed People and organizations snapshot with exact row-kind and token filters. Results retain published, empty, or unknown relation states and read-model freshness.
  • get_meeting read — Get one exact source-qualified meeting from the shared CityScroll meeting read model. Preserves source receipt, coverage, freshness, and attached meeting documents.
  • get_land_project read — Get one exact Land (ZAP) project by its ZAP project id. Includes its deep link, status, geography, applicant, review procedure, exact actions and ids, environmental facts, milestones, outcomes, sources, and any conflicts, when known.
  • browse_land_projects read — List public Land (ZAP) projects using the same filters as the Land page: review procedure, action type, stage, effect, and geography. Reads the full warehouse, not just active projects, so completed and past projects stay reachable too.
  • get_land_decision_path read — Get the typed Land decision path for one exact project. Observed milestones and events remain separate from the reviewed normative procedure stages, actors, effects, and parallel review groups. Absent and unknown stages stay explicit.
  • preview_watch read — Preview what a plain-English standing watch would deliver, without subscribing. Lens: money (procurement), land (rezonings), property, rules, meetings, people.
  • create_watch mutation — Create a standing email watch from plain English. The watch starts immediately. The welcome email states its scope and includes manage and unsubscribe links.
  • list_capability_gaps read — List the capability gaps CityScroll declares about itself, so a caller can name what this endpoint does not answer instead of assuming a tool for it exists. Declared gaps: civic.outcome.prediction (What outcome will a public decision definitely produce? — nearest tools: get_land_project, get_land_decision_path). Takes no input, reads no records, and returns only this published declaration.

Machine-readable inventory: JSON catalog.

Upstream data

CityScroll republishes and joins public datasets — for bulk work, go straight to the sources: City Record Online (dg92-zbpx, Socrata SODA) (opens in new tab) · Checkbook NYC API (opens in new tab) · Citywide Payroll (opens in new tab) · Civil Service List (opens in new tab) · ZAP (opens in new tab).