This is the Nomis RESTful API you can use it to perform a variety of structural discovery and data download requests. We have support for SDMX (presented as either XML or JSON), RSS feeds, CSV, JSON data downloads, Microsoft Excel downloads and respond to GET and POST requests.

To show help relevant to your requirements let us know how you plan to use the API...

I would like to know about...

Discovery and Delivery
You need to find out what datasets, dimensions and codes are available, and how to download the required data.
Discovery only
You only need to find the datasets, dimensions and codes that are available.
Delivery only
You only need to know how to download data.

I prefer to work with...

All types of document
Help will be shown with all available examples (XML, JSON and HTML).
HTML documents
Choose this if you have little knowledge of SDMX, XML or JSON (includes help on using our JavaScript class)
XML documents
Examples containing XML resources will be used.
JavaScript Object Notation (JSON) files
Examples will be tailored to the JSON format.

Terminology

The table below contains some of the terminology used in the API and supporting documentation, you might find it helpful to look at these before getting started:

RESTful REpresentational State Transfer, a software architecture for distributed systems, in this case using HTTP GET requests (for example when you ask for a URI in you web browser).
URI Universal Resource Identifier, a string of characters used to identify a resource on the internet.
API Application Programming Interface, an interface implemented by a software program to enable interaction with other software.
XML A set of rules for encoding documents electronically.
SDMX Statistical Data and Metadata eXchange, ISO standard to describe datasets, dimensions and data.
JSON JavaScript Object Notation, a simple text-based format for representing simple data structures and associative arrays.
KeyFamily A Nomis dataset, described in SDMX.
KeyFamilies A collection of Nomis datasets described in SDMX.
Dimension These are the things that make up a dataset (e.g. Geography, Family Type, Age, Duration).
Codelist List of codes and descriptions that are applicable to a Dimension.
Concept The name for a dimension, if you were writing an application to display data, this is the name you would want to display for the dimension.
Metadata Information about something, for example further descriptive text for a code, often shown either using annotations or in a dedicated Metadata XML file.

Please note that the example URIs in this document assume a web root of "http://www.nomisweb.co.uk".

Concurrently running requests

The number of concurrently running requests to the API is limited. To avoid limits being reached, try to run as few requests concurrently as possible. For more information on the specific limits set please contact the Nomis helpdesk.

Tool to help you build a URI

If you need help creating API links or don't want to get into learning the full API you can use the Query data interface to select the required data and get an API link from there.

When you go to the "format / layout" page of your query, select "Nomis API" format. Your selections will be converted to API links in a variety of formats.

You will also be given the option to remove columns you don't need, change their order and see how the data will look with a live preview table.

View a Summary of your URI

The summary page is a web page that shows the selections you have made for each dimension in your URI. It highlights any invalid Concepts or Codelist codes you may have specified, as well as indicating dimensions that you have specified. At the bottom of the summary page, there is a selection of download URIs for the various formats available.

At any point in constructing your RESTful URI, append "/summary" to see this page.

Example:
Summary of a query. This shows that you have not yet filtered ITEM and MEASURES. /api/v01/dataset/NM_1_1/summary?geography=2092957697&sex=5

Discover available datasets

A "structure:KeyFamily" node provides you with an outline of the structure of the data and includes the name of the Keyfamily in the "structure:Name" node, and a description in the "structure:Description" node. There is a "structure:Components" node, that contains a number of "structure:Dimension" nodes detailing the concepts and codelists that relate to that dimension. This information is fundamental in determining how to build your query.

Complete list of datasets

You can obtain a complete list of all the Nomis datasets that are available to query using this API in one request.

Example (XML):
Get an SDMX Structure document with a "KeyFamilies" node, containing a number of "structure:Keyfamily" nodes /api/v01/dataset/def.sdmx.xml
Use the "id" attribute from one of these nodes to get the structure of an individual dataset, in this case the "Jobseeker's Allowance with Rates and Proportions" dataset /api/v01/dataset/NM_1_1/def.sdmx.xml
Example (JSON):
Get a JSON file with "keyfamilies" variable, containing an array of "keyfamily" nodes /api/v01/dataset/def.sdmx.json
Use the "id" attribute from one of the variables to get the structure of an individual dataset, in this case the "Jobseeker's Allowance with Rates and Proportions" dataset /api/v01/dataset/NM_1_1/def.sdmx.json
Example (HTML):
View a web page with information about each of the datasets available /api/v01/dataset/def.htm
Use the "id" from one of these datasets to get just the structure that dataset, in this case the "Jobseeker's Allowance with Rates and Proportions" dataset /api/v01/dataset/NM_1_1/def.htm

Search

You can also search for a dataset with Name, Description or Keyword that matches a given search term by appending "search=term". Wildcard character is "*", match is not case sensitive.

If you want to search for a term within a specific part of the dataset definition you can prepend one of the following:

  • name- this will search for datasets with a name matching the term that follows.
  • description- this will search for datasets with a description matching the term that follows.
  • keywords- this will search for datasets with a keyword matching the term that follows.
  • contenttype-<contenttype>[-id] this will search for datasets with an associated contenttype defined and optionally a matching id within that contenttype.
  • units- this will search for datasets with units matching the term that follows.
A narrow search using the method above will perform more quickly than a general search. Contentype and units are not searched by default.

You can search for multiple terms at once by separating them with a comma (",").

Example (XML):
Search for KeyFamilies containing "Claimant" in their name or description /api/v01/dataset/def.sdmx.xml?search=*claimant*
Search for KeyFamilies containing the Keyword "Ethnic" /api/v01/dataset/def.sdmx.xml?search=keywords-ethnic*
Example (JSON):
Search for KeyFamilies containing "Claimant" in their name or description /api/v01/dataset/def.sdmx.json?search=*claimant*
Search for KeyFamilies containing the Keyword "Ethnic" /api/v01/dataset/def.sdmx.json?search=keywords-ethnic*
Example (HTML):
Search for KeyFamilies containing "Claimant" in their name or description /api/v01/dataset/def.htm?search=*claimant*
Search for KeyFamilies containing the Keyword "Ethnic" /api/v01/dataset/def.htm?search=keywords-ethnic*

Discover Codelists and choose Codes

The codelist uses an intelligent hierarchy to give you a top-down view of things like "Geography". Additional codes are introduced, not normally found in the complete codelist, that allow you to indicate that you want "all of a certain type within something else" - for example "all districts within the North East".

