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.
Research read IDs and scope
These reads show the public records CityScroll holds. No search hits does not mean no record exists. A record may lack a detail page or source document. Check each state on its own.
- Contract analysis: first ask for the list of accepted agency labels. Use one of those labels, with the same case. If a label is not known, the response suggests a match. It does not prove zero awards. Retry with the suggested label. For Parks, use Department of Parks and Recreation. The fiscal year uses the date a contract was registered. FY2026 runs from July 1, 2025 to June 30, 2026. It is not the year of an award or payment. The year used to split source files may also differ.
- Agency leaders: a published agency graph says which leader details are held. Keep the ID as given, including its encoded text. The record says if a separate dossier exists. It can link to the agency dossier's leadership record. That link is given only when the same person is named there. The node gives the source date and confidence. It also states the source's limits. A dated roster does not prove who holds the role today.
- Meetings: the meeting record keeps the source ID and the board it refers to. Check four things on their own: whether the source meeting is held, when it was observed, whether minutes were published, and whether a City Record notice is linked. A meeting can be present while its minutes are not published. It may have no linked notice. If there is too little evidence to tell, the link state stays unknown. Neither state removes the source meeting.
- Passage search: each result states the search scope, even with no hits. It gives the date the corpus was observed. Counts show how many records and passages it holds. Each source type has its own date and scope. Date bounds show the first and last source dates held. They do not mean all dates in that span are covered. Semantic search gives the same scope. A source's date is not the date the corpus was observed. A search covers only this retained set. No hit does not prove that CityScroll or a source has no such record.
Existing reads still work. Read the scope and dates sent with each result. For exact field names and values, see the schema catalog below.
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.
| Param | Meaning |
|---|---|
lens | money · land · property · rules · meetings · entity |
q | keywords (up to 4) |
agency | agency name as printed in the record |
min | minimum award $ (money lens → award feed) |
kind + name | entity 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.
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.
| Param | Meaning |
|---|---|
raw_string | exact text in agency_name. One row for each distinct source string |
canonical_id | stable text id assigned by the crosswalk |
canonical_name | name this site uses for the group |
variants | every 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.
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_federatedread — 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_noticesread — 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_noticeread — 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_dossierread — Get the bounded public dossier for one exact canonical CityScroll entity. Preserves attributed disagreements, availability, provenance, and public redaction.get_entity_relationshipsread — Explore the public links for one exact CityScroll entity. Agency leaders link to the same person's published leadership record when held. The result states if a separate dossier exists, gives the source date and confidence, and explains the source's limits.retrieve_cited_passagesread — Find source passages with stable citations and exact source links. Results include the corpus date, source types, counts, and date bounds, even with no hits. The search returns source text and its scope. It does not write an answer or infer civic links.get_contractread — 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_contractsread — List contracts in bounded pages. Each row keeps its exact identity, even when records share a PIN. Follow an analysis group to page through every registration, including those with no individual detail record.analyze_contractsread — Rank agencies, vendors, fiscal years, or amount bands by registered contract value or count. Each group links to its contracts when held. Start with no agency filter to get the accepted labels. An unknown label gets suggestions. The fiscal year uses the registration date, from July 1 through June 30. These totals do not measure payments or spending.get_person_or_organizationread — 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_organizationsread — 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_meetingread — Read one exact source meeting, with its ID, board, source date, and documents intact. The record states whether the meeting is held, whether minutes were published, and whether a City Record notice is linked. A missing notice link does not mean the source meeting is absent.get_land_projectread — 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_projectsread — 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_pathread — 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_watchread — Preview what a standing watch would deliver, without subscribing. Lens: money (procurement), land (rezonings), property, rules, meetings, people. Pass a structured filter to keep alternatives, phrases, and exclusions. Plain English remains optional.create_watchmutation — Create a standing email watch. The watch starts immediately. The welcome email states its scope and includes manage and unsubscribe links. Pass a structured filter to keep alternatives, phrases, and exclusions. Plain English remains optional.list_capability_gapsread — 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).