UK Planit API

The full details for each planning application and planning area are available, as follows:
/planapplic/
/planarea/

You can also search for planning applications using this endpoint:
/api/applics/

And you can get lists of planning areas and their relations using this end point:
/api/areas/

The results format is also available, including limits to queries and error messages

The data records and field names returned by the API are described in the separate Data Dictionary

Note the API specification may be subject to further change. Also note that access to the API is rate limited. Enquire for further details.

Full Details on an Application or Area

Planning Application
/planapplic/{applic_name}/{fmt}
/planapplic/{anyid}@{planarea}/{fmt}
Planning Area
/planarea/{planarea}/{fmt}
  • {fmt} the data format - either geojson or json (add a 'callback' key for JSONP), otherwise, if empty, an html page is returned
  • {applic_name} the unique name for the planning application on this system
  • {planarea} the unique name or numerical id of a planning area in this system
  • {anyid} a unique identifier for the planning application within its authority

Searching for Planning Applications

/api/applics/{fmt}?{query}

  • {fmt} data format - either csv, geojson, georss, json (add a 'callback' key for JSONP), or tsv
  • {query} encoded key=value pairs, with keys as follows:
  • A search for a particular application (see note 1) is defined by:
    • id_match -> find applications which match an exact identifier in the 'uid', 'altid', 'reference' or 'name' fields (see note 1 below)
  • A spatial search (see note 2) for planning applications is defined using:
    • krad -> radius (km) = defines the size of a circle search perimeter (see notes 2 and 6)
    • lat -> latitude = the N/S (y) coordinate for the centre of a circle search (in the range +48 to +62)
    • lng -> longitude = the W/E (x) coordinate for the centre of a circle search (in the range -11 to +4)
    • pcode -> postcode = UK postcode to use for an alternative centre of a circle search
    • not_near -> include this key (set to any value), if you want a circular search ('krad') to be based on recency not proximity (see note 2)
    • bbox -> only planning applications within this recangular bounding box are returned = 4 comma separated lng/lat values in the order West (min lng), South (min lat), East (max lng), North (max lat) (and note lng/lat range limits above)
    • boundary -> only planning applications within this polygon are returned = coordinates formatted as '[[x1,y1],[x2,y2],[x3,y3],[x4,y4],...]' (see note 3)
    • no_location -> include this key (set to any value), if you want to view residual results that cannot be found using a spatial search (because the application does not have a 'location') (see note 2 below)
  • A search limited to applications from a particular area or areas (see note 4) is defined by:
    • auth -> name or numerical id of the area
    • no_kin -> include this key (set to any value), if you only want results from the defined area and not its sub-areas (areas contained within its boundaries)
  • Further filtering of the results can be defined by:
    • recent -> only planning applications with a 'start_date' within this number of recent days are returned (0 means today) (see note 5 below)
    • start_date -> only planning applications with a 'start_date' field after (and including) this date are returned (all dates in YYYY-MM-DD or DD/MM/YYYY format)
    • end_date -> only planning applications with a 'start_date' field before (and including) this date are returned
    • changed -> only planning applications with a 'last_changed' date within this number of recent days are returned (0 means today) (see note 5 below)
    • changed_start -> only planning applications with a 'last_changed' date after (and including) this date are returned (all dates in YYYY-MM-DD or DD/MM/YYYY format)
    • changed_end -> only planning applications with a 'last_changed' date before (and including) this date are returned
    • different -> only planning applications with a 'last_different' date within this number of recent days are returned (0 means today) (see note 5 below)
    • different_start -> only planning applications with a 'last_different' date after (and including) this date are returned (all dates in YYYY-MM-DD or DD/MM/YYYY format)
    • different_end -> only planning applications with a 'last_different' date before (and including) this date are returned
    • app_size -> find applications of a particular development size (can be multiple comma separated values, for details see the data dictionary)
    • app_state -> find applications with a particular decision status (can be multiple comma separated values, for details see the data dictionary)
    • app_type -> find applications of a particular type (can be multiple comma separated values, for details see the data dictionary)
    • search -> searches for text in the 'description' (also looks in the 'application_type', 'development_type', 'id_type', 'status' and 'decision' fields). Quoted word sequences are counted as phrases, "or" is a logical OR operator, and a dash prefix is a NOT operator; other punctuation is ignored.
  • Limiting and ordering of the results can be defined by:
    • pg_sz -> page size - the maximum results from the query to return in one request ( default 300 ) (see Search Results and Limitations)
    • index OR page -> the result page returned will start at this index number (commencing from zero) or at this page number (starting at page 1)
    • sort -> comma separated list of fields to sort results on (ascending, or if prefix is '-', descending) (see notes 6 and 7)
    • select -> comma separated list of fields to include in the output (default is to return all fields) (see notes 7 and 8)
    • compress -> include this key set to a value such as 'on' or 'true' to remove redundant white space from JSON or GEOJSON results

