Skip to content
Documentation menu

Endpoints

List portfolio matches

GET
/api/v1/portfolio/matches

Applications on or near your Portfolio Monitor sites. Portfolio Monitor customers only.

Returns matches between your sites and planning applications, first found on or after since, oldest first. Each match includes the full application.

Each distinct application uses one record, unless you already received it this period.

  • Access: Portfolio Monitor customers.
  • Records: one per application returned, free if already returned this period. See records and allowances.

Parameters

ParameterTypeDescription
sincedate or timestampOnly matches first found on or after this date or timestamp. Defaults to 7 days ago.400 bad_request if it is not a date.
limitinteger 1-100Default: 100Page size, 1 to 100. Defaults to 100.Missing, zero or non-numeric values use 100; values above 100 are treated as 100.
cursorstringnext_cursor from the previous page, passed back exactly as returned (cur_...).400 bad_request if altered, or if it came from another endpoint.

Example request

curl "https://planningsignal.co.uk/api/v1/portfolio/matches?since=2026-10-01" \
  -H "Authorization: Bearer ps_live_your_key_here"

Example response

{
  "data": [
    {
      "id": 40213,
      "site_id": 812,
      "site_ref": "STORE-0147",
      "match_kind": "nearby",
      "distance_m": 180,
      "first_seen_at": "2026-10-02T05:41:09.000Z",
      "application": {
        "id": "pa_3kTq9ZxV1bN7cR2mW8yLpA",
        "reference": "2026/4417/P",
        "authority": "Camden",
        "address": "14 Fitzjohn's Avenue, London",
        "postcode": "NW3 5NA",
        "description": "Erection of a single storey rear extension and loft conversion with rear dormer.",
        "app_type": "Full",
        "app_state": "Undecided",
        "decision": null,
        "start_date": "2026-09-14",
        "decided_date": null,
        "lat": 51.5512,
        "lng": -0.1765,
        "url": "https://planning.example-council.gov.uk/application/2026-4417-P",
        "docs_url": null,
        "case_officer": "J. Patel",
        "attribution": null
      }
    }
  ],
  "next_cursor": null
}

Pass next_cursor back as cursor for the next page; it is null on the last page. See pagination.

Errors

StatuscodeWhen
400bad_requestBad since value or altered cursor.
403plan_requiredPortfolio Monitor is not active on the account.
401unauthorizedMissing, invalid or revoked key.
429rate_limitedOver 60 requests a minute.
429records_exhaustedNo new record fits in your remaining allowance.
500server_errorSomething failed on our side. Retry shortly.

Every error has the same JSON shape: { "error": "...", "code": "..." }, with extra fields on some codes. Full bodies are on rate limits and errors.

Questions? Contact us, or see the help centre.