This is one of a series of blog posts covering clinical codes and their use in OpenSAFELY research.

Electronic health records

Electronic health records (EHRs) are used to store a variety of patient information. Each patient’s record can be thought of as a series of events, each with a patient identifier, a date, a location, and associated event details. This information can be added to a patient’s electronic health records in either an unstructured way, such as free text, or in a structured way by adding the information using clinical codes.

What are clinical codes?

Clinical codes are alphanumeric or numeric identifiers corresponding to a specific piece of clinical or personal information. They also have a text description explaining the purpose of the clinical code. The information can consist of: diagnoses, observations, measurements, treatments, procedures, drugs or devices, referrals, tests, as well as patient information such as ethnicity. A numeric value may also be included with certain clinical codes, for example a systolic blood pressure reading.

An example primary care consultation including clinical coding is shown below: Example consultation with clinical coding
Data linked to clinical codes is green or blue, free text is black text.

Clinical codes can be easily searched, allowing retrieval of information in a way that would not be possible with unstructured information. This is useful in day-to-day clinical practice, audit and service evaluation, as well as research. Reasons to use clinical codes

There are many different types of clinical codes; each set of codes can be referred to as a clinical terminology system. They are used within EHRs in primary, secondary and tertiary care settings throughout the NHS, with national standards dictating their use. These clinical terminology systems can sit within or across multiple informational domains. Often their usage is setting specific, for example, OPCS-4 is a system used only to record treatments and procedures in secondary care settings.

The diagram below shows the domains covered by clinical terminology systems in the data within OpenSAFELY. Clinical terminology systems and their domains Note - Read/CTV3 codes are no longer updated within the NHS and use has transitioned to SNOMED CT codes in primary care.

Clinical terminology systems in OpenSAFELY

OpenSAFELY allows users to access many different health datasets. Users can query these using OpenSAFELY variables built for the clinical terminology systems present in each dataset. Below is an overview of the clinical terminology systems currently accessible in OpenSAFELY. If you’ve got any questions about clinical terminology systems not currently available in OpenSAFELY please get in touch to discuss this with us.


This is a structured clinical vocabulary for use in electronic health records, including in all GP systems in England. Use of SNOMED CT is mandated for capturing clinical terms within electronic patient records for all NHS providers in England. SNOMED CT is owned, administered, and developed by a not for profit organisation, and is used across the world with country specific editions and extensions as required. The UK extension contains codes for UK screening procedures, assessment scales, and British English spellings.

SNOMED CT codes are long numeric identifiers. For example, chronic kidney disease can be recorded by the code 709044004 which has the corresponding description: chronic kidney disease (disorder). The SNOMED CT codes are organised into a hierarchy; the further down the hierarchy the more precise the SNOMED CT codes get. Many conditions may be represented by a number of terms as appropriate to the situation, and chronic kidney disease is no exception - for example we have a codelist (a collection of clinical codes which will be covered in more detail in a future blog) which can detect all the possible codes that may be entered when a patient presents with chronic kidney disease.

How could I use SNOMED CT in OpenSAFELY?
In OpenSAFELY, SNOMED CT codes are present in the primary care data indicating a range of clinical and demographic information. An example of their use would be to return a cohort with a particular SNOMED CT codelist using with_these_clinical_events().

NHS Dictionary of Medicines and Devices (dm+d)

dm+d is the standard dictionary for medicines and devices used across the NHS. It contains standardised codes, descriptions, and metadata (such as price and pack size) for every entry. You can find out more about dm+d in our blog post.

dm+d codes
NHS dm+d codes are long numeric identifiers. An example for recording the virtual medicinal product for Amoxicillin 250mg capsules is 39732311000001104.

How could I use dm+d in OpenSAFELY?
In OpenSAFELY, NHS dm+d codes are present in primary care records indicating a prescription has been issued. An example of their use would be to return a cohort who had been prescribed medicines in a NHS dm+d codelist using with_these_medications().

British National Formulary (BNF)

The BNF is a reference resource containing the standard list of medicines used in UK prescribing. It gives information on the indications, dosages, and side effects for over 70,000 medicines. The BNF used to show medicines in a hierarchy (pseudo-classification); the NHS Business Services Authority now use a legacy version of the BNF hierarchy to assign codes to drugs and chemicals. More detail on BNF codes can be found in our blog post.

BNF codes
BNF codes are long alphanumeric identifiers which conform to a strict hierarchy. An example of a BNF code for Tramadol hydrochloride is 040702040.

How could I use BNF codes in OpenSAFELY?
BNF codes are not directly available in the primary care data. However, as the BNF has an intuitive hierarchy it is used by researchers to make it easier to find classes or groups of drugs based on their clinical use or mode of action. Using OpenCodelists it is possible to convert a BNF codelist to a dm+d codelist (see above for dm+d usage in OpenSAFELY).

For a detailed comparison on the difference between BNF, dm+d and SNOMED CT codes, see this blog.

International Classification of Diseases 10th revision (ICD-10)

ICD-10 is an international standard diagnostic classification, developed by the World Health Organisation, who still administer revisions and versions. ICD-10 codes cover diseases, injuries and other health problems, signs, symptoms, causes of death, and in some cases causes and social circumstances. These codes are used for all diagnosis recording in inpatient and outpatient services in the secondary care setting in the NHS. A new revision (ICD-11) is being rolled out with mandated use not expected until April 2026.

ICD-10 codes
ICD-10 codes are short alphanumeric identifiers. An example of an ICD-10 code for Urinary tract infection, site not specified is N39.0 (note the point after the 3rd digit is stripped out during processing in all datasets so is not present in the underlying data, and codes will often be represented without it).

How could I use ICD-10 in OpenSAFELY?
In OpenSAFELY ICD-10 codes are present in the SUS Admitted Patient Care Spell data and the ONS deaths data. An example of their use would be returning a cohort with an ICD-10 diagnosis codelist using admitted_to_hospital(… with_these_diagnoses=[codelist]…).

OPCS Classification of Procedures and Interventions (OPCS-4)

OPCS-4 is a clinical terminology system used to classify procedures, treatments and interventions, and used in secondary care services in the NHS.

OPCS-4 codes
OPCS-4 codes are alphanumeric identifiers. They have the same format as ICD-10 codes, so take care when using ICD-10 and OPCS codelists in your study. An example of an OPCS-4.9 code for Primary total prosthetic replacement of hip joint using cement is W37.1. Different versions of OPCS-4 are available and used in the NHS, the most recent of which being OPCS-4.10.

How could I use OPCS-4 in OpenSAFELY?
In OpenSAFELY, OPCS-4 codes are present in the SUS Admitted Patient Care Spell data. An example of their use would be returning a cohort with an OPCS-4 procedure codelist using admitted_to_hospital(… with_these_procedures=[codelist]…).