Skip to main content
Warning This document has not been updated for a while now. It may be out of date.
Last updated: 28 Jun 2023

email-alert-api: Matching content to subscriber lists

Format of matching criteria

A subscriber list uses several fields to store the criteria which define how it matches published content:

JSON fields

  • links
  • tags

These fields contain a JSON object which maps keys to arrays of values, similar to the links hash on a content item. For example:

    "key_1": {
        "any": ["value_a", "value_b", "value_c"],
    "key_2": {
        "all": ["value_x", "value_y"]

Only one of these should be used on a given subscriber list. They can also both be empty {} if they aren't needed.

You can find a list of permitted tags in lib/valid_tags.rb.

For a published content item to match the subscriber list on these fields, the links/tags in the request to email-alert-api must include all of the keys. If the value includes any then at least one of the values in the array needs to match for each key. If the value includes all, then each value in the array needs to match.

links uses content ids and tags uses slugs - but the queries used on these fields don't care about that difference.

It's crucial that the key names stored in these JSON fields match the key names used in the requests to email-alert-api (which are usually the same as the ones on the content item itself - taxon_tree is an exception). It's easy to break existing subscriptions by renaming a field in the links hash on published content without updating the corresponding subscriber lists, which would mean that subscribers stop getting emails for that kind of content.

String fields

  • document_type
  • email_document_supertype
  • government_document_supertype

More than one of these can be used on a given subscriber list. The two supertype fields were added to support the migration of Whitehall subscriptions to email-alert-api.

These fields are used in addition to or instead of links/tags on a given subscriber list. For example, a travel advice subscription for a particular country uses document_type and links -> countries, whereas the travel advice index subscription (which includes all countries) only uses document_type. See this wiki page for details of how each kind of subscription works.

UUID field

  • content_id

This field stores the content ID of a page on GOV.UK.

Content ID based subscriber lists match against any content changes that share the same content ID. These lists do not have populated document_type, email_document_supertype or government_document_supertype string fields.

Content ID based lists can also have links. When both links and content ID are present, the list will match content changes by links OR by content-id.

This "OR" match means we can support reverse linked email subscriptions. For example:

A user subscribes to alerts on a document collection page, with content ID '123-abc'. The params sent to email alert api contains both links and content ID, and will create a subscriber list that contains:

content_id: "123-abc"
links: {
    "document_collections" : {
        "any"=> [ "123-abc" ]

This list will match content changes made to the page with content ID "123-abc", and it will also match content changes to child pages which are reverse linked to to page with content id "123-abc".

Finding matches

The queries on subscriber lists power the two sides of the email system: subscribing and sending emails.


When a user is subscribing to something, the frontend app handling the email signup should use the API adapters find_or_create_subscriber_list method.

This first makes a GET request to find an existing subscriber list to use, and if one isn't found, it makes a POST request to create the desired subscriber list in email-alert-api.

GET /subscriber-lists?params... searches the database for an existing subscriber list which has exactly the same criteria as are given in the query params. The order of keys and the items within the arrays in links and tags doesn't matter.

Sending emails

When a POST /content-changes request is made to email-alert-api, the data in that request is used to find all subscriber lists in the database which it matches. The matching criteria on each list act as filters on the stream of published content: as long as the request includes at least one matching value for every key in the matching criteria on the subscriber list, an email will be sent to that list.