If you do not specify a date (the concept for date ranges is "time"), all will be selected. In order to make common date selections easier, we have reserved the following keywords:

  • "latest" the latest available data for this dataset
  • "previous" the date prior to "latest"
  • "prevyear" the date one year prior to "latest"
  • "first" the oldest available data for this dataset

Using the "time" concept you are limited to entering two dates, a start and end. All dates between these are returned.

If however you require a specific list of dates, or to work with dates relative to the latest date you can use the "date" parameter instead of "time". The "date" parameter is more flexible than using "time" and in future versions of the API it may replace the "time" parameter entirely.

To illustrate the difference between using "date" and "time"; if you specified "time=first,latest" in your URI you would get all dates from first to latest inclusive, whereas with "date=first,latest" your output would contain only the first and latest dates.

With the "date" parameter you can specify relative dates, so for example if you wanted the latest date, three months and six months prior to that you could specify "date=latest,latestMINUS3,latestMINUS6". You can use ranges with the "date" parameter, e.g. if you wanted data for 12 months ago, together with all dates in the last six month up to latest you could specify "date=prevyear,latestMINUS5-latest".

Metadata is available for some codes, if available, this is displayed as an annotation against that code. For the "time" concept, you will find metadata annotations about the date that the count was taken, or the exact date of the survey period as well as information on when data for that date is next scheduled to be revised.

If you need to know when a new date is going to be released, want to see the full revision history for a specific date, or view all detailed metadata held for any other concept you can download the metadata for that date or all dates as an XML or JSON file by appending ".metadata.xml" or ".metadata.json" (see examples below).

Whilst constructing your RESTful URI, after each Concept reference that you specify, you can obtain the Codelist for that concept. This saves you looking up the Codelist Id from the KeyFamily definition and formulating a URI to examine the Codelist. To do this, simply append ".def.sdmx.xml", ".def.sdmx.json" or ".def.htm" as in the examples below.

Example (XML):
What top level areas are available? /api/v01/dataset/NM_1_1/geography.def.sdmx.xml
What areas are within Darlington? /api/v01/dataset/NM_1_1/geography/2038432081.def.sdmx.xml
Partial codelist of the wards in Darlington /api/v01/dataset/NM_1_1/geography/2038432081TYPE1.def.sdmx.xml
Search for wards ending with "central" in Darlington /api/v01/dataset/NM_1_1/geography/2038432081TYPE1.def.sdmx.xml?search=*central
List all available genders ("sex") from the "Jobseeker's Allowance with Rates and Proportions" dataset after selecting geography /api/v01/dataset/NM_1_1/sex.def.sdmx.xml?geography=2038432081
List all available items ("item") from the "Jobseeker's Allowance with Rates and Proportions" dataset after selecting geography and sex /api/v01/dataset/NM_1_1/item.def.sdmx.xml?geography=2038432081&sex=7
Display metadata about the date January 2010 /api/v01/dataset/NM_1_1/time/2010-01.metdata.xml
Display metadata about the all dates including dates that are yet to be released /api/v01/dataset/NM_1_1/time.metdata.xml
Example (JSON):
What top level areas are available? /api/v01/dataset/NM_1_1/geography.def.sdmx.json
What areas are within Darlington? /api/v01/dataset/NM_1_1/geography/2038432081.def.sdmx.json
Partial codelist of the wards in Darlington /api/v01/dataset/NM_1_1/geography/2038432081TYPE1.def.sdmx.json
Search for wards ending with "central" in Darlington /api/v01/dataset/NM_1_1/geography/2038432081TYPE1.def.sdmx.json?search=*central
List all available genders ("sex") from the "Jobseeker's Allowance with Rates and Proportions" dataset after selecting geography /api/v01/dataset/NM_1_1/sex.def.sdmx.json?geography=2038432081
List all available items ("item") from the "Jobseeker's Allowance with Rates and Proportions" dataset after selecting geography and sex /api/v01/dataset/NM_1_1/item.def.sdmx.json?geography=2038432081&sex=7
Display metadata about the date January 2010 /api/v01/dataset/NM_1_1/time/2010-01.metdata.json
Display metadata about the all dates including dates that are yet to be released /api/v01/dataset/NM_1_1/time.metdata.json
Example (HTML):
What top level areas are available? /api/v01/dataset/NM_1_1/geography.def.htm
What areas are within Darlington? /api/v01/dataset/NM_1_1/geography/2038432081.def.htm
Partial codelist of the wards in Darlington /api/v01/dataset/NM_1_1/geography/2038432081TYPE1.def.htm
Search for wards ending with "central" in Darlington /api/v01/dataset/NM_1_1/geography/2038432081TYPE1.def.htm?search=*central
List all available genders ("sex") from the "Jobseeker's Allowance with Rates and Proportions" dataset after selecting geography /api/v01/dataset/NM_1_1/sex.def.htm?geography=2038432081
List all available items ("item") from the "Jobseeker's Allowance with Rates and Proportions" dataset after selecting geography and sex /api/v01/dataset/NM_1_1/item.htm?geography=2038432081&sex=7

"Contenttype" support metadata and classifications

There are many varying classifications, groupings and attributes of datasets that include things such as data sources, taxonomy etc.

We are working to add these to datasets where possible. When these are available, you will see them on dataset definitions as annotation tags (in XML or arrays in JSON).

The AnnotationTitle will begin "contenttype/" and finish with the type of content to which the entry relates. The AnnotationText details the id or ids in a comma delimited list if there is more than one allocated to this dataset for that content type.

For example in a dataset definition (def.sdmx.xml) a dataset source might appear as:

  <Annotation>
    <AnnotationTitle>contenttype/sources</AnnotationTitle>
    <AnnotationText>cc</AnnotationText>
  </Annotation>

To find out more about a contenttype (in either XML or JSON format) use the API. Your request is built up from the AnnotationTitle followed by the term "id" followed by the AnnotationText, for example from the above code you would find out more by requesting "/api/v01/contenttype/sources/id/cc.xml" for the XML version or "/api/v01/contenttype/sources/id/cc.json" for the JSON version of the document. This returns a fragment of a contenttype document pertaining only to that specific id.

