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 summary
This is a brief summary of the APIs available, see below for details. In the tables the API links are live examples and offer both JSON and HTML views of the data. Note that the HTML views are offered as an aid to debugging and development, they are not intended for presentation to consumers.
API structure
The APIs provide a REST style access to the data via simple 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 alerts from: /food-alerts/id
will return a JSON data packet similar to the following (details will depend on the currently available alerts):
{
"@context": "http://data.food.gov.uk/food-alerts/doc/context-TBD.jsonld",
"meta": {
"publisher": "Food Standards Agency",
"licence": "http://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/",
"documentation": "http://data.food.gov.uk/food-alerts/ui/reference",
"version": "0.1",
"comment": "Beta-test service",
"hasFormat": [
"http://data.food.gov.uk/food-alerts/id.csv?_limit=10",
"http://data.food.gov.uk/food-alerts/id.rdf?_limit=10",
"http://data.food.gov.uk/food-alerts/id.ttl?_limit=10",
"http://data.food.gov.uk/food-alerts/id.html?_limit=10"
],
"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",
...
}
]
}
The returned JSON data from all API endpoints follows the same structure of three elements: context, metadata and item(s).
The @context
reference is provided to enable the JSON data to be read directly as json-ld, but this an extension that is not yet supported.
Metadata and versioning
The metadata block provides information on the publisher and applicable licence as well as a link to this, or other, documentation. If the resource is also available in other formats then hasFormat
will supply list of URLs for those alternative formats (the media type is implied by a suffix, see content types).
"meta": {
"publisher": "Food Standards Agency",
"licence": "http://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/",
"documentation": "http://data.food.gov.uk/food-alerts/ui/reference",
"version": "0.1",
"comment": "Beta-test service",
"hasFormat": [
"http://data.food.gov.uk/food-alerts/id.csv",
"http://data.food.gov.uk/food-alerts/id.rdf",
"http://data.food.gov.uk/food-alerts/id.ttl",
"http://data.food.gov.uk/food-alerts/id.html"
]
}
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.
Finally, in the case of calls which provide lists of results any applied limit to the length of the list and offset from the start of the list will be shown in the metadata as limit
and offset
values, for example:
"meta": {
"publisher": "Food Standards Agency",
"licence": "http://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/",
"documentation": "http://data.food.gov.uk/food-alerts/ui/reference",
"version": "0.1",
"comment": "Beta-test service",
"hasFormat": [ ... ],
"limit": 10,
"offset" : 50
}
Items
The items
element in the JSON response will be an array containing objects describing items in the data. If requesting a description of a single item the items
element will still be an array (just with one element). If a list search returns no results then the items
array will be empty.
Each item will normally be identified by a URI given in the @id
field. Thus, for example in the more complete version of the earlier example we can see the alert has a URI, the last element of which matches the notation field (FSA-AA-01-2018
). This is a common pattern and when referencing items in API calls then it is often possible to just use this last element in place of the full URI.
"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",
"problem": [ ... ],
"productDetails": [ ... ],
"reportingBusiness": {
"commonName": "Tesco"
},
"title": "Tesco recalls its Tesco’s finest chocolate cake because of undeclared nuts (walnuts)",
"type": [
"http://data.food.gov.uk/food-alerts/def/AA",
"http://data.food.gov.uk/food-alerts/def/Alert"
]
}
]
When one item references another, such as in this case, the API will typically include key attributes of the referenced item in-line for convenience. However, we can always fetch (i.e. HTTP GET) data from the URI of the referenced item to obtain a full description.
Content Types
The descriptions of individual items can be obtained in multiple formats. The default format is JSON, but all item descriptions can also return information in RDF formats (RDF/XML and Turtle) and as HTML. The HTML rendering is intended as an aid to help developers understand the data, it is not an end-user application.
Similarly lists of items can be obtained in JSON, CSV and HTML as well as RDF formats.
To select the desired format use standard HTTP content negation. E.g.:
curl -i -H "Accept: text/csv" http://data.food.gov.uk/food-alerts/id?_limit=10
All endpoints also support a shortcut of appending a type suffix to the URI to force a particular content type. The supported suffixes are:
Suffix | Type |
.json | application/json |
.html | text/html |
.csv | text/csv |
.ttl | text/turtle |
.rdf | application/rdf+xml |
So the earlier example is equivalent to simply fetching the URL:
By default the CSV content returns 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 see all recent Allergy Alerts we can use the filter type=AA
:
We can then filter those to alerts which only reference the allergen walnut
:
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).
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. |
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.
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
The API endpoints for retrieving alert information are summarized below:
Each for the lists by default will return a summary view of the information. The fields included are indicated by default
in the view column of the structure tables. To view all of the information use _view=full
.
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:
Other country codes are GB-WLS
, GB-SCT
and GB-NIR
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:
Current and 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.