API reference
Base URL: https://daftalerts.example.com/api (or http://localhost:5080/api in development).
All endpoints except /health* and (in dev) /swagger* require:
Authorization: Bearer <token>
Errors are returned as RFC 7807 ProblemDetails (application/problem+json). Validation failures come back as ValidationProblemDetails with per-field errors in the errors dictionary.
Rate limit: 300 requests per minute per IP. Excess returns 429.
GET /api/properties
List properties with filter, sort, paging.
Query parameters
| Parameter | Type | Default | Notes |
|---|---|---|---|
status |
inbox \| approved \| recycled |
required | |
page |
int | 1 | 1-based |
pageSize |
int | 24 | max 100 |
search |
string | — | matches Address or Notes (case-insensitive contains) |
routingKeys |
csv string | — | e.g. D01,D02,D04. Validated against Eircode routing-key pattern. |
minBeds |
int | — | |
maxBeds |
int | — | |
minBaths |
int | — | |
minPrice |
decimal | — | |
maxPrice |
decimal | — | |
propertyTypes |
csv string | — | subset of House,Apartment,Studio,Shared,Other |
berMin |
string | — | e.g. C3 — matches properties with BER C3 or better (or null BER) |
sortBy |
receivedAt \| price \| beds |
receivedAt |
|
sortDir |
asc \| desc |
desc |
Response
{
"items": [
{
"id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"daftId": "6546017",
"daftUrl": "https://www.daft.ie/for-rent/house-herbert-lane-mews-dublin-2/6546017",
"address": "Herbert Lane Mews, Dublin 2, D02KC86",
"eircode": "D02KC86",
"routingKey": "D02",
"priceMonthly": 2850.00,
"currency": "EUR",
"beds": 2,
"baths": 2,
"propertyType": "House",
"berRating": "C1",
"mainImageUrl": "https://media.daft.ie/listings/6546017/hero.jpg",
"latitude": 53.33,
"longitude": -6.25,
"status": "inbox",
"receivedAt": "2026-04-15T09:12:30Z",
"approvedAt": null,
"recycledAt": null,
"notes": null
}
],
"total": 42,
"page": 1,
"pageSize": 24
}
GET /api/properties/{id}
Returns a single PropertyDto, or 404 if not found.
PATCH /api/properties/{id}
Update status and/or notes.
Request
{
"status": "approved",
"notes": "Great location, close to the Luas"
}
Both fields are optional. If status transitions to approved or recycled, the corresponding ApprovedAt / RecycledAt timestamp is set. Transitioning back to inbox (via bulk restore) clears both.
Response
The updated PropertyDto, or 400 with validation errors, or 404 if not found.
POST /api/properties/bulk
Batch approve/recycle/restore.
Request
{
"ids": ["<guid>", "<guid>"],
"action": "approve"
}
action is one of approve, recycle, restore. Up to 500 ids per call.
Response
{ "updated": 2 }
GET /api/stats
{
"inboxCount": 12,
"approvedCount": 5,
"recycledCount": 38,
"avgApprovedPrice": 2620.00,
"medianApprovedPrice": 2500.00
}
Averages and medians are computed only over approved properties.
GET /api/presets
Returns all filter presets, with the default first.
[
{
"id": "<guid>",
"name": "Dublin central rentals",
"routingKeys": ["D01","D02","D04","D06","D08"],
"minBeds": 1, "maxBeds": 3, "minBaths": 1,
"minPrice": null, "maxPrice": 3500.00,
"propertyTypes": ["House","Apartment"],
"berMin": null,
"isDefault": true,
"createdAt": "2026-04-15T00:00:00Z"
}
]
POST /api/presets
Create a preset.
Request
{
"name": "My preset",
"routingKeys": ["D02"],
"minBeds": 2, "maxBeds": 3, "minBaths": 1,
"minPrice": null, "maxPrice": 3000.00,
"propertyTypes": ["Apartment"],
"berMin": "C3",
"isDefault": false
}
Returns 201 Created with the full FilterPresetDto and a Location header.
PUT /api/presets/{id}
Same body shape, replaces the preset. Returns the updated DTO or 404.
DELETE /api/presets/{id}
Returns 204 on success, 404 if not found.
Health endpoints (no auth)
GET /health— liveness. Always returns 200 if the process is running.GET /health/ready— readiness. 200 when the DB is reachable and the geocoding worker has run within the last 5 minutes.
Example: approving in two calls
TOKEN=xxx
BASE=https://daftalerts.example.com/api
# List inbox
curl -s -H "Authorization: Bearer $TOKEN" \
"$BASE/properties?status=inbox&routingKeys=D02,D04&minBeds=2&maxPrice=3000"
# Approve a single listing
curl -s -X PATCH -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"status":"approved","notes":"worth a viewing"}' \
"$BASE/properties/<guid>"