If you want to find out about the contenttype in general (for example to obtain the entire classification or taxonomy) specify only the AnnotationTitle part of the contenttype annotation. For example, "/api/v01/contenttype/sources.xml" for the XML version or "/api/v01/contenttype/sources.json" for the JSON version. This returns the entire contenttype document, which will include a node for the specific id somewhere within it.

A list of available taxonomy, sources and classifications are published under /api/v01/contenttype/index.xml for the XML version or /api/v01/contenttype/index.json for the JSON version. When you find one that interests you, simply append the "id" and format required to the contenttype URL to view the content. For example, an index entry that has an id of "sources" would be found at "/api/v01/contenttype/sources.xml".

Once you have a contenttype (and optionally an individual item id), it is possible to find all related datasets. See the "search" section for how to specify search terms when discovering a list of available datasets.

Data download

After the dataset ID (e.g. NM_1_1 for Jobseeker's Allowance with Rates and Proportions) you indicate that you want to download the data by specifying a format for the download.

Your selections are made in the query string (the part of the URI after the "?"). For each of the "structure:Dimension" nodes in the KeyFamily you need to specify the "conceptRef" and the "structure:Code" value from the appropriate Codelist for that dimension in the form "conceptRef=code".

For any unspecified dimensions all available data will be downloaded, you can change this behaviour such that the default is selected rather than all for the omitted dimensions. To do this add the setallwherenotspecified=false parameter to your request.

You can use the keyword "default" when you want the recommended codes for any given dimension (this is mostly equivalent to total), or "total" where you want no breakdown for a given dimension.

Multi-dimensional table output (HTML and Microsoft Excel XLSX/XLS)

You can download data in HTML or Excel format by appending ".data.htm", ".data.xlsx" or ".data.xls" to your URI. This allows multi-dimensional tabulation.

You must specify the concepts that are to appear in the rows and columns. You can choose more than one (comma-separate the concepts) and this will result in those concepts being nested within each other. Any dimensions not specified will be presented in separated tables.

For example, assuming a dataset with geography, sex, ethnicity, occupation and age you might specify rows=ethnicity,sex&cols=age,occupation. This would result in a table of sex within ethnicity in the rows and occupation within age in the columns and a separate table for each geographic area.

For HTML, by default, the response from this query is a complete HTML page, but it is also possible to tune the output using the select argument. If any options are specified, then only parts of the response for those are returned. The available HTML options are:

  • header: Html tag, head tag, css style tag, body tag.
  • items: Descriptions at the top of each table for the dimensions that aren't in rows and columns.
  • rowheadinglabels: Labels for the names of dimensions that are included in rows.
  • colheadinglabels: Labels for the names of dimensions that are included in columns.
  • colheadings: Headings for the columns.
  • data or datawithindent: Figures (datawithindent option adds CSS class attributes to row labels to indicate indentation level in the form idtn where n is the zero based level).
  • warnings: Notes and warnings associated with the data.
  • footer: Closing body and html tags.
  • usedisplaynames: Label for row headings are shown in a shortened display friendly format which makes sense when used in context of all other codes in the codelist (particularly in combination with the datawithindent option.

Comma Separated Values or Tab Separated Values Download (csv/tsv)

To download your data as comma separated values (csv), at the end of your query path append ".data.csv". To download your data as tab separated values (tsv), at the end of your query path append ".data.tsv".

You have a 25000 cell limit on the number of data values downloaded in these formats.

These formats have columns describing each dimension and one value per row. They are good for high-speed bulk download and have many options for customising the output. At first glance this format seems verbose, but you can easily trim the output down to only the specific columns you require using the Select parameter. When first working on your URIs we suggest you use the RecordLimit parameter described below to get a feel for the output without triggering large downloads.

If you are downloading a large amount of data and/or wish to reduce the size of download, you can restrict the columns included in the file and skip rows where the data value is missing (which is useful for sparse datasets).

Select columns to be output
To select columns, specify "select=DIMENSION1,DIMENSION2,DIMENSION3" in your URI. The order you specify the columns in is the order they will appear in your CSV file. There is a column heading for each dimension concept in your query (e.g. GEOGRAPHY, SEX etc.) and some additional columns; OBS_VALUE, OBS_STATUS, OBS_CONF, URN, RECORD_OFFSET and RECORD_COUNT. You can also get the actual names for the dimension values by appending "_NAME" to the concept (e.g. SEX_NAME) and their type by appending "_TYPE" to the concept (e.g. GEOGRAPHY_TYPE, which in this example will tell you that an area is a Ward or District etc.). This means you don't have to keep your own lookup lists for the Nomis codes.

Note: Dimensions also have a code column, where standard codes are shown if available (e.g. Geography has a column GEOGRAPHY_CODE showing the GSS code).

Exclude missing data values
To hide missing data values, append "ExcludeMissingValues=true" to your URI. To hide records containing a data value of zero, append "ExcludeZeroValues=true" to your URI.

Exclude Coumn Headings
To exclude the column headings row, specify "ExcludeColumnHeadings=true" in your URI.

Query ID
If you would like to identify the results as belonging to a particular query you have made, you can add a column called "QUERY_ID" to the results; the value of this column can contain any custom ID you require, the ID you specify is repeated in every row of the results. This is useful if you make multiple calls to the API using some automated process and need to work out which query the results belong to. To specify a custom Query ID, append the parameter "&queryid=myref" to your URI (where myref is your own reference value).

Pagination (Record Limit and Offset)
You can limit the number of records returned from your query, and the record offset into the results to start from. This allows you to split your query into a series of smaller downloads or look at the first few records to see the column headings etc. without downloading the whole data file.

To set a record limit, append "RecordLimit=n" to your URI (where n is the number of rows and -1 is used to mean all rows) if you do not specify a RecordLimit then it is assumed you want all records.

To set the record offset, append "RecordOffset=n" to your URI (where n is the zero based offset into the results). If you go to a record beyond the end of the results only the column headings and no data will be returned. For offsets relative to the end of the results use a negative offset (e.g. "RecordOffset=-25" will give the last 25 records).

The current row offset of any given row is found in the "RECORD_OFFSET" column in your output. To determine how many data records in your results, you can look at the "RECORD_COUNT" column for any row of data in your output. This is a count of the number of records, so is one more than the last RECORD_OFFSET (which is zero based).

Note: RecordLimit and RecordOffset do not compensate for records that are removed when ExcludeMissingValues and/or ExcludeZeroValues is specified (i.e. records for missing values are always counted even if they are not included in your output file).

Example:
CSV file for a single area for all dates from Jobseeker's Allowance dataset /api/v01/dataset/NM_1_1.data.csv?geography=2038432081&sex=5&item=1&measures=20100
TSV file for a single area for all dates from Jobseeker's Allowance dataset /api/v01/dataset/NM_1_1.data.tsv?geography=2038432081&sex=5&item=1&measures=20100
CSV file for all districts from Jobseeker's Allowance dataset /api/v01/dataset/NM_1_1.data.csv?geography=TYPE486&sex=7&item=1&measures=20100&time=latest
CSV file for all districts from Jobseeker's Allowance dataset, selecting only the area code (GEOGRAPHY_CODE), item (ITEM_NAME) and value (OBS_VALUE) columns and excluding any missing values from the results /api/v01/dataset/NM_1_1.data.csv?geography=TYPE486&sex=7&measures=20100&time=latest&select=geography_code,item_name,obs_value&ExcludeMissingValues=true
CSV file for all districts from Jobseeker's Allowance dataset, selecting only the first 5 rows /api/v01/dataset/NM_1_1.data.csv?geography=TYPE486&sex=7&item=1&measures=20100&time=latest&recordlimit=5
CSV file for all districts from Jobseeker's Allowance dataset, selecting 10 rows from row 20 onwards. /api/v01/dataset/NM_1_1.data.csv?geography=TYPE486&sex=7&item=1&measures=20100&time=latest&recordlimit=10&recordoffset=20
CSV file for all districts from Jobseeker's Allowance dataset, selecting no rows, so that we can see what column headings are available. /api/v01/dataset/NM_1_1.data.csv?geography=TYPE486&sex=7&item=1&measures=20100&time=latest&recordlimit=0
CSV file for all districts from Jobseeker's Allowance dataset, selecting the last 5 rows of data in the results. /api/v01/dataset/NM_1_1.data.csv?geography=TYPE486&sex=7&item=1&measures=20100&time=latest&recordoffset=-5

Tabulating from one value per-row into grouped columns

This is an advanced feature that is similar to output that can be produced using Pivot Tables in Microsoft Excel against our standard download.

To extract data in a format where more than one value is present on a row (e.g. by geography in the rows and gender repeated in the columns), you can specify the grouping using the "rows" and "cols" parameters.

You have a 25000 cell limit on the number of data values for these tabulations.

You can have multiple selections in the "rows" and "cols" parameters, the data will always be output sorted and grouped as required (see examples below). The rows and cols you specify form the basis for result ordering; numbers are sorted numerically and text is sorted alphabetically. For example, if you specify "sex" your results will be ordered by the sex code (e.g. 5, 6, 7; giving male, female then total), if you specify "sex_name" the results will be ordered by the actual sex name (e.g. Female, Male, Total).

The column labels and their order are modified when tabulating:

  • When you group on one column and have selected only one data record column (e.g. OBS_VALUE); the column heading will be the actual code or name (e.g. "Male") and the column with the actual code or name will be automatically hidden.
  • When you group on one column and have selected multiple data record columns (e.g. OBS_VALUE,OBS_STATUS); the column heading will be the actual code or name followed by the record column description (e.g. "Male: OBS_VALUE"). The column containing the actual code or name will be automatically hidden.
  • When you group on multiple columns each of the things you designate as cols (together with their associated data columns), will be labelled with normal column descriptions prefixed with "GROUP n:" where n indicates the structural grouping level (e.g. 1, 1.1, 1.2 etc.).

You can hide column headings completely by adding "ExcludeColumnHeadings=true" to your URI. You can also hide the outputs of items specified in the "rows" and "cols" by enclosing the names in brackets - e.g. "cols=(sex)". Data will still be sorted and grouped correctly, but as descriptive detail will be removed it may be hard to interpret the results correctly. You should only hide grouped columns where you know exactly which data you are extracting and the order it is being extracted in.

Notes:

  • Any columns in your pre-tabulated CSV (e.g. all possible columns, or anything in your filtered "select" parameter) that aren't in your "rows" and "cols" parameters and are not naturally associated with one of them (e.g. "sex,sex_name") will be output automatically at the bottom level of each distinct column group (i.e. you do not need to specify OBS_VALUE or OBS_STATUS in the "cols" parameter).
  • You can only tabulate on columns that are output, so if restricting columns using "select" parameter, make sure you add any tabulated columns to this list.
  • Columns associated with the "rows" and "cols" parameters are re-ordered, but any other columns maintain their original order (or the order specified in your "select" parameter).
  • You cannot exclude missing values when tabulating, if specified, the option will be ignored.
  • If you select associated columns (e.g. "sex,sex_name") in your output and group by the main column (e.g. "cols=sex") the associated columns will automatically be grouped with it and if hidden (e.g. with "cols=(sex)") then all will be hidden.
  • If you specify the "rows" parameter but do not specify "cols", your data will be sorted based on that specification. Your output will contain one value per row and column headings will not be modified. This can be a useful way to sort your data on multiple columns (see the final example below).

Warning:

  • You can use tabulation in conjunction with pagination, however, you must be careful to select ranges of records that are balanced in terms of the data they contain (i.e. don't start and stop mid-dimension). The results of tabulation performed with incorrectly balanced pagination is undefined, as column headings and calculations are based on the data from the first complete tabulated row.

Example:
For reference, a standard CSV download /api/v01/dataset/NM_1_1.data.csv?geography=TYPE480&sex=5,6,7&item=1&measures=20100&time=latest&select=geography_name,sex_name,obs_value
Tabulate the above CSV download so that geography is in rows and gender repeated in columns (sorted by name) /api/v01/dataset/NM_1_1.data.csv?geography=TYPE480&sex=5,6,7&item=1&measures=20100&time=latest&select=geography_name,sex_name,obs_value&rows=geography_name&cols=sex_name
Tabulate the above CSV download so that geography is in rows and gender repeated in columns (sorted by code) /api/v01/dataset/NM_1_1.data.csv?geography=TYPE480&sex=5,6,7&item=1&measures=20100&time=latest&select=geography_name,sex,sex_name,obs_value&rows=geography_name&cols=sex
Tabulate the above CSV download so that geography is in rows (sorted by Nomis code) and gender repeated in columns (sorted by code) /api/v01/dataset/NM_1_1.data.csv?geography=TYPE480&sex=5,6,7&item=1&measures=20100&time=latest&select=geography,geography_name,sex,sex_name,obs_value&rows=geography&cols=sex
Tabulate a CSV download containing two different types of geography, so that the rows are sorted by geography alphabetically within their type in rows and gender is repeated in columns /api/v01/dataset/NM_1_1.data.csv?geography=TYPE480,TYPE464&sex=5,6,7&item=1&measures=20100&time=latest&select=geography_type,geography_name,sex_name,obs_value&rows=geography_type,geography_name&cols=sex_name
Query values and rates for latest data from Jobseeker's Allowance dataset and tabulate so that geography is within measures in rows and gender repeated in columns /api/v01/dataset/NM_1_1.data.csv?geography=TYPE480&sex=5,6,7&item=1&measures=20100,20201&time=latest&select=measures_name,geography_name,sex_name,obs_value&rows=measures_name,geography_name&cols=sex_name
Query values and rates for latest data from Jobseeker's Allowance dataset and tabulate so that geography is in the rows and measures within gender is repeated in columns /api/v01/dataset/NM_1_1.data.csv?geography=TYPE480&sex=5,6,7&item=1&measures=20100,20201&select=measures_name,geography_name,sex_name,obs_value&rows=geography_name&cols=sex_name,measures_name
Tabulate so that geography is in rows and gender repeated in columns, but this time, hide the descriptive columns for gender and exclude the heading row - you must be careful to understand the order of the results as the values are no longer fully described. /api/v01/dataset/NM_1_1.data.csv?geography=TYPE480&sex=5,6,7&item=1&measures=20100,20201&select=geography,sex,obs_value&rows=geography&cols=(sex)&ExcludeColumnHeadings=true
One value per row sorting on geography type then geography code then gender /api/v01/dataset/NM_1_1.data.csv?geography=TYPE480,TYPE464&sex=5,6,7&item=1&measures=20100&time=latest&select=geography_type,geography_code,sex_name,obs_value&rows=geography_type,geography_code,sex_name

JSON-stat : JavaScript Object Notation (JSON) Download

JSON is a light-weight data interchange format that can be parsed and then addressed as a JavaScript object in your web browser.

JSON-stat is a simple lightweight JSON dissemination format best suited for data visualization, mobile apps or open data initiatives, that has been designed for all kinds of disseminators. To download data in this format, append ".jsonstat.json" to your URI. You have a 25000 cell limit on the number of data values downloaded in this format. There are JSON-stat Tools available on the JSON-stat web site to make working with JSON-stat data files with JavaScript simple.

Nomis also offers a proprietery format of JSON data file which is a JSON conversion based on an SDMX Compact Data XML document. Please note that this format may be removed in future versions of the Nomis API as it is verbose and slow compared with JSON-stat format. To use this format, append ".data.json" to your URI. The Nomis JSON data file contains an array named "obs" which has an element for each data observation. Each of these elements has a number of variables with names that match the dimension concepts and other attributes of the value (note: all JSON variables are lower case).

Example (JSON):
JSON-stat data for a single value /api/v01/dataset/NM_1_1/jsonstat.json?geography=2038432081&sex=5&item=1&measures=20100&time=latest
Simple demo application using AJAX to obtain JSON data Simple AJAX demo application
Demo showing data in charts and graphs Nomis API and Google Visualization

Google Visualization Support (DataTable)

Google Visualization API uses a google.visualization.DataTable class to hold data that is to be rendered in a chart, graph or table.

The Nomis API can output data in a format that can be used to directly construct a Google DataTable making it very easy to produce charts, graphs and tables using Google Visualization API. To use this format, append "google.visualization.datatable.json" to your URI.

Notes:

  • You have a 25000 cell limit on the number of data values for these tabulations.
  • Use the "select", "rows" and "columns" options as detailed in the CSV download section of this document to shape the table into the correct format for your chart.
  • Where you have more than one visualization that uses the same data but with different column ordering or only a sub-set of the records you have already retrieved from Nomis, there is a google.visualization.DataView available. The DataView allows you to filter and hide columns and rows from a DataTable, when you create a chart with a DataView only the filtered set of data is plotted.

Produce data for a Google DataTable of JSA proportions for all regions with male and female. Geography is in rows and gender is repeated in columns /api/v01/dataset/NM_1_1.google.visualization.datatable.json?geography=TYPE480&item=1&sex=5,6&measures=20201&time=latest&select=geography_name,sex_name,obs_value&rows=geography_name&cols=sex_name
Example of the above API query used to produce a Google Bar Chart Nomis API DataTable output and Google Bar Chart
Below is an example visualization of a chart and table of data, put this in an HTML page to try it out. In this example we use jQuery but you can get the JSON response using other methods:
<script type="text/javascript" src="https://www.nomisweb.co.uk/libs/jquery/jquery.min.js"></script>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>

<script type="text/javascript">
google.charts.load('current', { packages: ['table', 'corechart'] });
google.setOnLoadCallback(displayData);

function displayData()
{
	$.ajax({
		url: 'http://www.nomisweb.co.uk/api/v01/dataset/NM_1_1.google.visualization.datatable.json',
		data: 'geography=2092957697&date=latestMINUS24-latest&item=1&measures=20201&select=date,sex_name,obs_value&rows=date&scols=sex_name',
		dataType: 'jsonp',
		success: function(data)
			{
				// Create google DataTable from JSON data taken directly from the Nomis API.
				var datatable = new google.visualization.DataTable(data);

				var chart = new google.visualization.LineChart(document.getElementById('nomis_chart'));
				chart.draw(datatable, {width: 800, height: 500, title: 'Nomis Data'});

				var table = new google.visualization.Table(document.getElementById('nomis_table'));
				table.draw(datatable, {showRowNumber: true});
			}
		});
		
	// You can repeat the above call with different API queries and different chart initializations
	// here to produce as many different charts as you require on your page.
}

</script>

<div id="nomis_chart"></div>
<div id="nomis_table"></div>

Mapping using Keyhole Markup Language (KML) (experimental)

This format provides data for up to 1000 areas in KML format. It can be obtained by appending ".data.kml" to your URI. You have a 1000 cell limit on the number of data values downloaded in this format.

Boundaries are only available for common areas (like regions, districts, wards, lower-level super output areas, Scottish datazones and output areas etc.).

Boundaries are shaded on an equal-interval key basis between minimum and maximum value in your results. When using this format, be sure to only request one value per area; i.e. only one of everything other than Geography.

Boundaries are extruded by an altitude proportional to their value, relative to minimum and maximum values in your results. When plotted using Google Earth the altitude of the boundary is indicative of the value relative to the others in your results.

Note: It is often best to compare rates where available, rather than absolute numbers.

Example (KML):
KML demo applications using Google Maps and Nomis KML output 2D Map
KML document for latest Jobseeker's Allowance rate for all wards in Durham district - try this URL in a search on Google Maps or add it as a "network link" in Google Earth. /api/v01/dataset/NM_1_1.data.kml?geography=2038432083TYPE312&sex=7&item=1&measures=20203&time=latest

SDMX GenericData Download

This format provides data in the SDMX GenericData document format. It can be obtained by appending ".generic.sdmx.xml" to your URI. You have a 25000 cell limit on the number of data values downloaded in this format (JSON has a a 25000 cell limit).

Example (XML):
SDMX GenericData for a single value from Jobseeker's Allowance dataset /api/v01/dataset/NM_1_1.generic.sdmx.xml?geography=2038432081&sex=5&item=1&measures=20100&time=latest
Example (JSON):
SDMX GenericData for a single value from Jobseeker's Allowance dataset /api/v01/dataset/NM_1_1.generic.sdmx.json?geography=2038432081&sex=5&item=1&measures=20100&time=latest

SDMX Structure Document

You can download all relevant parts of Codelists and Concepts together with the KeyFamily definition used by your query in one request. To do this, append ".structure.sdmx.xml" to your query path.

Codelists can often be large (for example Geography), downloading this entire list of codes and names where you may only require one or two is very resource intensive. If you only require those parts of codelists that are relevant to understanding your SDMX GenericData document then you will find this output fast and useful.

Using this SDMX Structure document in conjunction with your SDMX GenericData provides all the information you need to help present the results in a meaningful way.

SDMX CompactData Download

This format provides data in the SDMX CompactData document format. It can be obtained by appending ".compact.sdmx.xml" to your URI. You have a 25000 cell limit on the number of data values downloaded in this format.

Example (XML):
SDMX CompactData for a single value Jobseeker's Allowance dataset /api/v01/dataset/NM_1_1.compact.sdmx.xml?geography=2038432081&sex=5&item=1&measures=20100&time=latest

SDMX Compact Schema

The compact schema describes the attributes and tags used in the compact data document. It can be obtained by appending ".compactschema.sdmx.xsd" to your URI.

Microsoft Excel Spreadsheet Download (xls/xlsx)

To download your data as a Microsoft Excel spreadsheet, at the end of your query path append ".data.xlsx". To obtain older version of Excel use ".data.xls". You can change the name of the file that is downloaded by substituting "data.xls" with whatever name you would prefer (alphanumeric only, maximum 35 characters). You have a 25000 cell limit on the number of data values downloaded in this format. We automatically choose the layout that will produce the least number of tables but you can choose the concepts that go into the rows and columns using "rows=" and "cols=" (see example).

Example:
Excel file for a single value from Jobseeker's Allowance dataset /api/v01/dataset/NM_1_1.data.xls?geography=2038432081&sex=5&item=1&measures=20100&time=latest
Excel file for all sex values from Jobseeker's Allowance dataset (geography by sex layout) /api/v01/dataset/NM_1_1.data.xls?geography=2038432081&sex=5,6,7&item=1&measures=20100&time=latest&rows=geography&cols=sex

RSS Feed

You can use this to get the data formatted as an RSS Feed. When subscribed, your web browser or feed reader will notify you when the data for your URI has been updated.

This is useful for being notified when new data has been released.

To use this, append ".rss.xml" to the end of your query path. You have a 1000 cell limit on the number of data values downloaded in this format.

The RSS Feed has an Item for every observation resulting from your query. The Title of the Item is generated by describing each of the codes in each part of the series key for the observation, together with the date and the data value.

Example:
RSS feed of a single value from Jobseeker's Allowance dataset, in a time-series for the past year /api/v01/dataset/NM_1_1.rss.xml?geography=2038432081&sex=5&item=1&measures=20100&time=prevyear,latest

Specifying multiple Codes for per Concept

Your choice of code values for a concept, must be placed after a "?" at the end of your URI, separated by a "," character.

You can also specify ranges. There are two types of range supported, the first (placing a "-" between two values) is used to select everything in the codelist between the first code in your range and the last code; the second (placing an ellipsis "..." between two values) is used to select all codes that are in the numeric range from the first code to the last.

Example (XML):
SDMX GenericData for three values (male, female and total sex) from the Jobseeker's Allowance dataset /api/v01/dataset/NM_1_1.generic.sdmx.xml?geography=2038432081&sex=5,6,7&time=latest&item=1&measures=20100
Example (JSON-stat):
JSON formatted data for three values (male, female and total sex) from the Jobseeker's Allowance dataset /api/v01/dataset/NM_1_1.jsonstat.json?geography=2038432081&sex=5,6,7&time=latest&item=1&measures=20100
Example - Comma Separated Values (csv):
CSV download for three values (male, female and total sex) from the Jobseeker's Allowance dataset /api/v01/dataset/NM_1_1.data.csv?geography=2038432081&sex=5,6,7&time=latest&item=1&measures=20100

Make your own User-Defined components

You can combine the codes of some dimensions such as Age, Geography, Occupation and Industry to create your own aggregate figure. This is an advanced feature of the interface and the syntax for it is as follows:

MAKE|name|code1;code2;code3...etc.

Create a User-Defined area that combined North East, North West and Yorkshire and the Humber together geography=MAKE|my area|2013265921;2013265922;2013265923
Create a User-Defined area that combined North East, North West and Yorkshire and the Humber together (short version) geography=MAKE|my area|2013265921...2013265923
Create a User-Defined age that combined ages under 25 together age=MAKE|Young|1;2;3;4;5;6
Create a User-Defined age that combined ages under 25 together (short version) age=MAKE|Young|1...6

Lookup geography by Latitude and Longitude (experimental)

The API can take a latitude and longitude point and convert this into a geographic area recognised by Nomis. You will need the Longitude and Latitude of your point and the Nomis type number of the area you want to locate. This is an advanced feature of the interface and the syntax for it is as follows:

LATLONG|latitude;longitude;type

You can also specify a further type instruction to the API, telling it to get all areas of a certain type within the type you have located. For example where you want to find a district from a latitude and longitude and display all the wards within it.

LATLONG|latitude;longitude;type;typeswithin

Clickable map demo application using Google Maps, KML from this API and the Latitude/Longitude lookup feature. 2D click-to-explore data map
Look for the district (486) at a given latitude and longitude geography=LATLONG|53.612654;-2.4217;486
Look for the 2003 CAS Ward (312) at a given latitude and longitude geography=LATLONG|53.612654;-2.4217;312
Look for the 2003 CAS Wards (312) within the district (486) at a given latitude and longitude geography=LATLONG|53.612654;-2.4217;486;TYPE312

Lookup geography by Postcode

The API can take a postcode and from it locate a geographic area recognised by Nomis. You will need the full or partial postcode and the Nomis type number of the area you want to locate. This is an advanced feature of the interface and the syntax for it is as follows:

POSTCODE|find;type

You can also specify a further type instruction to the API, telling it to get all areas of a certain type within the type you have located. For example where you want to find a district from a latitude and longitude and display all the wards within it.

POSTCODE|find;type;typeswithin

Note: You can use a partial postcode (e.g. "DH1" or "DH1 1") to find all the areas that are covered by that partial postcode match. Where more than one area is found, these will all be added to your query.

Demo application using Google Maps, KML from this API and postcode lookup. 2D data map with postcode searching
Look for the district (486) that contains DH1 3LE geography=POSTCODE|dh1 3le;486
Look for the 2003 CAS Ward (312) that contains DH1 3LE geography=POSTCODE|dh1 3le;312
Look for the 2003 CAS Wards (312) within the district (486) that contains DH1 3LE geography=POSTCODE|dh1 3le;486;TYPE312

Cross-Origin Resource Sharing (CORS) and JSONP Callback

Cross-Origin Resource Sharing (CORS)

This standard works by adding new HTTP headers that allow servers to describe the set of origins that are permitted to read that information using a web browser. For more information on CORS, please see the W3C Cross-Origin Resource Sharing working draft. The Nomis API supports these headers both with and without pre-flight, allowing you to make cross-origin requests to our service from within your web browser JavaScript code. CORS is supported in most recent web browsers through an XMLHttpRequest (or XDomainRequest in Internet Explorer).

CORS Example:

 <html>
  <body>
    <p>This page queries Nomis for some latest data from the Jobseeker's Allowance dataset.</p>
    <p><input type="button" onclick="getData();" value="Click to get data"></p>
    
        <script type="text/javascript">
    //<![CDATA[
    
    var req = new XMLHttpRequest();
    
    function getData(){
        if(req)
        {    
            var url = 'http://www.nomisweb.co.uk/api/v01/dataset/NM_1_1.jsonstat.json?geography=2038432081&sex=7&item=1&measures=20100&time=latest';
            req.open('GET', url, true);
            req.onreadystatechange = handler;
            req.send(); 
        }
    }

    function handler(evt)
    {
        if (req.readyState == 4)
        {
            if (req.status == 200)
            {
                var response = eval('(' + req.responseText + ')');
                window.alert('Got data');
            }
            else window.alert('Error with call');
        }
    }
    //]]>
    
    </script>
  </body>
 </html>

JSON with padding (JSONP)

This is a complement to the JSON data format and an older alternative to using CORS. It allows you to request data from our server from a different domain. When requesting JSON output, you may specify a callback function in your request by adding "&callback=x" where x is the name of a function on your web page. Our JSON response will be wrapped in this function call, causing your browser to call your callback function with the data as a parameter to that function.

JSONP Example:

 <html>
  <body>
    <p>This page queries Nomis for some latest data from the Jobseeker's Allowance dataset.</p>
    
    <script type="text/javascript">
       function dataReady(data)
       {
          window.alert('Got callback');
       }
    </script>
    <script src="http://www.nomisweb.co.uk/api/v01/dataset/NM_1_1.jsonstat.json?geography=2038432081&sex=7&item=1&measures=20100&time=latest&callback=dataReady"></script>
  
  </body>
 </html>

Prevent caching

If you find your browser or application is caching API responses and you would like to ensure your URI is not cached, you may append a random number or string to your URI using a parameter called either "random" or "_" (as used by jQuery).

Example:

   <script type="text/javascript" src="http://www.nomisweb.co.uk/api/v01/dataset/NM_1_1.jsonstat.json?geography=2038432081&sex=7&time=latest&item=1&measures=20100&callback=dataReady&random=24127718">

Linking to an individual cell of data by URN

The API can directly address any individual cell of data held in the Nomis database using its unique URN.

To find the URN of a value, download data from the API as part of a normal API call and you will notice each observation has a "urn" attribute attached to it; use this to retreive that individual cell.

Example (XML):
SDMX GenericData for a single cell from the Jobseeker's Allowance dataset /api/v01/datastore/Nm-1d1d32179e1d2038432081d5d1d20100.generic.sdmx.xml
SDMX Structure Document for a single cell from the Jobseeker's Allowance dataset /api/v01/datastore/Nm-1d1d32179e1d2038432081d5d1d20100.structure.sdmx.xml
Example (JSON):
JSON formatted data for a single cell from the Jobseeker's Allowance dataset /api/v01/datastore/Nm-1d1d32179e1d2038432081d5d1d20100.json
Example - Comma Separated Values (csv):
CSV formatted data for a single cell from the Jobseeker's Allowance dataset /api/v01/datastore/Nm-1d1d32179e1d2038432081d5d1d20100.csv

Codelists

A Codelist contains a simple list of all code values, together with their names. These lists are important because they tell you what you can specify for a particular Dimension of a KeyFamily and also allow you to work out from your GenericData results (via the KeyFamily document) what the observations actually relate to.

Complete list of Codes

To obtain a specific Codelist all you need to know is the "id", you obtain this by looking at the KeyFamily document. Each "structure:Dimension" node in the KeyFamily document has a "codelist" attribute. The value of this attribute is the "id" for the Codelist of valid selectable codes for that dimension. A codelist "id" will usually begin with the letters "CL_".

Be aware that some Codelists can be very large - particularly Geography.

Example (XML):
Item codelist used by the Jobseeker's Allowance dataset /api/v01/codelist/CL_1_1_ITEM.def.sdmx.xml
Example (JSON):
Item codelist used by the Jobseeker's Allowance dataset /api/v01/codelist/CL_1_1_ITEM.def.sdmx.json
Example (HTML):
Item codelist used by the Jobseeker's Allowance dataset /api/v01/codelist/CL_1_1_ITEM.def.htm

Partial Codelists

SDMX does not formally support partial codelists, but you can use our API to retrieve a partial codelist should you only need the codes and names for part of a larger list:

Single code

To obtain a partial codelist you need to know the Codelist Id and value of the code you require.

Example (XML):
Partial Codelist of geography containing only "North East" /api/v01/codelist/CL_1_1_GEOGRAPHY/2013265921.def.sdmx.xml
Example (JSON):
Partial Codelist of geography containing only "North East" /api/v01/codelist/CL_1_1_GEOGRAPHY/2013265921.def.sdmx.json
Example (HTML):
Partial Codelist of geography containing only "North East" /api/v01/codelist/CL_1_1_GEOGRAPHY/2013265921.def.htm

Search for a Code

To search for codes where the name contains a given string, append "search=term" to your URI. Wildcard character is "*" and match is not case sensitive.

Example (XML):
Partial Codelist of areas ending with "Midlands" /api/v01/codelist/CL_27_1_GEOGRAPHY.def.sdmx.xml?search=*midlands
Example (JSON):
Partial Codelist of areas ending with "Midlands" /api/v01/codelist/CL_27_1_GEOGRAPHY.def.sdmx.json?search=*midlands
Example (HTML):
Partial Codelist of areas ending with "Midlands" /api/v01/codelist/CL_27_1_GEOGRAPHY.def.htm?search=*midlands

Concepts

A concept provides you with the name of the "thing" that the dimension relates to, if you were writing a user interface to the data, you would typically want to give the name of the concept, followed by a selection of codes from the appropriate codelist.

To obtain a specific Concept all you need to know is its "id", you obtain this by looking at the KeyFamily document. Each "structure:Dimension" node in the KeyFamily document has a "conceptRef" attribute. The value of this attribute is the "id" for the Concept.

Example (XML):
Item concept used by the Jobseeker's Allowance dataset /api/v01/concept/ITEM.def.sdmx.xml
Example (JSON):
Item concept used by the Jobseeker's Allowance dataset /api/v01/concept/ITEM.def.sdmx.json
Example (HTML):
Item concept used by the Jobseeker's Allowance dataset /api/v01/concept/ITEM.def.htm

Dataset Overview

A good way to get an overview of a dataset, its dimensions, codes and metadata is using the "overview" document, this format is specific to Nomis (not SDMX) and is available as either an XML or JSON document.

By default, all information available for a dataset is returned, but if you only require certain parts of the overview, you can use the "select" parameter to specify exactly which parts of the overview you are interested in. When you specify a select clause, then only the parts specified will be returned. Available terms are as follows (you can use multiple in a single request, separated by ","):

  • DatasetInfo - General dataset information such as name, description, sub-description, mnemonic, restricted access and status
  • Coverage - Shows the geographic coverage of the main geography dimension in this dataset (e.g. United Kingdom, England and Wales etc.)
  • Keywords - The keywords allocated to the dataset
  • Units - The units of measure supported by the dataset
  • ContentTypes - The classifications allocated to this dataset
  • DateMetadata - Information about the first release, last update and next update
  • Contact - Details for the point of contact for this dataset
  • Analyses - Show the available analysis breakdowns of this dataset
  • Dimensions - Individual dimension information (e.g. sex, geography, date, etc.)
  • Dimension-concept - Allows a specific dimension to be selected (e.g. dimension-geography would allow information about geography dimension). This is not used if "Dimensions" is specified too.
  • Codes - Full list of selectable codes, excluding Geography, which as a list of Types instead. (Requires "Dimensions" to be selected too)
  • Codes-concept - Full list of selectable codes for a specific dimension, excluding Geography, which as a list of Types instead. This is not used if "Codes" is specified too (Requires "Dimensions" or equivalent to be selected too)
  • DimensionMetadata - Any available metadata attached at the dimensional level (Requires "Dimensions" or equivalent to be selected too)
  • Make - Information about whether user defined codes can be created with the MAKE parameter when querying data (Requires "Dimensions" or equivalent to be selected too)
  • DatasetMetadata - Metadata attached at the dataset level
Example (XML):
Overview for Jobseeker's Allowance dataset /api/v01/dataset/nm_1_1.overview.xml
Overview for Jobseeker's Allowance dataset with view restricted to mainly metadata /api/v01/dataset/nm_1_1.overview.xml?select=DateMetadata,DatasetMetadata,Dimensions,DimensionMetadata
Example (JSON):
Overview for Jobseeker's Allowance dataset /api/v01/dataset/nm_1_1.overview.json
Overview for Jobseeker's Allowance dataset with view restricted to mainly metadata /api/v01/dataset/nm_1_1.overview.json?select=DateMetadata,DatasetMetadata,Dimensions,DimensionMetadata

API Key, your Unique ID and Signatures

Use of the API key is optional. If you do not use an API key, then you will be an anonymous "guest" user, the size of download will be limited to 25,000 cells.

To use the API anonymously, simply don't specify a Unique ID or Signature in your request.

To use the API without cell limits, you need to specify either your Unique ID for server-side calls (treat your Unique ID like a password, never pass it on to third parties) or your Signature for publically viewable URIs when you first create your RESTful URI.

To use your Unique ID, append it using "?uid=0x..............." on your URI, alternatively in links that you intend to make publically viewable, specify your signature in the form "?signature=.......". For more information about your Unique ID or creating a signature from your public and private keys, sign in on the Nomis homepage, click "my account" then "web services".

Error handling

If there is an error with the way your URI is formed, or Nomis is suffering internal server issues you may encounter an error.

When an error occurs:

  • Response HTTP Status Code will be set to 500 (internal server error)
  • Response body will contain information about the error (format will match that of requested page where possible - e.g. XML, JSON etc.)

Example error messages:

JSON

    { "error" : "Unable to contact data engine" }
    

XML

    <?xml version="1.0" encoding="UTF-8"?>
    <Error>Unable to contact data engine</Error>
    

Plain text (CSV etc.)

    Error: Unable to contact data engine