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.

WhatAPIParameters
List alerts /food-alerts/id
[json] [html]
type={type} problem.allergen={allergen} {path}={value} _view=default|full
List alerts changed since some point in time /food-alerts/id?since={ISOdatetime}
[json] [html]
type={type} problem.allergen={allergen} {path}={value} _view=default|full
Search for alerts matching some search term /food-alerts/id?search={search-term}
[json] [html]
type={type} problem.allergen={allergen} {path}={value} _view=default|full
An individual alert /food-alerts/id/{id}
[json] [html]
List of codes for allergens /food-alerts/def/allergens
[json] [html]
List of codes for pathogen risks /food-alerts/def/pathogen-risks
[json] [html]
List of hazard categories /food-alerts/def/hazards
[json] [html]
List of reasons for alert /food-alerts/def/reasons
[json] [html]

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:

SuffixType
.jsonapplication/json
.htmltext/html
.csvtext/csv
.ttltext/turtle
.rdfapplication/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:

QueryMeaning
_view=full|..An alternative view of the items. The default view includes just summary properties. The full view includes everything.
_limit=xReturn 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=xReturn the list of items starting with the xth 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:

FieldMeaningTypeOccursViews
titleShort title for the alert, guidelines suggest a length between 50 and 90 characters.string (language specific)full, default
shortTitleShortened version of the title of the alert for use in social media.string (langauge specific)full, default
descriptionThe 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
createdThe date the alert was created.xsd:datefull, default
modifiedThe date and time the alert was last modified. Note that major modifications will result in a new alert.xsd:dateTimefull, default
notationUnique identifier for the alertxsd:stringfull, default
actionTakenDescription of the action taken, or in the case of FAFAs actions to be taken by enforcement authority.string (language specific)optionalfull
consumerAdviceText giving the advice to consumersstring (language specific)optionalfull
SMStextShort description to be used in SMS notificationsstring (language specific)optionalfull
twitterTextShort description to be used in Twitter notificationsstring (language specific)optionalfull
alertURLURL 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:Resourceoptionalfull, default
shortURLShortened URL for this alert suitable for use in tweets and SMS.rdf:Resourceoptionalfull
relatedMediaOptional 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:Resourcemulti-valuedfull
relatedMedia.titleTitle for the option media.string (language specific)optionalfull
countryCountry 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:Conceptfull, default
country.labelLabel for a country to which the alert applies. string (language specific)full, default
problemOne 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:Problemmulti-valued, optionalfull, default
productDetailsOne or more structured descriptions of products which are the subject of the alert.alert:ProductDetailmulti-valued, optionalfull, default
reportingBusinessThe food business reporting the alert. May not be present in the case of FAFAsorg:Organizationoptionalfull, default
otherBusinessOptional additional businesses involved, e.g. distributing supermarkets. If there are multiple values present this field value will be an array.org:Organizationoptionalfull
previousAlertOptional, used for alerts which substantially update a previous alert.alert:Alertoptionalfull
statusThe status of the Alert, normally this will be alert:Published but in rare cases may be changed to alert:Withdrawnalert:Statusfull, default
status.labelThe name of the status of the Alert, normally this will be 'Published' but in rare cases may be changed to 'Withdrawn'.stringfull, default
typeType 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:Resourcemulti-valuedfull, 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:

FieldMeaningTypeOccursViews
problem.riskStatementText 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.allergenZero, 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:Allergenmulti-valuedfull, default
problem.allergen.labelA name for the problem.allergen.xsd:stringfull, default
problem.allergen.notationA string or other value which uniquely identifies the problem.allergen.full
problem.allergen.riskStatementDefault text describing the risk from this allergenstring (language specific)full
problem.hazardCategoryClassifies 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:HazardCategoryoptionalfull, default
problem.hazardCategory.labelA name for the problem.hazardCategory.xsd:stringfull, default
problem.hazardCategory.notationA string or other value which uniquely identifies the problem.hazardCategory.full
problem.pathogenRiskClassifies the problem as being due to actual or possible contamination with a pathogen.alert:PathogenRiskoptionalfull, default
problem.pathogenRisk.labelA name for the problem.pathogenRisk.xsd:stringfull, default
problem.pathogenRisk.notationA string or other value which uniquely identifies the problem.pathogenRisk.full
problem.pathogenRisk.pathogenIndicates the actual pathogen involved. The PathogenRisk may represent actual or possible contamination with this pathogen.skos:Conceptfull
problem.pathogenRisk.riskStatementDefault text describing the risk from this pathogen, or possible pathogenstring (language specific)full
problem.reasonClassifies 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:Reasonoptionalfull, default
problem.reason.labelA name for the problem.reason.xsd:stringfull, default
problem.reason.notationA 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:

FieldMeaningTypeOccursViews
productDetails.productNameName of the affected productstring (language specific)full, default
productDetails.productCodeIdentifying code for the affected productxsd:stringoptionalfull
productDetails.packSizeDescriptionDescription of the package size affected - may be weight, volume or other description.string (language specific)optionalfull
productDetails.allergenZero, 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:Allergenmulti-valuedfull
productDetails.batchDescriptionOne 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:BatchDescriptionmulti-valuedfull
productDetails.productCategoryIdentifies 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:ProductCategoryoptionaldefault

The description of the affected batch is expressed using a set of properties:

FieldMeaningTypeOccursViews
productDetails.batchDescription.bestBeforeDescription'Best before' date range for the batch expressed in text form for presentation.string (language specific)optionalfull
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:gMonthYearoptionalfull
productDetails.batchDescription.useByDescription'Use by' date range for the batch expressed in text form for presentation.string (language specific)optionalfull
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:gMonthYearoptionalfull
productDetails.batchDescription.batchCodeBatch number or code for the batch expressed in text form for presentation.string (language specific)optionalfull
productDetails.batchDescription.lotNumberLot number for batch expressed in text form for presentation.string (language specific)optionalfull
productDetails.batchDescription.batchTextDescriptionOther textual description for the batch.string (language specific)optionalfull

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.

FieldMeaningTypeOccursViews
commonNameName 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
identifierIdentifier 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.optionaldefault
legalNameLegal (registered) name of the organization. This field will not be supported in the initial version of the system. optionaldefault

Alert API

The API endpoints for retrieving alert information are summarized below:

WhatAPIParameters
List alerts /food-alerts/id
[json] [html]
{path}={value} _view=default|full
List alerts changed since some point in time /food-alerts/id?since={ISOdatetime}
[json] [html]
{path}={value} _view=default|full
Search for alerts matching some search term /food-alerts/id?search={search-term}
[json] [html]
{path}={value} _view=default|full
An individual alert /food-alerts/id/{id}
[json] [html]

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:

WhatAPIParameters
List of codes for allergens /food-alerts/def/allergens
[json] [html]
List of codes for pathogen risks /food-alerts/def/pathogen-risks
[json] [html]
List of hazard categories /food-alerts/def/hazards
[json] [html]
List of reasons for alert /food-alerts/def/reasons
[json] [html]

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.