# Cortile hackathon API

Synthetic data from a UK residential block management platform, for the real estate hackathon on 12 Nov 2026.

The dataset has the same shape and roughly the same scale as a real managing agent's portfolio. Every name, address, person and figure is made up. Data is as of 2026-11-12T09:00:00Z.

Please only share the key and data with people at the event, and only use them for the event.

## Get going in two minutes

Base URL: `https://hackathon.cortile.com`

Send your key in the `x-api-key` header (or `Authorization: Bearer <key>`).

```bash
export CORTILE_KEY=your-key-here
export CORTILE_API=https://hackathon.cortile.com

# What's available
curl -H "x-api-key: $CORTILE_KEY" $CORTILE_API/v1

# Overdue fire risk assessments
curl -H "x-api-key: $CORTILE_KEY" "$CORTILE_API/v1/compliance?type=fire_risk_assessment&status=overdue"

# Emergency tickets reported since 1 Oct, newest first
curl -H "x-api-key: $CORTILE_KEY" "$CORTILE_API/v1/tickets?urgency=emergency&reported_after=2026-10-01&sort=-reported_at"

# One building with its development and a summary of tickets and compliance
curl -H "x-api-key: $CORTILE_KEY" $CORTILE_API/v1/buildings/bld_0002

# A ticket with its contractor and full message history
curl -H "x-api-key: $CORTILE_KEY" $CORTILE_API/v1/tickets/tkt_000012
```

The full spec is at `/openapi.json`. Point your agent at it.

## What's in it

| Resource          | Rows   | What it is                                                                                                     |
| ----------------- | ------ | -------------------------------------------------------------------------------------------------------------- |
| `developments`    | 300    | Estates or schemes in 16 UK cities, with location, tenure model, developer, freeholder and responsible manager |
| `buildings`       | 1,000  | Blocks within developments: height, storeys, higher-risk status, lifts, heating, cladding position             |
| `units`           | 31,614 | Flats and commercial units: floor, bedrooms, area, tenure, service charge share                                |
| `leases`          | 21,611 | Long leases: leaseholder, term, ground rent, shared ownership share, arrears                                   |
| `service-charges` | 40,104 | Budget and actual spend per building, cost category and financial year (2024 to 2026)                          |
| `compliance`      | 9,777  | Statutory and safety checks per building: last done, next due, status, outcome, open actions                   |
| `tickets`         | 21,499 | Repairs and issues from Jan 2025 to Nov 2026: category, urgency, status, timings, contractor, cost             |
| `ticket-updates`  | 82,938 | Messages on tickets from residents, managers and contractors                                                   |
| `contractors`     | 364    | Contractors by trade and city, with rating and median response time                                            |
| `managers`        | 48     | Property managers and their regions                                                                            |

The data isn't uniform. Some buildings, contractors and managers perform much worse than others, and some problems keep coming back. Finding these patterns is part of the fun.

## Endpoints

Every resource has:

- `GET /v1/{resource}` lists records, with filters, `sort`, `limit` and `offset`
- `GET /v1/{resource}/{id}` gets one record

Some detail endpoints include related records:

- `developments/{id}` includes the manager and buildings
- `buildings/{id}` includes the development and ticket and compliance counts by status
- `units/{id}` includes the lease
- `tickets/{id}` includes the contractor and all updates

Related lists:

- `/v1/developments/{id}/buildings`
- `/v1/buildings/{id}/units`, `/leases`, `/compliance`, `/service-charges`, `/tickets`
- `/v1/units/{id}/leases`, `/tickets`
- `/v1/tickets/{id}/updates`
- `/v1/contractors/{id}/tickets`, `/compliance`
- `/v1/managers/{id}/developments`, `/tickets`

`GET /v1` lists every resource with its filters and sort fields.

## Conventions

- Ids are strings with a prefix: `dev_`, `bld_`, `unt_`, `lse_`, `cmp_`, `bud_`, `tkt_`, `upd_`, `con_`, `mgr_`.
- Fields are `snake_case`. Money is in GBP. Timestamps are ISO 8601 in UTC (`2026-11-12T09:00:00Z`), and dates are `YYYY-MM-DD`.
- Lists return `{ "data": [...], "pagination": { "limit", "offset", "has_more", "next_offset" } }`. Pass `next_offset` as `offset` to get the next page. `limit` is 1 to 100 and defaults to 25.
- Sort with `sort=field` or `sort=-field` for descending.
- Unknown query parameters are rejected, so typos don't silently return everything.
- Errors look like `{ "error": { "code", "message", "field" }, "request_id" }`. Codes are `invalid_parameter`, `unknown_parameter`, `unauthorised`, `not_found`, `rate_limited` and `internal_error`.
- Every response has an `x-request-id` header. Quote it if you need help.
- CORS is open, so you can call the API straight from a browser app.

## Limits

- 3,000 requests per minute per key and IP address. Over that you get a `429` with `Retry-After`. Back off and retry.
- `offset` is capped at 10,000. For anything bigger, use the downloads.

## Downloads

If you want to analyse everything, or keep working if the API goes down, download the whole dataset:

- SQLite: `/downloads/cortile-hackathon-sqlite.zip?api_key=YOUR_KEY` (8 MB zipped, one table per resource)
- JSON: `/downloads/cortile-hackathon-json.zip?api_key=YOUR_KEY` (5 MB zipped, one file per table)

In the SQLite file, the table names are `managers`, `developments`, `buildings`, `units`, `leases`, `contractors`, `compliance_items`, `service_charge_budgets`, `tickets` and `ticket_updates`. Booleans are stored as 0 and 1.

## Glossary

- **Development**: an estate or scheme, often several buildings built together.
- **Higher-risk building**: 18 metres or taller, or at least 7 storeys. These have extra legal duties under the Building Safety Act 2022.
- **Service charge**: what leaseholders pay each year for running the building. A budget is set at the start of the year and the actual spend is reconciled at the end. Each flat pays its `service_charge_share_pct` of the total.
- **Leaseholder**: owns a flat on a long lease (often 99 to 999 years). The freeholder owns the building.
- **Fire risk assessment (FRA)**: a legally required review of fire safety. It often produces actions that have to be closed.
- **EICR**: electrical safety inspection of the communal wiring.
- **LOLER**: the legally required thorough examination of a lift.
- **EWS1**: a form that records whether a building's external walls are safe. Lenders often ask for it.
