Property API documentation
Everything you need to integrate: authentication, endpoints, parameters, limits and error handling.
Getting started
The Managed. property API is a read-only JSON API. Only properties that are Live and not hidden at platform level are returned, with their available spaces.
https://mngd.co.uk/api/public/v1Authorization: Bearer mk_live_…X-Api-Key: mk_live_…Keys are shown once when created — we only store a fingerprint. If a key has allowed websites set, browser calls must come from one of those origins. Server-to-server calls should use keys with no website restriction.
Access tiers
- Basic — property details, location, photos, amenities, provider, spaces (size, floor, desks, description, availability, services) and summary figures
minSize/sumSizes. No pricing. - Full — everything in Basic plus space pricing:
price_month,rent_sqft,rates_sqft,service_charge_sqft,brooker_fee, and property summariesminRentSqft/minPrice.
Endpoints
https://mngd.co.uk/api/public/v1/propertiesList properties
Newest-updated first, paginated.
| Parameter | Type | Description |
|---|---|---|
| q | string | Search text: only returns listings whose name or address contains it (max 100 chars) |
| min_area | number | Minimum building area (sq ft) |
| max_area | number | Maximum building area (sq ft) |
| updated_since | ISO date | Only properties changed since this date — ideal for incremental syncs |
| page | number | Page number, default 1 |
| per_page | number | Results per page, default 25, max 100 |
Searching & filtering
q is a partial, case-insensitive match against the property name and address, so you can search by area, street, building name or postcode. Combine it with the size filters, and use total in the response to see how many listings match for paging.
- /properties?q=Shoreditch
- /properties?q=EC2A
- /properties?q=Soho&min_area=2000&max_area=5000
curl -H "Authorization: Bearer mk_live_..." \ "https://mngd.co.uk/api/public/v1/properties?q=Shoreditch&min_area=1000&page=1&per_page=25"
{
"data": [
{
"id": "3f2c…",
"name": "Example House",
"address": "1 Example Street, London EC2A 1AA",
"coordinates": { "lat": 51.52, "lng": -0.08 },
"images": ["https://…"],
"description": "…",
"area": 12000,
"amenities": ["Showers", "Bike storage"],
"website": "https://…",
"updated_at": "2026-10-01T09:30:00Z",
"provider": "Example Provider",
"spaces": [
{ "id": "…", "type": "Office", "size": 2500, "floor": "3", "unit": "…",
"desksn": 25, "description": "…", "available_from": "2026-11-01", "contract_type": "…",
"images": [], "floor_plan": null, "services": [] }
],
"minSize": 2500, "sumSizes": 2500
}
],
"page": 1,
"per_page": 25,
"total": 412
}https://mngd.co.uk/api/public/v1/properties/{id}Get one property
Returns { "data": { …property } }, or 404 if it doesn't exist or isn't live.
curl -H "Authorization: Bearer mk_live_..." \
"https://mngd.co.uk/api/public/v1/properties/{property-id}"https://mngd.co.uk/api/public/v1/providers/{provider-name}/propertiesList properties by provider
Live properties for one provider (operator or landlord). Use the provider's exact name — capitals and extra spaces don't matter, but partial names don't match. There's no list of providers, and an unknown name or a provider with no live listings returns 404 { "error": "Provider not found" }. Same response shape as List properties.
| Parameter | Type | Description |
|---|---|---|
| provider-name | string (path) | Exact provider name, URL-encoded (e.g. Example%20Workspace) |
| q | string | Search text within this provider's listings (name or address) |
| min_area / max_area | number | Building area range (sq ft) |
| updated_since | ISO date | Only properties changed since this date |
| page / per_page | number | Paging, default 1 / 25, max 100 per page |
curl -H "Authorization: Bearer mk_live_..." \ "https://mngd.co.uk/api/public/v1/providers/Example%20Workspace/properties?per_page=25"
https://mngd.co.uk/api/public/v1/shortlistsList your shortlists
Your saved manual shortlists. Shortlist calls need a key linked to your Managed. account (ask us to link it) and only ever return that account's own lists. Smart and archived shortlists aren't included.
curl -H "Authorization: Bearer mk_live_..." \ "https://mngd.co.uk/api/public/v1/shortlists"
{
"data": [
{ "id": "uuid", "name": "Client A – Soho", "description": null, "updated_at": "2026-10-30T09:00:00Z", "property_count": 12 }
]
}https://mngd.co.uk/api/public/v1/shortlists/{id}/propertiesList properties in a shortlist
Live properties in one of your shortlists, in the same shape as List properties. Someone else's shortlist, or an unknown ID, returns 404 { "error": "Shortlist not found" }. A key that isn't linked to an account returns 403.
| Parameter | Type | Description |
|---|---|---|
| id | uuid (path) | Shortlist ID from List your shortlists |
| q | string | Search within the shortlist (name or address) |
| page | number | Page number, default 1 |
| per_page | number | Results per page, default 25, max 100 |
curl -H "Authorization: Bearer mk_live_..." \ "https://mngd.co.uk/api/public/v1/shortlists/SHORTLIST_ID/properties"
Limits & errors
Each key has a per-minute rate limit, an optional monthly quota (successful calls only) and may have a lower maximum number of properties per call — per_page in the response shows the cap actually applied. Every call is logged in Usage.
| Parameter | Type | Description |
|---|---|---|
| 200 | OK | Success |
| 401 | Unauthorised | Missing, invalid or revoked key |
| 403 | Forbidden | Key paused, called from a website not on its allowed list, or not linked to a user (shortlists) |
| 404 | Not found | Property, provider or shortlist doesn't exist or isn't live |
| 429 | Too many requests | Rate limit (retry after 60s, see Retry-After) or monthly quota reached |
| 500 | Server error | Something went wrong — try again |
{ "error": "Rate limit exceeded. Try again in a minute." }JavaScript example
const res = await fetch("https://mngd.co.uk/api/public/v1/properties?per_page=50", {
headers: { Authorization: "Bearer " + process.env.MANAGED_API_KEY },
});
const body = await res.json();
if (!res.ok) throw new Error(body.error);
const { data, total } = body;