--- name: tallinn-open-data description: Query Tallinn's universal municipal open-data API when a dataset page supplies its backing table name. module: tlnandmed.mjs execution: get --- # Tallinn Open Data API ## Access Public FastAPI GET service. No authentication. Dataset pages in the national portal document table names. ## Endpoints - Instructions: https://avaandmed.tallinn.ee/ - OpenAPI: https://avaandmed.tallinn.ee/openapi.json - Query: https://avaandmed.tallinn.ee/data/ - Known table example: https://avaandmed.tallinn.ee/data/?table=andurid_data&page=1&per_page=2 ## Retrieve 1. Find the Tallinn dataset in `andmed.eesti.ee`; read its description for the `table` name. The API does not list tables — `/tables` is 404 and `/data/` with no table is a 422 `Field required`. The catalogue's own JSON does this without opening the portal (verified 2026-08-01): `GET https://avaandmed.eesti.ee/api/datasets?limit=75&search=` (an unknown query parameter is a 400, and `limit` above 75 is rejected), then `GET https://avaandmed.eesti.ee/api/datasets/slug/` for each hit. The table name appears in the detail record either as an `avaandmed.tallinn.ee/data/?table=` access URL or written into the description as `(tabel: )`. Search the words the dataset uses, not the city: `search=tallinn` matches 48 datasets and **none** of the ones this API serves, while `search=vanalinna väravate` finds `andurid_data` at once. 2. Query `/data/` with required `table` and optional `columns`, `filters`, `order_by`, `page`, and `per_page`. 3. Use `page >= 1` and `1 <= per_page <= 1000`; paginate until a page is shorter than `per_page`. 4. Treat `filters` as the service's documented SQL-WHERE-style expression and URL-encode it. The `andurid_data` example returns Old Town gate sensor records with `id`, `andurid_id`, `name`, `ts`, `pir`, `in`, `out`, `humidity`, and `temp`. ## Return Preserve the national catalog page, table name, columns/filter/order, page size, original fields, source endpoint, and retrieval time. ## Limits - A made-up or stale table name returns a JSON 500 with `Table not found`; the OpenAPI schema alone cannot discover valid tables. - Maximum documented concurrency is five requests and query timeout is 20 seconds. - Different tables have unrelated schemas. - The service reports **no row count**: a page shorter than `per_page` is the only end-of-table signal, so a figure is a total only when paging ran to a short page. ## Verify Require HTTP 200 JSON and a list of records. For `andurid_data`, require `andurid_id`, `name`, `ts`, and numeric count fields. A 422 missing-table response or 500 table-not-found response is not successful access. Known-good acceptance check, run against the live API by `scripts/check-sources.mjs` (issue #82): ```probe GET https://avaandmed.tallinn.ee/data/?table=andurid_data&page=1&per_page=2 expect /"andurid_id":\s*\d+/ expect /"ts":\s*"\d{4}-\d{2}-\d{2}/ # The counter is the failure worth pinning: an invented table answers HTTP 500 # with {"detail":"404: Table not found"} rather than an empty list, so a # mistyped name can never be read as a dataset that holds nothing. counter GET https://avaandmed.tallinn.ee/data/?table=andurid_data_zzz&page=1&per_page=2 ``` ## Module API tallinnOpenData(table, {columns, filters, orderBy, limit, page, perPage}) -> {source, page, table, query, totals, columns, rows, note} tallinnDatasets(term, {limit}) -> {source, page, term, totals, tables, datasets, note}