# What a town allows on a site

> For a law or planning firm: the zoning bylaws and defined terms that apply to an address, and what council and staff have said about it.

After this recipe you can give your own language model one site's zoning bylaws, defined terms and council record, each with its link, and ask it what may be built there.

**For:** a law or planning firm checking a site for a client.

**Uses:** [`GET /v1/jurisdictions/at`](https://data.heytownhall.com/docs/reference/jurisdictions/get-v1-jurisdictions-at), [`GET /v1/bylaws`](https://data.heytownhall.com/docs/reference/documents/get-v1-bylaws), [`GET /v1/defined-terms`](https://data.heytownhall.com/docs/reference/documents/get-v1-defined-terms) and [`GET /v1/search`](https://data.heytownhall.com/docs/reference/search/get-v1-search). Four requests: three records requests and one search.

## Steps

1. Find who governs the site from its coordinates. A site in a town inside a regional district has both; zoning is the town's.
2. List the town's zoning bylaws, and the defined terms that match a word you care about, such as "building".
3. Search the town's agenda items, motions and notices for the address. Quotes keep the address together.
4. Number each record with its link and hand the list to your language model with your question.

The example is 412 Harbour Road in Port Ellery, a sandbox town.

## The code

```python
import os

import requests

BASE = "https://data.heytownhall.com"
HEADERS = {"Authorization": f"Bearer {os.environ['HTD_KEY']}"}
SITE = {"lat": "49.05", "lng": "-124.1"}
ADDRESS = '"412 Harbour Road"'
TERM = "building"
QUESTION = "What may be built at 412 Harbour Road, and what has council said about it?"

def get(path, params):
    res = requests.get(f"{BASE}{path}", params=params, headers=HEADERS, timeout=30)
    body = res.json()
    if not res.ok:
        raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")
    return body["results"]

town = next(j for j in get("/v1/jurisdictions/at", SITE) if j["kind"] == "municipality")
bylaws = get("/v1/bylaws", {"jurisdiction": town["id"], "subject": "zoning"})
terms = get("/v1/defined-terms", {"jurisdiction": town["id"], "term": TERM})
said = get("/v1/search", {"q": ADDRESS, "jurisdiction": town["id"], "in": "agenda_items,motions,posts", "limit": 20})

records = [(f"Bylaw {b['number']}, {b['title']}, adopted {b['adopted_on']}", b["source_url"]) for b in bylaws]
records += [(f"Defined term \"{t['term']}\": {t['definition']}", t["source_url"]) for t in terms]
records += [(f"{h['date']}, {h['family'].replace('_', ' ')}: {h['title']}. {h['snippet']}", h["source_url"]) for h in said]

prompt = "\n".join([
    QUESTION,
    f"Answer only from these records of {town['name']}. Cite each claim by its number and keep its link. If the records do not answer the question, say so.",
    "",
    *(f"[{i}] {text} ({url})" for i, (text, url) in enumerate(records, 1)),
])
print(prompt)  # Send this to your own language model.
```

```js
const BASE = 'https://data.heytownhall.com';
const headers = { Authorization: `Bearer ${process.env.HTD_KEY}` };
const SITE = { lat: '49.05', lng: '-124.1' };
const ADDRESS = '"412 Harbour Road"';
const TERM = 'building';
const QUESTION = 'What may be built at 412 Harbour Road, and what has council said about it?';

async function get(path, params) {
  const url = new URL(path, BASE);
  for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v);
  const res = await fetch(url, { headers });
  const body = await res.json();
  if (!res.ok) throw new Error(`${body.error.code}: ${body.error.message}`);
  return body.results;
}

const town = (await get('/v1/jurisdictions/at', SITE)).find((j) => j.kind === 'municipality');
const bylaws = await get('/v1/bylaws', { jurisdiction: town.id, subject: 'zoning' });
const terms = await get('/v1/defined-terms', { jurisdiction: town.id, term: TERM });
const said = await get('/v1/search', { q: ADDRESS, jurisdiction: town.id, in: 'agenda_items,motions,posts', limit: 20 });

const records = [
  ...bylaws.map((b) => [`Bylaw ${b.number}, ${b.title}, adopted ${b.adopted_on}`, b.source_url]),
  ...terms.map((t) => [`Defined term "${t.term}": ${t.definition}`, t.source_url]),
  ...said.map((h) => [`${h.date}, ${h.family.replaceAll('_', ' ')}: ${h.title}. ${h.snippet}`, h.source_url]),
];

const prompt = [
  QUESTION,
  `Answer only from these records of ${town.name}. Cite each claim by its number and keep its link. If the records do not answer the question, say so.`,
  '',
  ...records.map(([text, url], i) => `[${i + 1}] ${text} (${url})`),
].join('\n');
console.log(prompt); // Send this to your own language model.
```

## What the sandbox prints

```text
What may be built at 412 Harbour Road, and what has council said about it?
Answer only from these records of City of Port Ellery. Cite each claim by its number and keep its link. If the records do not answer the question, say so.

[1] Bylaw 1400, Zoning Bylaw, adopted 2026-05-12 (https://portellery.example/bylaws/400000.pdf)
[2] Defined term "accessory building": means a detached building or structure that is subordinate to the principal building on the same lot. (https://portellery.example/bylaws/400000.pdf)
[3] 2026-10-06, post: Notice of public hearing: 412 Harbour Road. A short summary as the government posted it. (https://portellery.example/news/100001)
[4] 2026-10-04, agenda item: Rezoning application for 412 Harbour Road to permit a six-storey residential building. THAT City of Port Ellery receive the report "Rezoning application for 412 Harbour Road to permit a six-storey residential building" for information and direct staff to report back. (https://port-ellery.civicweb.example/meetings/900007)
[5] 2026-09-21, agenda item: Rezoning application for 412 Harbour Road to permit a six-storey residential building. THAT City of Port Ellery receive the report "Rezoning application for 412 Harbour Road to permit a six-storey residential building" for information and direct staff to report back. (https://port-ellery.civicweb.example/meetings/900006)
[6] 2026-08-07, agenda item: Rezoning application for 412 Harbour Road to permit a six-storey residential building. THAT City of Port Ellery receive the report "Rezoning application for 412 Harbour Road to permit a six-storey residential building" for information and direct staff to report back. (https://port-ellery.civicweb.example/meetings/900004)
[7] 2026-07-24, agenda item: Rezoning application for 412 Harbour Road to permit a six-storey residential building. THAT City of Port Ellery receive the report "Rezoning application for 412 Harbour Road to permit a six-storey residential building" for information and direct staff to report back. (https://port-ellery.civicweb.example/meetings/900003)
[8] 2026-07-24, motion: R724-1. THAT City of Port Ellery approve the recommendation on "Rezoning application for 412 Harbour Road to permit a six-storey residential building". (https://port-ellery.civicweb.example/meetings/900003/minutes.pdf)
[9] 2026-05-10, agenda item: Rezoning application for 412 Harbour Road to permit a six-storey residential building. THAT City of Port Ellery receive the report "Rezoning application for 412 Harbour Road to permit a six-storey residential building" for information and direct staff to report back. (https://port-ellery.civicweb.example/meetings/900001)
```

## Going further

- **Permits and fees for the work:** [`GET /v1/permits`](https://data.heytownhall.com/docs/reference/land-use/get-v1-permits) and [`GET /v1/fees`](https://data.heytownhall.com/docs/reference/land-use/get-v1-fees) for the same town.
- **What was said in the room:** add `transcripts` to `in`. A transcript hit links to the recording at the moment it was said.
- **The bylaw's own text** is at its `source_url`. Give your model the passages that matter, with the link.
