Introduction
FSA Food Alerts API Documentation
Last update: 30th Jan, 2018
Introduction
The FSA Food Alerts API provides access to current and recent Food Alerts: Allergy Alerts (AA), Product Recall Information Notices (PRIN) and Food Alerts for Action (FAFA). It provides applications with the facility to list alerts matching some filter criterion, and to retrieve a description of an alert.
This is a beta release of the Food Alerts API. The format of the data, and the API endpoints, should remain stable for the forseeable future. We will aim to fix bugs that are reported, but will aim not to make any breaking changes unless that is unavoidable. The data being served from this API represents Food Alerts issued by the FSA from January 2018 onwards. Historical collections of food alerts may be obtained via the FSA Data Catalog
If you have questions or suggestions on using the new API please contact our Data Team at: data@food.gov.uk.
API Structure
Each API endpoint provides REST style access to the data via HTTP GET requests. Data can be returned in a range of formats including JSON, CSV and web pages.
Simple Requests
For example fetching a list of resources from: /food-alerts/id?_limit=10
will return a JSON data packet similar to the following:
{
"meta": {
"comment": "Updated beta-service, API backward compatible",
"license": "http://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/",
"licenseName": "OGL 3",
"publisher": "Food Standards Agency",
"version": "0.3",
"limit": 10
},
"items": [
{
"@id": "http://data.food.gov.uk/food-alerts/id/FSA-AA-01-2018",
"created": "2018-01-09",
"modified": "2018-01-29T16:17:27+00:00",
"notation": "FSA-AA-01-2018",
...
}
...
]
}
All of the JSON descriptions returned by the API are comprised by metadata
and items
blocks.
Metadata and Versioning
The metadata description included in JSON and RDF results provides information about the API,
such as the publisher and applicable licence.
If the resource is also available in other formats,
then the hasFormat
or dct:hasFormat
property will give list of URLs for those alternative formats.
See content types for more information about the available content types.
{
"meta": {
"comment": "Updated beta-service, API backward compatible",
"license": "http://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/",
"licenseName": "OGL 3",
"publisher": "Food Standards Agency",
"version": "0.3",
"limit": 10
},
...
}
The metadata block also includes version number information. The intention is that, after initial release,
updates to the API should maintain backward compatibility. If an incompatible change to the API is required
then we will attempt to provide access to the prior version for a transitional period. In that case the
meta
block will also provide replaces
and isReplacedBy
links between
the new and the old versions of the affected API endpoints.
When a list of resources is requested,
the metadata description will include any applied limit to the length of the list and offset from the start of the list.
They will be shown in the metadata as limit
and offset
values, as in the example above.
Items
The items
element in the JSON response will be an array containing objects describing resources in the data.
When requesting a description of a single item the items
element will still be an array (just with one element).
If a list request returns no results then the items
array will be empty.
Each item will normally be identified by a URI given in the @id
field.
"items": [
{
"@id": "http://data.food.gov.uk/food-alerts/id/FSA-AA-01-2018",
"created": "2018-01-09",
"modified": "2018-01-29T16:17:27+00:00",
"notation": "FSA-AA-01-2018",
...
}
...
]
When one resource references another, the API will typically include key attributes of the referenced resource in-line. Alternatively, you can fetch (i.e. HTTP GET) the URI of the referenced resource to obtain a full description (depending on the URI, the descriptions of related resources may not be served by this API).
Content Types
The descriptions of individual resources can be obtained in multiple formats. When accessing the API through your browser, the format will be HTML, but JSON and RDF formats (RDF/XML and Turtle) are also supported.
Similarly, lists of resources can be obtained in JSON, CSV and HTML and RDF formats. For resources with associated geometries, GeoJSON format is also supported.
To request a specific content type, use standard HTTP content negotiation, for example:
curl -i -H "Accept: text/csv" /food-alerts/id?_limit=10
You can also request a specific content type by appending a path extension to the URI,
or by supplying the extension as the _format
query parameter.
The supported values are:
Suffix | Type |
---|---|
.csv | text/csv |
.geojson | application/geo+json |
.html | text/html |
.json | application/json |
.rdf | application/rdf+xml |
.ttl | text/turtle |
So the earlier example is equivalent to simply fetching the URL:
By default, the CSV results will use column names matching the property paths in the corresponding JSON format.
Lists: Filtering and Paging
Some endpoints return information describing a single identified item but many return information on a list of items. Such list endpoints support query parameters to filter the list to only include some items. In most cases these filters take the form:
prop1.prop2...propn=value
Here, the props
are the short property names that appear in the JSON format and the
value
is the value that the property is required to have. The value might be a number, a string, a
date or a URI. In the case of the URI then you can often use the last segment of the URI on its own.
For example, to list all Allergy Alerts since the start of 2024 use:
If the same filter is used twice with different values then the API will return results for both values (i.e. it acts as a disjunction).
You can apply prefixes to the parameter in order to apply standard filters to your query:
Prefix | Meaning |
---|---|
min- |
Applies a strictly greater than filter. |
mineq- |
Applies a greater than or equal to filter. |
max- |
Applies a strictly less than filter. |
maxeq- |
Applies a less than or equal to filter. |
For example, supply the parameter min-dob=12/03/1993
to query resources with date of birth after 12/03/1993.
You can also specify a filter range using (
and )
for exclusive bounds,
and (*
and *)
for inclusive bounds.
The upper and lower boundary values are separated with ..
.
Note that you can use both kinds of boundaries in a single query, eg. friends=(4..17*)
.
Note When filtering on a range of date-times, to ensure accurate comparison,
you should include the timezone on the timestamp that you want to compare values to.
For example, to write a timestamp in UTC time, append a Z
to the end.
See here for more information.
When filtering on resource values, you can reference the resource by its URI or its compact URI, based on the defined namespace prefixes. Note that when URIs are supplied in query parameters, they must be correctly encoded.
type=http%3A%2F%2Fwww.w3.org%2F2004%2F02%2Fskos%2Fcore%23Concept
type=skos:Concept
Some endpoints also support referencing resources by just their short names, for example type=Concept
.
List endpoints also support view modification parameters. These are distinguished by starting with an underscore character. The commonly supported modifiers are:
Query | Meaning |
---|---|
_view=full|.. |
An alternative view of the items. The default view includes just summary properties. The full view includes everything. |
_limit=x |
Return only x items from the list, some endpoints may impose a default limit and/or a maximum to which the limit can be set. |
_offset=x |
Return the list of items starting with the x th item, together with _limit this enables paging through a long set of results. |
_sort=prop.prop... |
Reorder the list of results in ascending order of the given property (or property chain). To sort in descending order use _sort=-prop . More than one sort can be included in which case they will be applied in order. |
_count=prop1,prop2... |
Request an aggregated count query on the given properties. Use @id to denote a count on the total number of results. |
_groupBy=prop1,prop2... |
When requesting an aggregated query using _count , perform a grouping on the given properties. |
If a limit or offset is applicable, whether explicit in the query or implicitly imposed by the API, then the
metadata object will include a limit
or offset
field to show what limits were applied.
Projection
The _projection
query parameter lets you specify a set of properties to return for each resource.
The properties that are returned by each endpoint by default are defined in "Returned Data" section.
You can also specify any of the properties that are documented on the class corresponding to the endpoint result.
See the model documentation for full details of the classes in the data model.
- Use
.
to specify nested properties:prop1.prop2
- Use
,
to separate properties or property paths. - Use
()
in case you want to specify multiple child properties:prop1(prop2,prop3)
.
This is just a shorthand forprop1.prop2,prop1.prop3
- Use wildcard
*
to request all nested properties:prop1(*)
.
The wildcard is not recursive and will only include the immediate child properties.
You can also supply the _withView
query parameter (no value is required) to include the properties on
selected view in addition to your projection.
The view can be selected with the _view
query parameter, otherwise the API will use the default view.
API Summary
This is a brief summary of the APIs available, see below for details.
Note that the HTML views are offered as an aid to debugging and development,
but they are not intended for presentation to consumers.
All URIs are relative to the service base URI of http://data.food.gov.uk/food-alerts
.
Alerts
Description | API | Parameters |
---|---|---|
List of all alerts | /food-alerts/id [json] [html] |
type={type}
problem.allergen={allergen}
_view={default|full}
|
Details of a single alert | /food-alerts/id/{id} [json] [html] |
id={value}
_view={default}
|
List of codes for allergens | /food-alerts/def/allergens [json] [html] |
_view={default}
|
List of codes for pathogen risks | /food-alerts/def/pathogen-risks [json] [html] |
_view={default}
|
List of hazard categories | /food-alerts/def/hazards [json] [html] |
_view={default}
|
List of reasons for alert | /food-alerts/def/reasons [json] [html] |
_view={default}
|
Alerts
Alerts are returned as a nested JSON structure with top level summary text and nested structures to describe the problem(s) leading to the specific risks to the consumer and the details of the affected product(s).
Alert structure: top level
Note on namespaces
The underlying data representation for Food Alerts is the
Resource Description Framework (RDF).
In RDF, constant identifiers, such as an alert or the class of all problems are
represented as web addreses (aka
URIs).
In order to avoid writing out long URI in full, we abbreviate them using
namespaces, such as alert:Problem
. Taking the namespace
alert
to have the value http://data.food.gov.uk/food-alerts/def/
,
the abbreviation thus expands to http://data.food.gov.uk/food-alerts/def/Problem
.
In the JSON serialisation of the alerts data, namespaces are typically omitted for clarity.
The top level structure of an individual alert is:
Field | Meaning | Type | Occurs | Views |
---|---|---|---|---|
title | Short title for the alert, guidelines suggest a length between 50 and 90 characters. | string (language specific) | full, default | |
shortTitle | Shortened version of the title of the alert for use in social media. | string (langauge specific) | full, default | |
description | The main textual description of the alert not including the sections covered elsewhere (risk, product details, action taken, consumer advice). For most alerts (AA, PRIN) this will be the summary paragraph. FAFAs allow for more extensive text in the Alert description. | string (language specific) | full | |
created | The date the alert was created. | xsd:date | full, default | |
modified | The date and time the alert was last modified. Note that major modifications will result in a new alert. | xsd:dateTime | full, default | |
notation | Unique identifier for the alert | xsd:string | full, default | |
actionTaken | Description of the action taken, or in the case of FAFAs actions to be taken by enforcement authority. | string (language specific) | optional | full |
consumerAdvice | Text giving the advice to consumers | string (language specific) | optional | full |
SMStext | Short description to be used in SMS notifications | string (language specific) | optional | full |
twitterText | Short description to be used in Twitter notifications | string (language specific) | optional | full |
alertURL | URL for the alert on the FSA web site. This is where the human readable presentation will appear, and is the URL that should be referenced in social media announcements. A shortened version of this URL is provided in the shortURL field. | rdf:Resource | optional | full, default |
shortURL | Shortened URL for this alert suitable for use in tweets and SMS. | rdf:Resource | optional | full |
relatedMedia | Optional URL link to a supporting document or other media, typically a PDF of a product recall notice or Point of Sale notice from the reporting business. It may also be an image of the product, or other supporting documentation. In some cases there may be multiple supporting documents, in which case the JSON value will be an array. | rdf:Resource | multi-valued | full |
relatedMedia.title | Title for the option media. | string (language specific) | optional | full |
country | Country to which the alert applies. May have more than one value (e.g. England and Wales). Absence of a country value indicates that alert may apply to any country within the UK. | skos:Concept | full, default | |
country.label | Label for a country to which the alert applies. | string (language specific) | full, default | |
problem | One or more structured descriptions of problems, or suspected problems, with the products that may pose a risk for consumers and that have led to the advice being issued. | alert:Problem | multi-valued, optional | full, default |
productDetails | One or more structured descriptions of products which are the subject of the alert. | alert:ProductDetail | multi-valued, optional | full, default |
reportingBusiness | The food business reporting the alert. May not be present in the case of FAFAs | org:Organization | optional | full, default |
otherBusiness | Optional additional businesses involved, e.g. distributing supermarkets. If there are multiple values present this field value will be an array. | org:Organization | optional | full |
previousAlert | Optional, used for alerts which substantially update a previous alert. | alert:Alert | optional | full |
status | The status of the Alert, normally this will be alert:Published but in rare cases may be changed to alert:Withdrawn | alert:Status | full, default | |
status.label | The name of the status of the Alert, normally this will be 'Published' but in rare cases may be changed to 'Withdrawn'. | string | full, default | |
type | Type of the alert, will be a generic Alert and one of AA (Allergy Alert), PRIN (Product Recall Information Notice) or FAFA (Food Alert For Action). | rdf:Resource | multi-valued | full, default |
Note that in JSON and HTML views the fields are returned in alphabetical order, the above table has been reordered to group related fields for ease of reading.
Some fields are flagged as optional at this stage to allow some flexibility during development. We expect more to become mandatory for well-formed alerts of particular types.
Alert structure: Problem description
The structure of the nested Problem description structure is:
Field | Meaning | Type | Occurs | Views |
---|---|---|---|---|
problem.riskStatement | Text describing the problem in terms of the risk to consumers. Typically this will be based on standard text patterns for the particular risk, but it may be overridden in the editor to express the particular situation at hand. | string (language specific) | full, default | |
problem.allergen | Zero, one or more allergens drawn from the controlled list of allergens. For an Allergen Alert there will also be at least one allergen present on the problem statement. | alert:Allergen | multi-valued | full, default |
problem.allergen.label | A name for the problem.allergen . | xsd:string | full, default | |
problem.allergen.notation | A string or other value which uniquely identifies the problem.allergen . | full | ||
problem.allergen.riskStatement | Default text describing the risk from this allergen | string (language specific) | full | |
problem.hazardCategory | Classifies the problem as into one of the hazard categories. This information is useful for analysis and retrieval but does not directly affect the default textual presentation of the alert. Support for this field is under discussion. | alert:HazardCategory | optional | full, default |
problem.hazardCategory.label | A name for the problem.hazardCategory . | xsd:string | full, default | |
problem.hazardCategory.notation | A string or other value which uniquely identifies the problem.hazardCategory . | full | ||
problem.pathogenRisk | Classifies the problem as being due to actual or possible contamination with a pathogen. | alert:PathogenRisk | optional | full, default |
problem.pathogenRisk.label | A name for the problem.pathogenRisk . | xsd:string | full, default | |
problem.pathogenRisk.notation | A string or other value which uniquely identifies the problem.pathogenRisk . | full | ||
problem.pathogenRisk.pathogen | Indicates the actual pathogen involved. The PathogenRisk may represent actual or possible contamination with this pathogen. | skos:Concept | full | |
problem.pathogenRisk.riskStatement | Default text describing the risk from this pathogen, or possible pathogen | string (language specific) | full | |
problem.reason | Classifies the reason for the problem as being one of a standard set of reasons. This information is useful for analysis and retrieval but does not directly affect the default textual presentation of the alert. Support for this field is under discussion. | alert:Reason | optional | full, default |
problem.reason.label | A name for the problem.reason . | xsd:string | full, default | |
problem.reason.notation | A string or other value which uniquely identifies the problem.reason . | full |
In order to render a human-readable presentation of the alert, consistent with the current presentation on food.gov.uk, only the riskStatement
and the list of allergen
(or in indeed just allergen.label
) values is needed. The pathogenRisk
, hazardCategory
and reason
(and their nested structure) are provided as a means to categorize the problem to enable filtering, navigation and analytics. They need not be separately included in the presentation since the riskStatement
should already describe the associated risk. The use of these coding schemes is under discussion at present and may be subject to change.
Alert structure: Product Detail
For each alert there will be one or more products that are affected. The product detail structure describes the products and the particular batches affected:
Field | Meaning | Type | Occurs | Views |
---|---|---|---|---|
productDetails.productName | Name of the affected product | string (language specific) | full, default | |
productDetails.productCode | Identifying code for the affected product | xsd:string | optional | full |
productDetails.packSizeDescription | Description of the package size affected - may be weight, volume or other description. | string (language specific) | optional | full |
productDetails.allergen | Zero, one or more allergens drawn from the controlled list of allergens. The overall problem statement will include all allergens, however in some cases a single Alert might involve multiple products with different allergens present in each. This field supports that situation. | alert:Allergen | multi-valued | full |
productDetails.batchDescription | One or more descriptions of the product batches affected by the alert. In most cases there will only be a single batch description for each product detail, but in rare cases there can be a table of such descriptions. | alert:BatchDescription | multi-valued | full |
productDetails.productCategory | Identifies the category of the affected product. This information is used to support search and analysis and does not need to be separately included in the alert presentation. | alert:ProductCategory | optional | default |
The description of the affected batch is expressed using a set of properties:
Field | Meaning | Type | Occurs | Views |
---|---|---|---|---|
productDetails.batchDescription.bestBeforeDescription | 'Best before' date range for the batch expressed in text form for presentation. | string (language specific) | optional | full |
productDetails.batchDescription.bestBeforeDate | 'Best before' date (or dates) for the batch. In some cases there may be multiple dates or the dates by might be given as month-year only. This field is used for API filtering and not for presentation, the presentation form is given by the bestBeforeDescription field. | xsd:date or xsd:gMonthYear | optional | full |
productDetails.batchDescription.useByDescription | 'Use by' date range for the batch expressed in text form for presentation. | string (language specific) | optional | full |
productDetails.batchDescription.useByDate | 'Use by' date (or dates) for the batch. In some cases there may be multiple dates or the dates by might be given as month-year only. This field is used for API filtering and not for presentation, the presentation form is given by the useByDescription field. | xsd:date or xsd:gMonthYear | optional | full |
productDetails.batchDescription.batchCode | Batch number or code for the batch expressed in text form for presentation. | string (language specific) | optional | full |
productDetails.batchDescription.lotNumber | Lot number for batch expressed in text form for presentation. | string (language specific) | optional | full |
productDetails.batchDescription.batchTextDescription | Other textual description for the batch. | string (language specific) | optional | full |
A specific batch description may have only one of these properties or any combination of them. The specific properties chosen should allow the information to consumers to be presented appropriately. For example, there may be no practical difference between a "batch number" and a "lot number" but it is helpful to use the specific phrasing which matches the product packaging. We anticipate that more of these presentation properties may need to be added during development. If there is no suitable specific property available then use the generic batchTextDescription
field and phrase the value appropriately.
The dates are captured in both textual and numeric form. Only the textual form should be presented since this will include phrasing intended to best convey to specific date range to consumers. The numeric form is included to allow some measure of filtering but does not completely capture all the ways in which date ranges are expressed in the alerts.
Alert structure: Businesses
Where the alerts link to businesses (either the reportingBusiness
or otherBusiness
) the business will be represented by a nested structure. In future a common register of food businesses operators (FBOs) may be developed to provide access to such enriched business information. The nested structure shown below provides for this future extension. However, during the initial release of the system only the commonName
field will be present.
Field | Meaning | Type | Occurs | Views |
---|---|---|---|---|
commonName | Name by which the organization is commonly known. Following FSA guidance, this common name is preferred to the legal entity name, so "Tesco’s" rather than "Tesco Stores Ltd". | default | ||
identifier | Identifier for the organization, typically company registration number. This field will not be supported in the initial version of the system. In the future a register of food businesses may be used to obtain unique identifiers for relevant businesses. | optional | default | |
legalName | Legal (registered) name of the organization. This field will not be supported in the initial version of the system. | optional | default |
Alert API
See below for examples of useful filter parameters for each endpoint.
Description | API | Parameters |
---|---|---|
List of all alerts | /food-alerts/id [json] [html] |
type={type}
problem.allergen={allergen}
_view={default|full}
|
Details of a single alert | /food-alerts/id/{id} [json] [html] |
id={value}
_view={default}
|
Examples
Retrieve a full view of all alerts modified since a specific time:
Limit the above list to just Allergy Alerts:
Return the above results in summary form as a CSV:
Find all alerts that reference the allergen walnut:
Search for all allergy alerts than mention chocolate:
List alerts are specifically tagged as applying to England:
Returned data
Code lists
The lists of controlled codes that are used to represent allergens, pathogen risks and the various problem classifications (hazards, reasons) are all included in the data and can be retrieved as JSON, CSV or HTML in the same way:
See below for examples of useful filter parameters for each endpoint.
Description | API | Parameters |
---|---|---|
List of codes for allergens | /food-alerts/def/allergens [json] [html] |
_view={default}
|
List of codes for pathogen risks | /food-alerts/def/pathogen-risks [json] [html] |
_view={default}
|
List of hazard categories | /food-alerts/def/hazards [json] [html] |
_view={default}
|
List of reasons for alert | /food-alerts/def/reasons [json] [html] |
_view={default}
|
Returned data
Future Development
Problem coding
The API and data structures described above provide the option to categorize the problems associated with alerts in terms of both a hazard category and a reason. Whether this level of coding is both useful and practical is under discussion and this area may be subject to change as the work proceeds.
Product Category
In addition to classifying and coding problems it would be potentially possible to classify the affected products into product categories. However, the value and practicality of this is unclear at the moment. Any sufficiently comprehensive product category list is potentially long and complex to use. Furthermore, FSA is the process of developing a registry of food types which might eventually be an appropriate source of high level product categories. Given this uncertainty we do not currently provide for product categorization. This may be an area for future development.
Batch Details
The descriptions of product and product batches in historical alerts are very variable. This is natural since the descriptions need to match the way they are described on the product packaging so that consumers can understand what to look for. The current design allows some flexibility over this by allowing arbitrary text descriptions for a set of properties and allowing a range of properties in batch descriptions. We expect that some properties are missing from the initial design and will be added as the work proceeds. It is also possible that the overall approach to batch description may need to be revised.
Food Businesses
Most alerts need to link to one or more food businesses, for example the business reporting the issue or businesses like supermarkets involved in the product distribution chain. As noted earlier the design allows us to represent such businesses in a structured way, including linking to stable identifiers for businesses. However, resolving businesses to a set of identifiers is not currently possible with sufficient reliability and coverage to be included in the current development. For now businesses will only be identified by a common name. This is an area for future development.
Multilingual support
In future development we anticipate there may be a need to support Welsh language versions of Food Alerts. The
underlying data representation already supports this. We would anticipate extending the API to provide a filter
parameter to select the desired language to return results in (for example _lang=en
). However, support
for this is not planned within the current phase of work.
Namespace Prefixes
Listed below are supported namespace prefixes.
You can use them to specify the URI values of query parameters in short form.
For example, ?type=type=http%3A%2F%2Fwww.w3.org%2F2004%2F02%2Fskos%2Fcore%23Concept
is equivalent to
the prefixed short form, ?type=skos:Concept
.