The Database API
Please read Terms and conditions, Copyright, Fair Use, etc. if you are going to use this API.
This page describes version 6 of the API, made live on February 20, 2013.
Version 5 (old documentation) has been withdrawn. You can see a summary of changes from version 5.
There is an experimental Python Database API interface if you want to work with this API from Python.
Introduction
The same information as provided by the The Map URL API is provided in machine readable form using URLs like this:
https://map.cam.ac.uk/v6.json?q=search[&partial=yes] https://map.cam.ac.uk/v6.json?bb=boundingbox https://map.cam.ac.uk/v6.json?ref=ref https://map.cam.ac.uk/v6.json?inst=inst
with the same interpretation as in The Map URL API (note that one=list is not relevant in the q= and bb= variants, and the simple name variant is not available to the API - just use http://map.cam.ac.uk/v6.json?q=name).
An additional option ?limit=limit is also available on the ?q and ?bb forms which limits the number of results returned to the number given. For example
https://map.cam.ac.uk/v6.json?q=saint&limit=15
Values of query parameters, such as ?q= are limited to 2,000 characters. For ?inst= and ?ref= queries, a maximum of 25 may be requested at once (separating the requested codes with '|').
Also, there is another query type available to the database API not available when using a consumer URL. ?alpha=letter will provide an alphabetically ordered listing of the entire institution database for that letter. This is used as the basis for the directory page and other alphabetic listings. Please cache the results of this search so that it does not place an unwarranted load on the database. You can also filter by type, for example:
https://map.cam.ac.uk/v6.json?alpha=s&filter=college
The version 6 API also supports discovery and navigation around the reference hierarchy. See The Database API reference discovery for more details. In addition, the interactive browser (also linked from the 'More...' menu) can be useful when exploring the data available and when identifying the various codes used.
The 'v6' is a version number, allowing for potential backward compatibility if we change the spec at some point in the future. Only v6 is useful for now. v5 was deprecated in January 2013 and backward compatibility was not provided.
The 'json' part indicates the results are provided in JSON format. We may produce other formats in future, in which case URLs such as https://map.cam.ac.uk/v6.xml?... would be introduced, but for the time being, only JSON is supported.
The result is a JSON array:
[ { "type": type0, ... }, { "type": type1, ... }, ... ]
where each object in the array is an entity matching the request. If there are no results, an empty array is produced. If there is only one result, it is still provided as an array (of one object), not as just the object. Note also that requests by inst and ref may occasionally also yield more than one result.
The content of the rest of each object depends on:
- type
- what information is available for each result
- whether the request was a search (q=... or name) or direct look up (ref or inst URLs)
type is one of:
error
institution
site
college
building
entrance
nonuniversity
virtualsite
street
more
Error reports
If type is error, then the http request will also return an appropriate status code, typically 400 indicating the request is malformed (wrong combination of query parameters, for example) or 404 (api version or format not implemented for example). The consumer should also be prepared to handle other HTTP errors generated by the server which will not provide JSON data (500 for example). Apart from these, all correctly formed requests will generate status 200. Note that this includes requests with no results (which produce an empty array).
Note also that if you mis-spell 'v6.json' (for example, say you incorrectly use a capital V), then the URL may be interpreted as the end-user form M:/name so you would get a stream of HTML!
v5.json, the now deprecated API, will always produce an error like this (actually an HTTP 410 error).
Entity structure
Contents of JSON objects representing entities found are as follows, by type.
In general, each request includes information about things linked to each result: the buildings for an institution, the entrances to a site and so on. This referencing only applies one level deep: those parts are excerpted: they do not themselves contain further entities to which they refer. If you need these, you would have to request the content by ref or inst from the parent. The fields omitted in the second level are indicated with an asterisk in the tables that follow.
error
key | value | notes | |
type | error | ||
code | the HTTP status code | int | |
error | text describing the error | string |
more
key | value | notes | |
type | more | When the number of results is limited by ?limit=limit, the last element in the array of results may indicate "more", that there are more results that could be found but the limit was reached. Because certain results are redacted in some circumstances, note that the number of elements in the array may be fewer than limit+1 even if the limit is reached. "more" is not included if all the available results are returned. There isn't any way to page through the results: the search needs to be made more specific. |
institution
key | value | notes | ||
type | institution | |||
inst | the institution code of the entity | string | ||
role | kind of institution |
string, one of: |
||
prefix | the name prefix | string | for example, 'Department of', 'Centre for' | |
name | the substantive part of the institution name | string | for example, 'Geography'. This is the field to sort on for alphabetically ordered institutions | |
suffix | the name suffix | string | often an acronym or former name, which would often be presented in parentheses. For example, when name is 'Advanced Photonics and Electronics', prefix is 'Centre for ' and suffix would be 'CAPE'. The whole might be presented as 'Advanced Photonics and Electronics (CAPE), Centre for' or 'Centre for Advanced Photonics and Electronics (CAPE)' | |
parent* | when the entity is subsidiary to another, this is the institution code of the parent institution | entity | for example the faculty of a department | |
options | arbitrary space separated tokens indicating arbitrary options | string | ||
sd | the subdomain of the entity | string | e.g. "lucy-cav" | |
info | contact information (etc) | array of objects (see below) |
for example:
"info": [ Note that all this contact information relates to the entity concerned. Subordinate entities will have their own contact information if relevant. |
|
sortasvia | when result matched via an AKA field (see below) or from a role, the index of the info element which it matched against | integer |
virtualsite
'virtualsite' entities are only returned as part of The Database API reference discovery process in response to a search with 'ref=*' or 'ref=SITE/*'. These are just like sites and subsites except that they have no location information associated with them. They exist only so that the complete set of prefix letters (including those for buildings not on any real site) is available as a starting point for reference discovery (see the documentation for details). Looking up their ref verbatim will yield no result.
key | value | notes | |
type | virtualsite | ||
ref | the reference of the entity | string | e.g. "K", "EXT/BEAUFORT" See The Database API reference discovery for a discussion of reference formats |
name | the name of the entity (assuming it has one) | string | "north city" |
nonuniversity | key only present if the virtual site is not part of the university estate but where we want to refer to it in the map | boolean | always true if present. Currently the only virtual non-university site has reference 'EXT', along with some virtual sub-sites of 'EXT' |
Fields common to all geographical objects
The remainder are all geographical objects and share the following common fields:
key | value | notes | |
type | |||
ref | the reference of the entity | string |
e.g. "H/FORVIE" |
name | the name of the entity (assuming it has one) | string | e.g. "Forvie Site", "Austin Building" |
lat | the latitude of a representative position of the entity | float | |
lon | the longitude of a representative position of the entity | float | |
primitive | whether the building was derived from an OSM way ("w") or node ("n") | string (either "w" or "n") | primitive and id can be used together to form a link to the OSM browser, as in http://osm.org/browse/way/1234567 |
id | the OSM id of the node or way from which the entity was derived | int |
sites, colleges and buildings are usually areas (ways) in OSM, though there are a few "buildings" which represent an office in larger, possibly non-university premises, represented just as a node. Complex buildings, e.g. one containing 'holes', are represented as OSM 'multipologon relations'. In these cases the referenced way will be the one corresponding to the outside of the building - the holes can be accessed via the relation containing this way and OSM tags relating to the building will be associated with the outer way or the relation (but not both). |
site
key | value | notes | |
type | site | ||
nonuniversity | true | boolean | present to distinguish non-university sites from university sites (currently the only non-virtual, non-university site is 'H', the Cambridge Biomedical Campus) |
parent* | when the site is a sub-site, this is the main site | site object | for example object for "Cambridge Biomedical Campus" when name is "Forvie Site" |
entrances* | to the site | array of entrance objects | see below |
college
key | value | notes | |
type | college | This is the geographical entity for a college site or sub-site, not the institutional information which is an inst. This is very similar to site. | |
parent* | when the college item is a subsidiary site, the main site | college object | e.g. object for "Magdalene College" when site is ref MAGD/CRIPPS |
entrances* | as for site | array of entrance objects | see below |
institution* | the institution information associated with this college area | institution object |
building
key | value | notes | |
type | building | ||
parent* | site/college in which the building is situated | site/college object | |
entrances* | entrances of the building | array of entrance objects | see below |
occupants* | occupants of the building | array of institution objects |
entrance
key | value | notes | |
type | entrance | entrances apply to sites and colleges as well as buildings. Note, entrances are always derived from OSM node entities. | |
parents* | buildings and/or sites/colleges to which this entrance gives access | array of building/site/college objects | note that a few entrances give access to university properties on either side; also occasionally an entrance to a building isn't actually part of the building footprint. |
occupants* | the institutions that gain access by this entrance | array of institution objects | OK, you don't exactly "occupy" an entrance, but consistent with buildings |
direction | the direction of a normal to the parent building/site/college at an entrance, in degrees between -180 and 180 measured anticlockwise from the east (positive x axis) pointing away from the building | float | the direction can be used to orient an overlaid arrow pointing to the entrance. |
user | some or all of the letters "fbvg" | string | standing for "foot", "bicycle", "vehicle" and "goods" respectively, indicating the class or classes of users which can use the entrance. |
door | boolean | whether this entrance is the door to a building (true) or a gate to a site (false) |
nonuniversity
Non-university objects are only provided no reference is available. Where they have a University reference they are included in the general scheme of sites and buildings, with the nonuniversity element set to true.
key | value | notes | |
type | nonuniversity | ||
role | what kind of thing this is | string | e.g. "hotel" |
street
key | value | notes | |
type | street | no additional fields other than the common ones |
Contact information
Contact information for institutions and colleges is grouped into an array of items each of which may be repeated and qualified as necessary. For example, multiple phone numbers with descriptions of what each is for. Note that these all relate to the entity concerned. Subordinate entities will have their own contact information if relevant, so addresses, phone numbers etc. for child institutions should not be given as alternate addresses within the same info array.
key | value | |
person | string | primary contact named individual, for example "Prof. John Doe". |
description | string | A brief description of the function of the institution |
title | string | primary contact title, for example "The Bursar", where useful for more personal addressing. |
address | array of objects (see below) |
postal address (assumed to be the primary address if not described otherwise by the role attribute - see below). |
phone | string | in the international form +44 1223 33nnnn |
fax | string | ditto |
string | ||
url | string | complete, including the http:// |
founded | int | (colleges only) year of foundation |
logo | string | url of image which is used to brand the institution |
string | twitter handle including the @, e.g. @camgeog | |
string | ||
AKA | string |
another name or search term by which the institution is known. Unlike other info fields, the value of this info item is (usually) added to the search index. This may be used in different ways according to the accompanying options. An "xm" option excludes the entry from the paper map (this might be a very old name, for example, which you want search results to hit, but not include in an up-to-date static map). "xw" excludes it from the web site searches and presentation, but includes it in the paper map and other alphabetic listings. "xd" excludes it from presentation (the user doesn't see it), but includes it in the index. Additionally when a ?q returns a result via a match on an AKA, the top level structure contains 'viaaka', the index of the info element which it matched against. This is so that you can tell the user if you want to why their search matched when it doesn't appear to match the main entry name. |
subsection | string | indicates that all the entries that follow up to a subsection-end entry or another subsection entry or the end of the info array are grouped together. This would typically be used where an institution lists contact details for a well-defined part or function of the institution - for example, the phone, fax and email for the Box Office part of the ADC Theatre. A consumer would typically render the subsection string as a subheading of some kind and possibly indent its contents or separate them out in some suitable way. (note: this supersedes the version 5 method of grouping, where repeated roles indicated subsections, which was rather clumsy and prevented the individual elements having their own roles). |
subsection-end | string (unused) | explicitly terminates a group of subsection elements. |
Contact information qualifiers
Each of these objects contains a type to identify the key, and may also contain other qualifying information, as follows:
key | value | |
type | one of the keys listed in the previous table | |
role | string | description of what the contact information will be used for. If omitted, assumed to be the primary contact information of this type. For URLs this would typically be used for the link text rather than displaying the URL itself. For others it would serve as a caption. |
options | string | arbitrary space separated string of options (meanings client dependent) |
Addresses
Addresses are further subdivided so that they can be presented linearly, in "label" form or as a VCARD etc, by combining the elements with suitable punctuation and markup, and also cross-linked where appropriate - for example the street element could be linked with the URL http://www.cam.ac.uk/streetname to jump to the map for the street name. These should be used in order when presenting an address.
Addresses may also be associated with geographical locations (sites, colleges and buildings) and their entrances. This supersedes the amorphous list of locations and entrances provided in version 5. An address may be
- just a postal address for correspondence, in which no location or entrances will be included in the address data
- a postal address with a corresponding location on the ground (possibly with entrances)
- just a location (and possibly its entrances), where the intention is to show the location on a map, but to direct post to a central address in a second address element, or occasionally that a postal address is not available for the location.
Each element contains a type field whose value is one of the keys in the following table, and then a key/value pair according to the type, as follows:
key | value | |
maildrop | string | for parts of an address such as a room number or a PO Box number |
building | string | name of building |
number | string | location on a street, e.g. "42a" |
site | string | e.g. "Lords Bridge", "New Museums Site" |
street | string | e.g. "Downing Place" |
street2 | string | occasionally a second street is part of the address |
smallplace | string | where place is a local village |
place | string | usually "Cambridge" |
county | string | rarely needed |
postcode | string | |
location | location object | see above. This is an excerpted geographical location object. There will only be at most one location object per address. |
entrance | entrance object | see above. This is an excerpted geographical entrance object. There may be multiple entrance elements per address, but there will never be an entrance object in an address if there is no location object preceding it for the same address. Conversely, location elements do not have any entrance elements preceding them. |
Some examples:
-
Hamilton Kerr Institute:
[ {"type": "street", "street": "Mill Lane"},
{"type": "smallplace", "smallplace": "Whittlesford"},
{"type": "place", "place": "Cambridge"},
{"type": "postcode", "postcode": "CB22 4NE"} ] -
Division of Anaesthesia
[
{ "type": "maildrop", "maildrop": "Box 93" },
{ "type": "maildrop", "maildrop": "Level 4" },
{ "type": "site", "site": "Addenbrooke's Hospital" },
{ "type": "street", "street": "Hills Road" },
{ "type": "place", "place": "Cambridge" },
{ "type": "postcode", "postcode": "CB2 2QQ" },
{ "type": "location", "location": {
"type": "building", "ref": "H132",
"lat": 52.17525, "lon": 0.141464, "id": 1643255315 }
},
{ "type": "entrance", "entrance": {
"type": "entrance", "ref": "H131-A",
"name": "Addenbrooke's Hospital Main Entrance",
"lat": 52.175206, "lon": 0.140538,
"direction": 104, "user": "f", "primitive": "n", "id": 1643254795,
"entrance": "main", "door": true }
},
{
"type": "entrance", "entrance": {
"type": "entrance","ref": "H-A",
"lat": 52.176241, "lon": 0.144354,
"direction": 15, "user": "fbv", "primitive": "n", "id": 664530277,
"entrance": "main", "door": false
}
},
...
]
Here is a complete example record (for the Department of Anglo-Saxon, Norse and Celtic). Remember that all result records will be presented in an array, even if there is only one of them.
{
"type": "institution",
"inst": "asnc",
"prefix": "Department of",
"name": "Anglo-Saxon, Norse and Celtic",
"sd": "asnc",
"role": "academic",
"info": [
{ "type": "address",
"address": [
{ "type": "number", "number": "9" },
{ "type": "street", "street": "West Road" },
{ "type": "place", "place": "Cambridge" },
{ "type": "postcode", "postcode": "CB3 9DP" },
{ "type": "location", "location": {
"type": "building", "ref": "S040",
"name": "Faculty of English",
"lat": 52.20246, "lon": 0.108541, "id": 26378099 }
},
{ "type": "entrance", "entrance": {
"type": "entrance", "ref": "S040-A",
"lat": 52.202422, "lon": 0.108616, "direction": -169,
"user": "f", "primitive": "n", "id": 1487638771,
"entrance": "main", "door": true }
},
{ "type": "entrance", "entrance": {
"type": "entrance", "ref": "S-C",
"lat": 52.202752, "lon": 0.108839, "direction": 94,
"user": "fb", "primitive": "n", "id": 961417125,
"entrance": "main", "door": false
}
},
{ "type": "entrance", "entrance": {
"type": "entrance", "ref": "S-E",
"lat": 52.202702, "lon": 0.108056, "direction": 94,
"user": "fbv", "primitive": "n", "id": 961417126,
"entrance": "main", "door": false }
}
]
},
{ "type": "phone", "phone": "+44 1223 335079" },
{ "type": "fax", "fax": "+44 1223 335092" },
{ "type": "email", "email": "asnc@hermes.cam.ac.uk" },
{ "type": "url", "url": "http:\/\/www.asnc.cam.ac.uk\/" },
{ "type": "url", "url": "http:\/\/www.asnc.cam.ac.uk\/people\/index.htm", "role": "Contacts" }
]
}
Coordinates
There are very few real-world coordinates in the database (it doesn't, for example, include building outlines). But this information is available from the OSM API by reference to the OSM id in the 'id' field of all geographic entities.
For building outlines, the OSM API supports:
http://osm.org/api/0.6/way/<ID> http://osm.org/api/0.6/way/<ID>/full http://osm.org/api/0.6/way/<ID>/relations
Note however that a building doesn't have to be just a single closed way, since it can have have holes in the area. These are handled as OSM "multipolygons". In essence, there is an outer way plus a number of inner ways
For example, Churchill West Court (ref CHU016, https://map.cam.ac.uk/v6.json?ref=CHU016&debug=1). The Map API tells you it is a way with id 148247888 and you can plug it into the OSM API thus
http://www.openstreetmap.org/api/0.6/way/148247888/full
returning
<osm version="0.6" generator="OpenStreetMap server"> <node id="1613469175" lat="52.2128314" lon="0.1013427" version="1" changeset="10553242" user="davidearl" uid="3582" visible="true" timestamp="2012-01-31T20:37:02Z"/> <node id="1613469065" lat="52.2127198" lon="0.101803" version="1" changeset="10553242" user="davidearl" uid="3582" visible="true" timestamp="2012-01-31T20:36:58Z"/> ... <nd ref="1613469175"/> <nd ref="1613469065"/> ... <tag k="amenity" v="university"/> <tag k="building" v="yes"/> <tag k="name" v="West Court"/> <tag k="operator" v="Churchill College (University of Cambridge)"/> <tag k="ref" v="CHU016"/> </way> </osm>
and http://www.openstreetmap.org/api/0.6/way/148247888/relations gets
<osm version="0.6" generator="OpenStreetMap server"> <relation id="1999559" visible="true" timestamp="2012-01-31T20:40:32Z" version="1" changeset="10553242" user="davidearl" uid="3582"> <member type="way" ref="148247888" role="outer"/> <member type="way" ref="148248147" role="inner"/> <tag k="type" v="multipolygon"/> </relation> </osm>
telling you it is a multipolygon outer, and giving the info to traverse to the inner as above.