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 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.
_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 for prop1.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:

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

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

/food-alerts/id
Show
/food-alerts/id/{id}
Show

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

/food-alerts/def/allergens
Show
/food-alerts/def/pathogen-risks
Show
/food-alerts/def/hazards
Show
/food-alerts/def/reasons
Show

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.

Prefix Full URI
allergen http://data.food.gov.uk/codes/alerts/def/allergen/
reason http://data.food.gov.uk/codes/alerts/def/reason/
owl http://www.w3.org/2002/07/owl#
xsd http://www.w3.org/2001/XMLSchema#
skos http://www.w3.org/2004/02/skos/core#
schema-org http://schema.org/
rdfs http://www.w3.org/2000/01/rdf-schema#
pathogen-risk http://data.food.gov.uk/codes/alerts/def/pathogen-risk/
qb http://purl.org/linked-data/cube#
dgu http://reference.data.gov.uk/def/reference/
dct http://purl.org/dc/terms/
alert http://data.food.gov.uk/food-alerts/def/
hazard http://data.food.gov.uk/codes/alerts/def/hazard/
model http://localhost/localmapping/
api http://purl.org/linked-data/api/vocab#
text http://jena.apache.org/text#
foaf http://xmlns.com/foaf/0.1/
product http://data.food.gov.uk/codes/alerts/def/product/
void http://rdfs.org/ns/void#
org http://www.w3.org/ns/org#
id-alert http://data.food.gov.uk/food-alerts/id/
rdf http://www.w3.org/1999/02/22-rdf-syntax-ns#
def-foodtype http://data.food.gov.uk/codes/foodtype/def/terms/
id-foodtype http://data.food.gov.uk/codes/foodtype/id/
pathogen http://data.food.gov.uk/codes/alerts/def/pathogen/
dc http://purl.org/dc/elements/1.1/