Notes

  1. The application 'name' field is unique nationally on this system, but other identifiers may match multiple times (eg the same 'uid' used by different authorities). If 'id_match' is supplied then all spatial search parameters ('krad', 'bbox', 'lat', 'lng', 'pcode', 'boundary') are ignored.
  2. Spatial searching finds planning applications where the 'location' field is within a circle, rectangle or polygon. If a circular search is specified ('krad') then any 'bbox' or 'boundary' will be ignored. If 'lat' and 'lng' are defined then any 'pcode' will be ignored. If 'no_location' is specified, all other spatial searching parameters are ignored.
  3. A 'boundary' can also be formatted as a GeoJSON Polygon or MultiPolygon geometry. The 'boundary' can be supplied in a POST request if the URL becomes unwieldy but there is a size limit of 4000 points. You can download existing OSM boundaries from Gimme Geodata and simplify them at mapshaper. You can create your own GeoJSON boundaries at geojson.io or convert from other formats at Ogre.
  4. By default non-planning areas such as regions or metropolitan counties will include the results of associated planning sub-areas (areas contained within their boundaries). Non-unitary English counties have small numbers of their own planning applications (minerals, waste, schools etc) but the default is also to include results from sub-areas (district councils). You can change this default behaviour by including the 'no_kin' key.
  5. If 'recent' is supplied then 'start_date' and 'end_date' are ignored. If 'changed' is supplied then 'changed_start' and 'changed_end' are ignored. If 'different' is supplied then 'different_start' and 'different_end' are ignored.
  6. If 'sort' is not specified, the default order for search results is '-start_date' order. However if a circular proximity search is undertaken ('krad' together with 'lat' & 'lng', or 'pcode' but without a 'not_near' field), the nearest applications are returned in order of 'distance' from the centre. The 'sort' field also accepts sorting suffixes -> '.asc', '.desc', '.nullsfirst' and '.nullslast'.
  7. If 'sort' and 'select' are specified, the 'sort' fields must also be listed in the 'select'. There is no default 'sort' order if a 'select' list of fields is specified.
  8. Use '*' to select all fields. You can rename fields in the output by adding a prefix alias with a colon eg 'alias:aliased_field_name'. You can also include 'other_fields' for display at the top level by using a '->' selector. For example 'select=*,nsd:other_fields->n_statutory_days' would add an extra 'nsd' field at the top level with the number of statutory days. (Special cases: you cannot select 'distance' as it is calculated during a spatial search)

Simple Example: /api/applics/json?auth=Hackney&start_date=2010-10-01&end_date=2010-10-02&pg_sz=10
Paging Example: /api/applics/json?auth=Hackney&start_date=2010-09-01&end_date=2010-10-02&pg_sz=100&page=3
Single Application Example (from 'link' field): /planapplic/Hackney/2010/2242/json
Search Example: /api/applics/json?auth=Wiltshire&search=%22solar%20panel%22%20or%20photovoltaic&pg_sz=20&select=name,description
Update Example: /api/applics/json?auth=Camden&recent=60&changed=60

Searching for Planning Areas

