API overview

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.

Base URL
https://mngd.co.uk/api/public/v1
Authentication
Authorization: Bearer mk_live_…
or X-Api-Key: mk_live_…
Format
HTTPS GET only · JSON responses · CORS enabled

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 summaries minRentSqft / minPrice.

Endpoints

GET
https://mngd.co.uk/api/public/v1/properties

List properties

Newest-updated first, paginated.

ParameterTypeDescription
qstringSearch text: only returns listings whose name or address contains it (max 100 chars)
min_areanumberMinimum building area (sq ft)
max_areanumberMaximum building area (sq ft)
updated_sinceISO dateOnly properties changed since this date — ideal for incremental syncs
pagenumberPage number, default 1
per_pagenumberResults 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
}
GET
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}"
GET
https://mngd.co.uk/api/public/v1/providers/{provider-name}/properties

List 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.

ParameterTypeDescription
provider-namestring (path)Exact provider name, URL-encoded (e.g. Example%20Workspace)
qstringSearch text within this provider's listings (name or address)
min_area / max_areanumberBuilding area range (sq ft)
updated_sinceISO dateOnly properties changed since this date
page / per_pagenumberPaging, 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"
GET
https://mngd.co.uk/api/public/v1/shortlists

List 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 }
  ]
}
GET
https://mngd.co.uk/api/public/v1/shortlists/{id}/properties

List 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.

ParameterTypeDescription
iduuid (path)Shortlist ID from List your shortlists
qstringSearch within the shortlist (name or address)
pagenumberPage number, default 1
per_pagenumberResults 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.

ParameterTypeDescription
200OKSuccess
401UnauthorisedMissing, invalid or revoked key
403ForbiddenKey paused, called from a website not on its allowed list, or not linked to a user (shortlists)
404Not foundProperty, provider or shortlist doesn't exist or isn't live
429Too many requestsRate limit (retry after 60s, see Retry-After) or monthly quota reached
500Server errorSomething 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;