Appearance
API Overview
The REST API runs on Fastify 5 at port 3001.
- Swagger UI: http://localhost:3001/docs
- Base URL:
http://localhost:3001(local) orhttps://mtl-rent-api.fesenko.net(tunnel)
Authentication
JWT tokens in httpOnly cookies. Include credentials: "include" in fetch requests.
Protected endpoints require the token cookie or Authorization: Bearer <token> header.
Response Format
All endpoints return JSON. List endpoints include pagination:
json
{
"listings": [...],
"pagination": {
"page": 1,
"limit": 20,
"total": 156,
"totalPages": 8
}
}Error Format
json
{
"error": "Error message"
}Endpoints Summary
Public (no auth)
| Method | Path | Description |
|---|---|---|
| GET | /health | Health check |
| GET | /listings | Browse listings with filters + pagination |
| GET | /listings/:id | Listing detail with images |
| GET | /listings/:id/similar | Similar listings (scored by bedrooms, price, distance) |
| GET | /neighborhoods | List neighborhoods |
| GET | /neighborhoods/:slug | Neighborhood profile with stats |
| GET | /articles | List published articles (blog/wiki) |
| GET | /articles/:slug | Get single published article |
| GET | /postal-areas | List all FSAs with listing stats + boundaries |
| GET | /postal-areas/:fsa | FSA detail with boundary, listings, nested postal codes |
| GET | /postal-areas/code/:code | Full 6-digit postal code detail with listings |
| GET | /census-tracts | All census tracts with boundaries + income data |
| GET | /census-tracts/:ctuid | Single census tract by CTUID |
| GET | /income/snapshots | Income snapshots (filterable by geo_type, source, year) |
| GET | /income/fsa-trends | CRA FSA income trends 2015-2021 |
| GET | /income/ct-comparison | 2016 vs 2021 CT income change (923 matched CTs) |
| GET | /income/distribution | Income bracket distributions (19 brackets, 2016+2021) |
| GET | /income/rent-trends | CMHC avg rent by zone over time (optional geo_code filter) |
| POST | /auth/register | Register user |
| POST | /auth/login | Login (sets cookie) |
| POST | /auth/logout | Logout (clears cookie) |
| POST | /inquiries | Submit inquiry (name + email + message) |
Authenticated (any user)
| Method | Path | Description |
|---|---|---|
| GET | /auth/me | Current user |
| PUT | /auth/profile | Update name and phone |
| PUT | /auth/password | Change password |
| GET | /favorites | User's saved listings |
| GET | /favorites/check | Check which listings are favorited |
| POST | /favorites | Save a listing |
| DELETE | /favorites/:listingId | Remove favorite |
| GET | /inquiries/my | User's sent inquiries |
Landlord
| Method | Path | Description |
|---|---|---|
| GET | /listings/my | Landlord's own listings |
| POST | /listings | Create listing |
| PUT | /listings/:id | Update listing (owner) |
| PATCH | /listings/:id/status | Change status (owner) |
| DELETE | /listings/:id | Delete listing (owner) |
| POST | /listings/:id/images | Upload images (owner) |
| DELETE | /listings/:id/images/:imageId | Delete image (owner) |
| PATCH | /listings/:id/images/:imageId | Set primary image (owner) |
| GET | /listings/:id/notes | List notes (owner) |
| POST | /listings/:id/notes | Add note (owner) |
| PUT | /listings/:id/notes/:noteId | Edit note (owner) |
| DELETE | /listings/:id/notes/:noteId | Delete note (owner) |
| GET | /inquiries/listing/:id | Inquiries for a listing (owner) |
| POST | /claims | Submit claim for scraped listing |
| GET | /claims/my | Landlord's claims |