Resolve virus taxa across ICTV releases programmatically.
The EVORA project (European Viral Outbreak Response Alliance) in collaboration with the ICTV (International Committee on Taxonomy of Viruses) has developed a public programmatic access to the official taxonomy of viruses by transforming ICTV releases into the ICTV ontology and serving it through the Ontology Lookup Service (OLS) API.
OLS is a REST-based web service hosted by EMBL-EBI that provides programmatic access to biomedical ontologies, including the ICTV ontology. This makes it possible to retrieve structured semantic information about virus taxa and their relationships across ICTV releases.
This is useful for:
With the ICTV OLS API, you can:
The ICTV OLS API follows REST principles and returns JSON responses, making it accessible from any programming language or environment that can make HTTP requests.
The ICTV ontology data can be accessed in two complementary ways:
Lightweight client libraries that encapsulate the complexity of direct OLS queries and provide a simple, domain-friendly interface for common use cases.
Use this if you:
Direct HTTP access to the OLS API endpoints, giving you full control and flexibility for custom queries and advanced workflows.
Use this if you:
This directory provides lightweight client libraries that make it easy to query the ICTV Ontology API, as served through the OLS API.
These helpers allow you to resolve ICTV taxon names, historical ICTV identifiers, IRIs, virus names and NCBI Taxon IDs to the current ICTV taxon, including lineage and replacement history.
Helpers are available in three languages:
js/ictv-api.js)python/ictv-api.py)php/ictv-api.php)helpers/
βββ js/
β βββ ictv-api.js
βββ python/
β βββ ictv-api.py
βββ php/
βββ ictv-api.php
js/ictv-api.js)ES module suitable for browsers, Node.js, and static sites.
Installation: Simply import from CDN or local file.
import { ICTVApi } from 'https://cdn.jsdelivr.net/gh/EVORA-project/ictv-ontology/helpers/js/ictv-api.js';
const api = new ICTVApi();
const result = await api.resolveToLatest("SARS-CoV-2");
console.log(result);
Note: Requires a module-compatible environment. Use in HTML with script type="module"> or in modern Node.js projects with "type": "module" in package.json.
Features:
No dependencies β pure ES module.
π Full JS helper documentation: See helpers/js/README.md
python/ictv-api.py)Best for: Data pipelines, scripts, Jupyter notebooks, ETL workflows
Lightweight client using the requests library.
Installation: Copy python/ictv-api.py to your project.
from ictv_api import ICTVOLSClient
client = ICTVOLSClient()
result = client.resolveToLatest("Zika virus")
print(result)
Features:
getAllFromRelease())getTaxonByRelease())π Full Python helper documentation: See helpers/python/README.md
php/ictv-api.php)Best for: Server-side integrations, CMS backends, database imports
Standalone PHP helper using cURL (built-in).
Installation: Copy php/ictv-api.php to your project.
require_once "ictv-api.php";
$api = new ICTVOLSClient();
$result = $api->resolveToLatest("Tehran virus");
print_r($result);
Features:
getAllFromRelease())getTaxonByRelease())π Full PHP helper documentation: See helpers/php/README.md
| Feature | JavaScript | Python | PHP |
|---|---|---|---|
| Basic resolution | β | β | β |
Bulk export (getAllFromRelease) |
β | β | β |
| Release-specific queries | β | β | β |
| Dependencies | None | requests |
curl (built-in) |
| Best for | π Web | π Data pipelines | π₯οΈ Server-side |
| Full Docs | js/README | python/README | php/README |
All three helper implementations follow the same general resolution strategy:
The helper libraries return a normalized ICTV taxon object containing:
This abstraction allows developers to focus on domain logic rather than on raw OLS API response handling.
π ICTV Taxon Resolver
https://evora-project.github.io/ictv-resolver/
A browser-based demonstration of the helper logic. It accepts:
and returns the latest accepted ICTV taxon with lineage and mapping information.
Source code: https://github.com/EVORA-project/ictv-resolver
For users who need direct access to the ICTV Ontology Lookup Service API without using helper libraries, this section provides guidance on constructing and executing OLS API queries.
π Official OLS Documentation: https://www.ebi.ac.uk/ols4/api-docs
The ICTV Ontology is exposed through two main sets of OLS endpoints:
https://www.ebi.ac.uk/ols4/api/ontologies/ictv
/api/suggestExamples:
https://www.ebi.ac.uk/ols4/api/v2/ontologies/ictv
Examples:
GET /api/v2/ontologies/ictv/classesGET /api/v2/ontologies/ictv/classes/{DOUBLE_URL_ENCODED_IRI}GET /api/v2/ontologies/ictv/entities/{DOUBLE_URL_ENCODED_IRI}If you want to retrieve all classes for one ICTV release, your code can query the classes endpoint while filtering by the release value stored in owl:versionInfo, with pagination and the includeObsoleteEntities set to true as all former releases terms are marked as obsolete.
Example pattern:
GET /api/v2/ontologies/ictv/classes?http%3A%2F%2Fwww.w3.org%2F2002%2F07%2Fowl%23versionInfo=MSL39&page=0&size=10&includeObsoleteEntities=true
Parameters:
page: Page number (0-indexed)size: Number of items per page (up to 1000)http%3A%2F%2Fwww.w3.org%2F2002%2F07%2Fowl%23versionInfo: version info corresponding to the MSL number in the ICTV ontologyincludeObsoleteEntities: boolean set to true to include obsolete termsAn iteration loop can simply handle paginated results to retrieve all terms
Response structure: JSON array of classes objects with IRIs, labels, synonyms, and metadata.
Note: As the ICTV ontology is a unified ontology of all ICTV releases (made available online on OLS typically 24H after a new ICTV release), as all the previous releases terms are marked as obsolete and as the classes endpoint has false for default value of the includeObsoleteEntities parameter, omitting the versionInfo and the includeObsoleteEntities will automatically return the taxonomic terms of the most recent ICTV release.
example: https://www.ebi.ac.uk/ols4/api/v2/ontologies/ictv/classes?page=0&size=1000
Example response fragment:
{
"page" : 0,
"numElements" : 1000,
"totalPages" : 21,
"totalElements" : 20845,
"elements" : [ {
"appearsIn" : [ "ictv" ],
"curie" : "ICTV19710003",
"directAncestor" : [ "http://ictv.global/id/MSL40/ICTV20080005", "http://ictv.global/id/MSL40/ICTV201857095", "http://ictv.global/id/MSL40/ICTV201907198", "http://ictv.global/id/MSL40/ICTV201907209", "http://ictv.global/id/MSL40/ICTV201907210", "http://purl.obolibrary.org/obo/NCBITaxon_10239" ],
"directParent" : [ "http://ictv.global/id/MSL40/ICTV20080005" ],
"hasDirectChildren" : true,
"hasDirectParents" : true,
"hasHierarchicalChildren" : true,
"hasHierarchicalParents" : true,
"hierarchicalAncestor" : [ "http://ictv.global/id/MSL40/ICTV20080005", "http://ictv.global/id/MSL40/ICTV201857095", "http://ictv.global/id/MSL40/ICTV201907198", "http://ictv.global/id/MSL40/ICTV201907209", "http://ictv.global/id/MSL40/ICTV201907210", "http://purl.obolibrary.org/obo/NCBITaxon_10239" ],
"hierarchicalParent" : [ "http://ictv.global/id/MSL40/ICTV20080005" ],
"hierarchicalProperty" : "http://www.w3.org/2000/01/rdf-schema#subClassOf",
"imported" : false,
"iri" : "http://ictv.global/id/MSL40/ICTV19710003",
"isDefiningOntology" : false,
"isObsolete" : false,
"isPreferredRoot" : false,
"label" : [ "Picornaviridae" ],
"linkedEntities" : {
"http://ictv.global/id/MSL39/ICTV19710003" : {
"numAppearsIn" : 1.0,
"hasLocalDefinition" : true,
"label" : [ "Picornaviridae" ],
"curie" : "ICTV19710003",
"type" : [ "class", "entity" ]
},
...
}
Objective: Find the current accepted ICTV taxon for a viral taxon that may be known by a historical or obsolete taxon name.
https://www.ebi.ac.uk/ols4/api/v2/ontologies/ictv/classes?label=severe%20acute%20respiratory%20syndrome%20coronavirus&includeObsoleteEntities=true
Parameters:
label: The taxon name to search for (URL-encoded)includeObsoleteEntities: Set to true to include obsolete termsResponse: List of matching classes, including obsolete ones.
Note: Except in case where it is already known that the searched term is obsolete, it is a good practice to run a first search with includeObsoleteEntities=false to seek in the most recent ICTV release first.
When an obsolete entity is found, it typically includes a reference using the IAO:0100001 property (term_replaced_by), which links to the current/replacement taxon.
Key metadata fields:
term_replaced_by (IAO:0100001): Points to the current replacement taxon IRIidentifier (from dcterms): correspond to the ICTV ID of the current class taxon, this ID is persistent across ICTV releases except special events like split, merged, or abolished terms.hasExactSynonym (from oboInOwl): Historical names and synonymshas_rank (TAXRANK_1000000): indicate the rank of the current taxoniri: the current term IRI that is, in the ICTV ontology, made of the ontology IRI, the MSL release, and the identifierExample workflow:
1. Search: "Severe acute respiratory syndrome coronavirus"
2. Find obsolete entity with IRI: http://ictv.global/id/MSL22/ICTV20040588
3. Check for "term_replaced_by" relationship β points to:
http://ictv.global/id/MSL40/ICTV20040588
4. Fetch the replacement entity (see Use Case 4 below)
5. Return as the current accepted taxon
Objective: Query the ICTV API using stable ICTV IDs, which remain consistent across releases.
ICTV IDs (e.g., ICTV20040588) are stable identifiers provided by ICTV specifically for use with the ICTV ontology and API.
The API endpoint pattern for resolving by ICTV ID is:
https://ebi.ac.uk/ols4/api/v2/ontologies/{ONTOLOGY}/classes/{DOUBLE_URL_ENCODED_IRI}
1. Construct the IRI:
http://ictv.global/id/MSL40/ICTV20040588
MSL40: ICTV release identifier (Master Species List, version 40)ICTV20040588: The stable ICTV ID for SARS-CoV-22. Double URL-Encode the IRI:
The IRI must be double URL-encoded to embed it safely in the API path:
Original: http://ictv.global/id/MSL40/ICTV20040588
Encoded: http%253A%252F%252Fictv.global%252Fid%252FMSL40%252FICTV20040588
Encoding breakdown:
: β %3A β %253A (double-encoded)/ β %2F β %252F (double-encoded)3. Construct the full API URL:
https://ebi.ac.uk/ols4/api/v2/ontologies/ictv/classes/http%253A%252F%252Fictv.global%252Fid%252FMSL40%252FICTV20040588
4. Fetch the entity:
curl "https://ebi.ac.uk/ols4/api/v2/ontologies/ictv/classes/http%253A%252F%252Fictv.global%252Fid%252FMSL40%252FICTV20040588"
Response: Full JSON object for the species of SARS-CoV-2 including:
For any ICTV IRI, follow this pattern:
1. IRI Format: http://ictv.global/id/{RELEASE}/{ICTV_ID}
2. Step 1 Encoding: http%3A%2F%2Fictv.global%2Fid%2F{RELEASE}%2F{ICTV_ID}
3. Step 2 Encoding: http%253A%252F%252Fictv.global%252Fid%252F{RELEASE}%252F{ICTV_ID}
4. API URL: https://ebi.ac.uk/ols4/api/v2/ontologies/ictv/classes/{STEP_2_ENCODING}
| Endpoint | Purpose |
|---|---|
GET /api/v2/ontologies/ictv/classes |
List all current ICTV classes/taxa |
GET /api/v2/ontologies/ictv/classes?label={LABEL} |
Search classes by taxon name |
GET /api/v2/ontologies/ictv/classes?label={LABEL}&includeObsoleteEntities=true |
Search classes by name including obsolete taxa |
GET /api/v2/ontologies/ictv/classes/{ENCODED_IRI} |
Retrieve a specific class by IRI |
GET /api/v2/ontologies/ictv/entities |
List all entities, including classes and individuals |
GET /api/v2/ontologies/ictv/entities?label={LABEL} |
Search by name across all entity types |
GET /api/v2/ontologies/ictv/entities/{ENCODED_IRI} |
Retrieve a specific entity by IRI |
GET /api/v2/ontologies/ictv/individuals |
List isolates and strains |
GET /api/v2/ontologies/ictv/properties |
List ontology properties |
| Parameter | Values | Purpose |
|---|---|---|
label |
string (URL-encoded) | Search by entity label/name |
includeObsoleteEntities |
true/false | Include obsolete terms in results |
page |
integer | Page number (0-indexed) |
size |
integer (1-1000) | Results per page |
{
"iri": "http://ictv.global/id/MSL38/ICTV20040588",
"label": "Severe acute respiratory syndrome-related coronavirus",
"synonym": [
"SARS-CoV",
{
"type": [
"reification"
],
"value": "Severe acute respiratory syndrome coronavirus",
"axioms": [
{
"http://www.geneontology.org/formats/oboInOwl#hasSynonymType": "http://purl.obolibrary.org/obo/OMO_0003008",
"http://www.w3.org/2002/07/owl#versionInfo": "MSL22",
"oboSynonymTypeName": "previous name"
}
]
}
],
"isObsolete": true,
"hierarchicalParent": [ "http://ictv.global/id/MSL38/ICTV20186129" ],
"hierarchicalAncestor": [ "http://ictv.global/id/MSL38/ICTV19750006", "http://ictv.global/id/MSL38/ICTV19960002", "http://ictv.global/id/MSL38/ICTV20090624", "http://ictv.global/id/MSL38/ICTV20091082", "http://ictv.global/id/MSL38/ICTV201857095", "http://ictv.global/id/MSL38/ICTV20186105", "http://ictv.global/id/MSL38/ICTV20186129", "http://ictv.global/id/MSL38/ICTV201907198", "http://ictv.global/id/MSL38/ICTV201907209", "http://ictv.global/id/MSL38/ICTV201907210", "http://purl.obolibrary.org/obo/NCBITaxon_10239" ],
"http://purl.obolibrary.org/obo/IAO_0100001" : "http://ictv.global/id/MSL40/ICTV20040588",
"http://purl.obolibrary.org/obo/TAXRANK_1000000" : "http://purl.obolibrary.org/obo/TAXRANK_0000006",
"http://purl.org/dc/terms/identifier" : "ICTV20040588"
}
iri: Unique identifier for the taxonlabel: Current accepted namesynonym: Known alternative namesisObsolete: Boolean indicating if the taxon is deprecatedhierarchicalParent: Direct parent taxonhierarchicalAncestor: Taxonomic ancestors (lineage)annotation: Additional metadata including replacement chainshttp://purl.obolibrary.org/obo/IAO_0100001: Link to the replacement term if exists and if the current term is obsoletehttp://purl.obolibrary.org/obo/TAXRANK_1000000: Taxonomic rank information according to the TAXRANK ontologyhttp://purl.org/dc/terms/identifier: The ICTV ID of the current taxonWhen resolving historical taxa, you may encounter the term_replaced_by relationship (IAO:0100001):
Original Request:
GET /api/v2/ontologies/ictv/classes?label=old%20name&includeObsoleteEntities=true
Response includes:
{
"iri": "http://ictv.global/id/OLD_RELEASE/ICTV123456",
"label": ["Old taxon name"],
"isObsolete": true,
"http://purl.obolibrary.org/obo/IAO_0100001": "http://ictv.global/id/MSL40/ICTV789012"
}
}
Follow-up Request:
GET /api/v2/ontologies/ictv/classes/http%253A%252F%252Fictv.global%252Fid%252FMSL40%252FICTV789012
Response:
{
"iri": "http://ictv.global/id/MSL40/ICTV789012",
"label": "Current taxon name",
"isObsolete": false,
...
}
Real example request URL of ICTV ID ICTV20040588 on MSL38 with API V2: https://www.ebi.ac.uk/ols4/api/v2/ontologies/ictv/classes/http%253A%252F%252Fictv.global%252Fid%252FMSL38%252FICTV20040588
The repository includes a comprehensive Jupyter notebook illustrating typical workflows: