API Usage Guide
Learn how to programmatically access ISBT blood group data
What is an API?
An Application Programming Interface (API) is a set of rules and protocols that allows different software applications to communicate with each other. Think of it as a waiter in a restaurant who takes your order, delivers it to the kitchen, and brings your food back to you.
The ISBT Blood Group Database API allows researchers, developers, and healthcare systems to programmatically access blood group data without manually browsing the website. This enables automation, integration with laboratory systems, and large-scale data analysis.
π‘ Key Insight: In fact, this website itself uses the ISBT API to fetch what it needs for the data pages!
RESTful API Architecture
The ISBT API follows REST (Representational State Transfer) principles, which means:
- Resource-based URLs: Each URL represents a specific resource (systems, antigens, alleles)
- HTTP methods: GET (retrieve), POST (create), PATCH (update), DELETE (remove)
- Stateless: Each request contains all information needed to process it
- JSON format: Data is returned in JavaScript Object Notation format
Learn more about RESTful APIs at: https://restfulapi.net/
The API base URL for the ISBT Blood Group Database is: https://api-blooddatabase.isbtweb.org
Try the API in Your Browser
The API is really designed to be used computationally using programming languages like Python, JavaScript, or R - but even your web browser can make GET requests to fetch data from the API (its how the internet works!).
Before diving into code, you can explore the API directly using your web browser. This is great for understanding the data structure and testing endpoints:
π©Έ Get All Blood Group Systems
View all ISBT blood group systems with their basic information:
https://api-blooddatabase.isbtweb.org/system㪠Search Kell System Antigens
Browse all antigens in the Kell blood group system:
https://api-blooddatabase.isbtweb.org/antigen/search?system_symbol=KEL𧬠Search ABO System Alleles
Explore genetic variants in the ABO blood group system:
https://api-blooddatabase.isbtweb.org/allele/search?system_symbol=ABOπ Interactive API Documentation
Explore all endpoints with interactive documentation:
https://api-blooddatabase.isbtweb.org/apiπ‘ Pro Tip: Most browsers will automatically format JSON responses for easier reading. Try the links above to see the raw data structure and some examples before writing code!
Python Examples
Here are some practical Python examples using the popular requests
and pandas
libraries.
Copy and paste the code snippets into your Python environment (e.g. Jupyter Notebook, VSCode, PyCharm) to run them. Each example includes comments explaining what the code does.
You will have to install Python and these libraries first if you havenβt already - see the external Python installation guide, requests installation guide, and the pandas installation guide.
1. Get All Blood Group Systems
import requests
import json
# Base URL for the API
BASE_URL = "https://api-blooddatabase.isbtweb.org"
def get_all_systems():
"""Fetch all blood group systems from the ISBT API."""
try:
response = requests.get(f"{BASE_URL}/system")
response.raise_for_status() # Raises an HTTPError for bad responses
systems = response.json()
print(f"β
Found {len(systems)} blood group systems")
# Display first few systems
for system in systems[:3]:
isbt_num = system['isbt_number']
name = system['name']
symbol = system['symbol']
print(f"System {isbt_num:03d}: {name} ({symbol})")
return systems
except requests.exceptions.RequestException as e:
print(f"β Error fetching systems: {e}")
return None
# Execute the function
systems_data = get_all_systems()
# Print full data as JSON (optional)
print(json.dumps(systems_data, indent=2))
2. Search Antigens by System
import requests
from typing import List, Dict, Optional
BASE_URL = "https://api-blooddatabase.isbtweb.org"
def search_antigens_by_system(system_symbol: str) -> Optional[List[Dict]]:
"""
Search for all antigens in a specific blood group system.
Args:
system_symbol (str): System symbol (e.g., 'KEL', 'ABO', 'RH', 'FY')
Returns:
List of antigen dictionaries or None if error
"""
try:
search_params = {"system_symbol": system_symbol}
response = requests.get(
f"{BASE_URL}/antigen/search",
params=search_params,
timeout=30
)
response.raise_for_status()
antigens = response.json()
if not antigens:
print(f"β οΈ No antigens found for system '{system_symbol}'")
return []
print(f"π©Έ Found {len(antigens)} antigens in {system_symbol} system")
print("=" * 50)
# Sort by ISBT number for systematic display
sorted_antigens = sorted(antigens, key=lambda x: x.get('isbt_number', 0))
for antigen in sorted_antigens:
name = antigen['name']
isbt_code = antigen['isbt_code']
isbt_number = antigen['isbt_number']
approved = antigen.get('approved', False)
status = "β
Approved" if approved else "β³ Pending"
print(f"π¬ {isbt_code}: {name}")
print(f" ISBT Number: {isbt_number}")
print(f" Status: {status}")
print(" " + "-" * 40)
return antigens
except requests.exceptions.RequestException as e:
print(f"β Error searching {system_symbol} antigens: {e}")
return None
except Exception as e:
print(f"β Unexpected error: {e}")
return None
# Example usage: Get antigens from different systems
print("=== Kell System Antigens ===")
kell_antigens = search_antigens_by_system("KEL")
print("\n=== Duffy System Antigens ===")
duffy_antigens = search_antigens_by_system("FY")
print("\n=== ABO System Antigens ===")
abo_antigens = search_antigens_by_system("ABO")
3. Get Alleles for a Specific System
import requests
import pandas as pd
from typing import List, Dict, Optional
BASE_URL = "https://api-blooddatabase.isbtweb.org"
def get_system_alleles(system_symbol: str) -> Optional[pd.DataFrame]:
"""
Fetch alleles for a specific blood group system using search endpoint.
Args:
system_symbol (str): System symbol (e.g., 'KEL', 'ABO', 'RH', 'FY')
Returns:
pandas.DataFrame with allele data or None if error
"""
try:
# Use the allele search endpoint with system_symbol parameter
search_params = {"system_symbol": system_symbol}
response = requests.get(
f"{BASE_URL}/allele/search",
params=search_params,
timeout=30
)
response.raise_for_status()
alleles = response.json()
if not alleles:
print(f"β οΈ No alleles found for system '{system_symbol}'")
return None
print(f"𧬠Found {len(alleles)} {system_symbol} alleles")
print("=" * 50)
# Convert JSON response directly to DataFrame - much cleaner!
df = pd.read_json(response.text)
# Select only the columns we're interested in
desired_columns = [
'id', 'isbt_allele', 'isbt_phenotype', 'reference_allele',
'sv_allele', 'null_allele', 'mod_allele', 'partial_allele',
'weak_allele', 'el_allele', 'allele_order', 'alternate_names',
'approved'
]
# Keep only columns that exist in the response
available_columns = [col for col in desired_columns if col in df.columns]
df = df[available_columns]
# Display summary statistics
print(f"π {system_symbol} Allele Summary:")
print(f" Total alleles: {len(df)}")
# Show allele type distribution
allele_types = []
type_columns = ['reference_allele', 'sv_allele', 'null_allele', 'mod_allele',
'partial_allele', 'weak_allele', 'el_allele']
for col in type_columns:
if col in df.columns:
count = df[col].sum()
if count > 0:
type_name = col.replace('_allele', '').replace('_', ' ').title()
allele_types.append(f"{type_name}: {count}")
if allele_types:
print(" Allele types:")
for allele_type in allele_types:
print(f" {allele_type}")
# Show sample data with key columns
print(f"\nπ First 5 alleles (key properties):")
display_cols = ['isbt_allele', 'isbt_phenotype', 'reference_allele',
'null_allele', 'weak_allele', 'approved']
available_cols = [col for col in display_cols if col in df.columns]
print(df[available_cols].head().to_string(index=False))
# Show approval statistics
if 'approved' in df.columns:
approved_count = df['approved'].sum()
total_count = len(df)
print(f"\nβ
Approved: {approved_count}/{total_count} alleles")
# Show reference allele info
if 'reference_allele' in df.columns:
ref_count = df['reference_allele'].sum()
print(f"π¬ Reference alleles: {ref_count}")
return df
except requests.exceptions.RequestException as e:
print(f"β Error fetching {system_symbol} alleles: {e}")
return None
except Exception as e:
print(f"β Unexpected error: {e}")
return None
# Example usage: Get alleles from different systems
print("=== Kell System Alleles ===")
kell_df = get_system_alleles("KEL")
print("\n=== ABO System Alleles ===")
abo_df = get_system_alleles("ABO")
4. Load Systems Data into Pandas DataFrame
import requests
import pandas as pd
from pathlib import Path
from typing import List, Dict, Optional
BASE_URL = "https://api-blooddatabase.isbtweb.org"
def load_systems_to_dataframe(save_csv: bool = True) -> Optional[pd.DataFrame]:
"""
Load all ISBT blood group systems into a pandas DataFrame.
Args:
save_csv (bool): Whether to save data to CSV file
Returns:
pandas.DataFrame with systems data or None if error
"""
try:
# Fetch systems data
response = requests.get(f"{BASE_URL}/system", timeout=30)
response.raise_for_status()
systems_data = response.json()
# Convert to pandas DataFrame
systems_df = pd.DataFrame(systems_data)
# Data validation
if systems_df.empty:
print("β οΈ No systems data received")
return None
# Display basic information
print(f"π Loaded {len(systems_df)} blood group systems")
print(f"π§ Columns: {list(systems_df.columns)}")
# Show sample data
key_columns = ['isbt_number', 'name', 'symbol', 'category']
available_columns = [col for col in key_columns if col in systems_df.columns]
print(f"\nπ First 5 systems:")
print(systems_df[available_columns].head().to_string(index=False))
# Category analysis
if 'category' in systems_df.columns:
print(f"\nπ Systems by category:")
category_counts = systems_df['category'].value_counts()
for category, count in category_counts.items():
print(f" {category}: {count}")
# Approval status analysis
if 'approved' in systems_df.columns:
approved_count = systems_df['approved'].sum()
total_count = len(systems_df)
print(f"\nβ
Approved systems: {approved_count}/{total_count}")
# Sort by ISBT number for systematic view
if 'isbt_number' in systems_df.columns:
sorted_systems = systems_df.sort_values('isbt_number')
print(f"\nπ’ Systems by ISBT number (first 10):")
display_cols = ['isbt_number', 'name', 'symbol']
available_display = [col for col in display_cols if col in sorted_systems.columns]
print(sorted_systems[available_display].head(10).to_string(index=False))
# Save to CSV if requested
if save_csv:
output_file = Path('isbt_systems.csv')
systems_df.to_csv(output_file, index=False)
print(f"\nπΎ Data saved to '{output_file}'")
return systems_df
except requests.exceptions.RequestException as e:
print(f"β Error fetching systems: {e}")
return None
except Exception as e:
print(f"β Unexpected error: {e}")
return None
# Execute the function
systems_df = load_systems_to_dataframe(save_csv=True)
Best Practices
- Rate Limiting: Be respectful with API calls. Donβt make too many requests in quick succession
- Error Handling: Always check HTTP status codes and handle errors gracefully
- Data Validation: Validate the structure and content of API responses before processing
- Caching: Cache frequently accessed data to reduce API calls and improve performance
- Version Control: Use release information to track which version of data youβre working with
- Documentation: Keep your API usage documented for reproducibility
Authentication and Access
The ISBT API provides public read access to most blood group data. For write operations (creating, updating, or suggesting changes), authentication is required. To request API access:
- Visit the access request page
- Provide details about your intended use
- Wait for approval from the ISBT working party
- Use provided credentials for authenticated requests
Additional Resources
- Interactive API Documentation - Try endpoints directly in your browser
- Database Browser - Explore data through the web interface
- Database Usage Tutorial - Learn to navigate the web interface
- Contact Us - Get help with API integration
Note: The API structure and endpoints may evolve as the database grows. Always refer to the latest API documentationfor the most current information and consider versioning in your applications.