Developer platform

One property. Twenty datasets. One API. Every number shows its source.

Area intelligence, property reports, EPC, sold-price comparables and published indices — over REST and MCP with one key. Every section carries machine-readable provenance: source, licence, vintage, and a methodology page where one exists. Built for applications and AI agents that have to show their working.

Free tier: 250 credits/month, no card. Paid plans from £29/month, no contracts — pricing.

First request

Use your key in three steps

Copy the full key once, keep it server-side, then send it as a Bearer token. REST and MCP use the same key and the same credit allowance.

  1. 1 · CREATE

    Create and copy a key

    The full secret appears only once.

  2. 2 · STORE

    Keep it out of client code

    Use a server secret or environment variable.

  3. 3 · SEND

    Authenticate every call

    Authorization: Bearer ppa_live_…

REST

One key, one curl

Query by UPRN (preferred), postcode, or outcode. Responses are address-light by default — facts and identifiers, never bulk address data.

curl -H "Authorization: Bearer ppa_live_YOUR_KEY" \
  "https://postcodeproperty.ai/api/v1/property?uprn=100021082254"

Model Context Protocol

Remote MCP for agents

The same data as 8 read-only tools on the same credit meter, using the current remote Streamable HTTP transport. Client-specific guides name only configurations that have been verified.

{
  "mcpServers": {
    "postcodeproperty": {
      "url": "https://postcodeproperty.ai/mcp",
      "headers": {
        "Authorization": "Bearer ppa_live_YOUR_KEY"
      }
    }
  }
}
Only have the shortened prefix? The original key cannot be shown again because only its hash is stored. Revoke it in the dashboard, create a replacement, and copy the full value immediately.

Call the REST API from your backend

These examples read the key from POSTCODEPROPERTY_API_KEY. Configure that variable in your hosting provider or local secret store before running them.

JavaScript / TypeScript

const response = await fetch(
  "https://postcodeproperty.ai/api/v1/area?postcode=SW1A%201AA",
  {
    headers: {
      Authorization: `Bearer ${process.env.POSTCODEPROPERTY_API_KEY}`
    }
  }
);

if (!response.ok) throw new Error(`API error: ${response.status}`);
const report = await response.json();

Python

import os
import requests

response = requests.get(
    "https://postcodeproperty.ai/api/v1/area",
    params={"postcode": "SW1A 1AA"},
    headers={
        "Authorization": f"Bearer {os.environ['POSTCODEPROPERTY_API_KEY']}"
    },
    timeout=30,
)
response.raise_for_status()
report = response.json()

Endpoints & credits

Calls are metered in weighted credits; X-Credits-* headers report your allowance on every response. Dashboard-issued sandbox keys (ppa_test_sk_…) return deterministic fixtures across every documented REST family and all 8 MCP tools — no quota and no live upstream calls. Create a ppa_live_… key when you are ready for real data.

EndpointCreditsWhat you get
GET /api/v1/area1Area report: score, crime, schools, transport, broadband, flood, prices, trends, rental, healthcare, amenities, demographics, air quality, planning.
GET /api/v1/investment-score1The 1–10 score with weighted breakdown and completeness.
GET /api/v1/property5Flagship: property-grade report by UPRN or postcode — EPC, sale history, council tax estimate, risk, area context. +2 credits for address-string resolution (paid plans).
GET /api/v1/comparables2Recent sold prices around a postcode (exact-outcode) with stats. Max 100 rows/call.
GET /api/v1/epc1EPC certificate attributes by UPRN or postcode, newest first.
GET /api/v1/coverage0Free pre-flight: which datasets hold data here, before you spend credits.
GET /api/v1/data-freshness0Public dataset catalogue: cadence, reported upstream vintage, health, geographic coverage and exposure policy. No key required.
POST /api/v1/compare1/postcodeCompare 2–5 areas with honest data-backed verdicts.
POST /api/v1/summary10AI summary of our cached area data (no client-supplied prompts).
GET /api/v1/metrics/{metric}1Published indices (green-premium live; more publish with their methodology pages).
GET /api/v1/rankings1Persona outcode rankings — investor, family or young_professional — rank-ordered nationally, recomputed twice monthly. Optional region prefix filter; up to 250 rows/call. meta.attribution carries the licence statements for that persona’s inputs (OSM/ODbL for young-professional nightlife).

MCP tools mirror these on the same meter: get_area_reportget_investment_scoreget_property_reportget_comparablesget_epccheck_coveragecompare_areasget_metric

Playground

Calls run from your browser with your own key — create one free in under a minute.

Provenance is the product

Every section names its source, licence and vintage; meta.attribution carries the exact statements to reproduce when republishing; cached serves are disclosed in meta.cache, and failures are honest unavailableSources — never confident zeros.

"crime": {
  "level": "average",
  "summary": "…",
  "provenance": {
    "source": "police.uk street-level crime",
    "licence": "OGL-v3",
    "asOf": "2026-08",
    "note": "Police.uk publishes with a ~2-month lag…"
  }
},
"meta": {
  "sourceCompleteness": 100,
  "vintages": { "crime": "2026-08", "housePrices": "2026-08", … },
  "attribution": [ { "source": "HM Land Registry", "statement": "…" } ],
  "cache": { "hit": true, "age_seconds": 312, "tier": "memory" }
}

Rate limits & errors

Two limits apply to every key: a per-minute burst rate and your plan's monthly credit allowance. Both come back as 429s you tell apart by the error code — v1 preserves its top-level error envelope and now adds a support correlation ID in X-Request-Id (and request_id on middleware errors). A per-IP guard applies on top, in two tiers: requests without an Authorization header are capped at 120 requests/minute per IP; requests carrying one are capped at 600 — above every plan ceiling.

PlanRequests/minCredits/month
Free30250
Developer603,000
Growth12020,000
Scale300100,000
StatusCodeWhat it means
401invalid_api_keyMissing, malformed or revoked key.
403insufficient_scopeThe key lacks the scope this endpoint requires.
429rate_limitedPer-minute burst limit hit. Carries Retry-After: 60; per-key 429s also carry X-RateLimit-Limit — back off and retry.
429usage_limit_exceededMonthly credit allowance exhausted. Carries X-Credits-Limit, X-Credits-Used and X-Credits-Remaining: 0 — no Retry-After, because credits return when your billing window rolls (or you upgrade), not after a wait.

Only successfully delivered 2xx data responses consume credits. Validation, not-found, upstream and server errors are logged at zero credits. Every metered success carries X-Credits-Limit, X-Credits-Used, X-Credits-Remaining and X-RateLimit-Limit, so you never have to guess where your allowance stands.

There is no cursor pagination — responses are capped instead, and say so: comparables returns at most 100 rows (with a truncated flag when more exist), epc at most 100 certificates newest-first, and compare accepts at most 5 postcodes. If a cap bites, narrow the query.

Versioning & changelog: additive changes — new fields, new endpoints, new MCP tools — ship within v1 without notice; breaking changes get a new versioned path and 90 days' notice on the changelog.