/api/areas/{fmt}?{query}

  • {fmt} data format - csv, geojson, json (add a 'callback' key for JSONP), or tsv
  • {query} encoded key=value pairs, with keys as follows:
  • One of the following search types:
    • auth and optional relation -> returns related areas where 'auth' is the name or numerical id of a planning authority (or a list of ids) and 'relation' can be one of 'parent' (Area above), 'children' (Sub-areas), 'offspring' (All sub-areas), 'alloffspring' (Area & sub-areas), 'allsiblings' (Area & related areas), 'siblings' (Related areas), 'ancestors' (All parent areas), 'allancestors' (Area & all parents), 'regions' (Associated region(s)), 'enclosed' (Planning sub-areas)
    • auths -> text to match in the 'area_name' or 'long_name' fields to find multiple planning areas
    • region -> returns areas within a region (one of 'regions' (All regions), 'multi' (Cross regional), 'super' (Above regional), 'Channel Islands', 'East England', 'East Midlands', 'Isle of Man', 'London', 'North East', 'North West', 'Northern Ireland', 'Scotland', 'South East', 'South West', 'Wales', 'West Midlands', 'Yorkshire and Humber')
    • area_type -> finds areas matching a specific type (one of 'planning' (All planning areas), 'active' (Active planning areas), 'inactive' (Inactive planning areas), 'stale' (Stale planning areas), 'Combined Planning Authority', 'Council District', 'Cross Border Area', 'Crown Dependency', 'English County', 'English District', 'English Region', 'English Unitary Authority', 'London Borough', 'Metropolitan Borough', 'Metropolitan County', 'National Park', 'Northern Ireland District', 'Other Planning Entity', 'Scottish Council', 'Welsh Principal Area', 'UK Nation') (see note 1)
    • krad, lat, lng, pcode, not_near, bbox, boundary -> spatial search for planning areas whose 'boundary' intersects with a circle, rectangle or polygon - defined in exactly the same way as the spatial search for planning applications above
  • Limiting and ordering of the results can be defined by:
    • pg_sz -> page size - the maximum results from the query to return in one request ( default 10 )
    • index OR page -> the result page returned will start at this index number (commencing from zero) or at this page number (starting at page 1)
    • sort -> comma separated list of fields to sort results on (ascending, or if prefix is '-', descending) (see note 2)
    • select -> comma separated list of fields to include in the output (default is to return all fields) (see note 3)
    • compress -> include this key set to a value such as 'on' or 'true' to remove redundant white space from JSON or GEOJSON results

Notes

  1. 'Stale planning areas' are defined as those where the system has been unable to access planning applications for the last six weeks. 'Inactive planning areas' are those where the sysem has never been able to access planning application data.
  2. If 'sort' is not specified, the default order for search results is 'area_name' order.
  3. If 'sort' and 'select' are specified, the 'sort' fields must also be listed in the 'select'. There is no default 'sort' order if a 'select' list of fields is specified.

Example: /api/areas/json?auth=Hackney&relation=siblings&select=area_name

Results Format and Limitations

JSON and GEOJSON result fields

  • JSON
    • records -> a page of data records from the full query - for details of the fields see the data dictionary
  • GEOJSON
    • type -> 'FeatureCollection'
    • features -> a page of 'Features' from the full query - each of which includes a 'geometry' (Point/Polygon) and its 'properties' - for details of 'properties' fields see the data dictionary
  • from -> index of the first item in the 'records'/'features' list
  • to -> index of the last item in the 'records'/'features' list
  • secs_taken -> time taken to complete the query
  • total -> number of records found by the full (unpaged) query

Errors and limits

  • A query that returns exactly 'pg_sz' records is likely to be an incomplete result. Always check against the 'to' and 'total' fields to see if more data are available in a subsequent page.
  • There is an absolute limit of 5000 results that can be returned by any request. But please don't try to get all the data in one request by setting this as your default page size. Instead make multiple requests with a smaller 'pg_sz' and increment the 'page' value each time.
  • There is also an absolute limit of 1000kB of content data that can be returned by any request.
  • Multiple successive requests that exceed the current rate limit will trigger a 429 status code (look at the error message or the Retry-After header to see when you can try again).
  • All other errors will result in a 400 status code and an explanatory message included in an 'error' field - this includes underlying database queries that take longer than 45.0 secs.
  • CSV and TSV results are also paged lists, but the table cannot include any metadata (eg 'from', 'to', 'total') indicating its range.
  • To speed up your JSON/GEOJSON requests consider including 'compress=on' in the query to remove redundant white space.