| name | monarch-database |
| description | Monarch Initiative knowledge graph REST API for disease-gene-phenotype associations and cross-species orthology. MONDO disease-to-gene/phenotype, HP phenotype profiles, cross-species comparisons. Use for rare disease gene prioritization and phenotype-based candidate ranking. For GWAS use gwas-database; for clinical pathogenicity use clinvar-database. |
| license | BSD-3-Clause |
monarch-database
Overview
The Monarch Initiative integrates disease-phenotype-gene relationships from 30+ biomedical databases (OMIM, Orphanet, ClinVar, MGI, ZFIN, Reactome) into a unified knowledge graph. The REST API at https://api.monarchinitiative.org/v3/api provides access to associations between genes, diseases, and phenotypes using MONDO disease IDs, Human Phenotype Ontology (HPO) terms, and standard gene identifiers. No authentication is required; the service is free for academic use.
When to Use
- Mapping a disease (MONDO ID) to all associated causal genes and their evidence sources
- Retrieving phenotype profiles (HP terms) for a disease to build phenotypic similarity models
- Ranking candidate genes by phenotypic similarity to a patient's HPO symptom list
- Querying cross-species gene-phenotype associations (mouse, zebrafish, fly) for model organism comparisons
- Exploring rare disease gene-phenotype networks for diagnostic candidate generation
- Resolving entity metadata (gene symbol, disease name, phenotype label) from a MONDO/HP/HGNC ID
- Use
opentargets-database instead when you need drug-target evidence scores or tractability data alongside disease associations
- Use
clinvar-database when you need clinical pathogenicity classifications with submitter review status
Prerequisites
- Python packages:
requests, pandas, matplotlib
- Data requirements: MONDO IDs (e.g.,
MONDO:0007374), HP term IDs (e.g., HP:0001250), or gene symbols/HGNC IDs
- Environment: internet connection; no API key required
- Rate limits: no published rate limit; use
time.sleep(0.3) between batch requests; avoid bursts over 10 requests/second
pip install requests pandas matplotlib
Quick Start
import requests
MONARCH_API = "https://api.monarchinitiative.org/v3/api"
def monarch_get(endpoint: str, params: dict = None) -> dict:
"""GET request to Monarch API; raises on HTTP errors."""
r = requests.get(f"{MONARCH_API}{endpoint}", params=params, timeout=30)
r.raise_for_status()
return r.json()
result = monarch_get("/association/all", params={
"subject": "MONDO:0007374",
"category": "biolink:GeneToDiseaseAssociation",
"limit": 10
})
print(f"Total gene associations: {result['total']}")
for item in result["items"][:5]:
obj = item.get("object", {})
print(f" Gene: {obj.get('label', 'N/A')} ({obj.get('id', 'N/A')})")
Core API
Query 1: Disease-Gene Associations
Retrieve all genes associated with a disease by MONDO ID. Returns causal gene records with evidence metadata.
import requests
import pandas as pd
import time
MONARCH_API = "https://api.monarchinitiative.org/v3/api"
def monarch_get(endpoint, params=None):
r = requests.get(f"{MONARCH_API}{endpoint}", params=params, timeout=30)
r.raise_for_status()
return r.json()
def get_disease_genes(mondo_id: str, limit: int = 200) -> pd.DataFrame:
"""Return DataFrame of genes associated with a disease."""
result = monarch_get("/association/all", params={
"subject": mondo_id,
"category": "biolink:CausalGeneToDiseaseAssociation",
"limit": limit
})
rows = []
for item in result.get("items", []):
obj = item.get("object", {})
rows.append({
"gene_id": obj.get("id"),
"gene_symbol": obj.get("label"),
"taxon": obj.get("taxon", {}).get("label") if obj.get("taxon") else None,
"relation": item.get("predicate"),
"evidence_count": len(item.get("evidence", [])),
})
pd.DataFrame(rows)
df = get_disease_genes()
()
(df[[, , ]].to_string(index=))
Query 2: Disease-Phenotype Associations
Retrieve HPO phenotype terms linked to a disease. Useful for building phenotype profiles and similarity scoring.
def get_disease_phenotypes(mondo_id: str, limit: int = 200) -> pd.DataFrame:
"""Return DataFrame of phenotypes (HP terms) for a disease."""
result = monarch_get("/association/all", params={
"subject": mondo_id,
"category": "biolink:DiseaseToPhenotypicFeatureAssociation",
"limit": limit
})
rows = []
for item in result.get("items", []):
obj = item.get("object", {})
rows.append({
"hp_id": obj.get("id"),
"phenotype": obj.get("label"),
"frequency": item.get("frequency", {}).get("label") if item.get("frequency") else None,
"onset": item.get("onset", {}).get("label") if item.get("onset") else None,
})
return pd.DataFrame(rows)
df = get_disease_phenotypes("MONDO:0007374", limit=50)
print(f"Phenotypes for Marfan syndrome: {len(df)}")
print(df[["phenotype", "hp_id", "frequency"]].head(8).to_string(index=))
Query 3: Entity Lookup
Retrieve metadata for any Monarch entity (gene, disease, phenotype) by its identifier.
def get_entity(entity_id: str) -> dict:
"""Retrieve metadata for a gene, disease, or phenotype by its ID."""
result = monarch_get(f"/entity/{entity_id}")
return result
hp = get_entity("HP:0001250")
print(f"Name: {hp.get('name')}")
print(f"ID: {hp.get('id')}")
print(f"Description: {hp.get('description', '')[:120]}")
print(f"Synonyms: {[s.get('val') for s in hp.get('synonyms', [])[:3]]}")
disease = get_entity("MONDO:0007374")
print(f"\nDisease: {disease.get('name')}")
print(f"ID: {disease.get('id')}")
Query 4: Text Search for Entities
Search for entities by free-text label, useful for resolving disease names or phenotype terms to IDs.
def search_entities(query: str, category: str = None, limit: int = 10) -> list:
"""Search Monarch entities by label/synonym."""
params = {"q": query, "limit": limit}
if category:
params["category"] = category
result = monarch_get("/search", params=params)
return result.get("items", [])
hits = search_entities("Ehlers-Danlos", category="biolink:Disease", limit=8)
for hit in hits:
print(f" {hit.get('id'):<25} {hit.get('name', 'N/A')}")
Query 5: Gene-to-Disease Associations
Retrieve diseases associated with a gene. Useful for understanding a gene's disease spectrum.
def get_gene_diseases(gene_id: str, limit: int = 100) -> pd.DataFrame:
"""Return DataFrame of diseases associated with a gene."""
result = monarch_get("/association/all", params={
"subject": gene_id,
"category": "biolink:GeneToDiseaseAssociation",
"limit": limit
})
rows = []
for item in result.get("items", []):
obj = item.get("object", {})
rows.append({
"disease_id": obj.get("id"),
"disease_name": obj.get("label"),
"predicate": item.get("predicate"),
})
return pd.DataFrame(rows)
df = get_gene_diseases("HGNC:3603")
print(f"Diseases linked to FBN1: {len(df)}")
print(df[["disease_name", "disease_id"]].head(5).to_string(index=False))
Query 6: Gene-Phenotype Associations (Cross-Species)
Query phenotypes linked to a gene across species including mouse, zebrafish, and human.
def get_gene_phenotypes(gene_id: str, limit: int = 100) -> pd.DataFrame:
"""Return gene-phenotype associations, optionally across species."""
result = monarch_get("/association/all", params={
"subject": gene_id,
"category": "biolink:GeneToPhenotypicFeatureAssociation",
"limit": limit
})
rows = []
for item in result.get("items", []):
subj = item.get("subject", {})
obj = item.get("object", {})
rows.append({
"gene_id": subj.get("id"),
"gene_symbol": subj.get("label"),
"taxon": subj.get("taxon", {}).get("label") if subj.get("taxon") else None,
"phenotype_id": obj.get("id"),
"phenotype": obj.get("label"),
})
return pd.DataFrame(rows)
df = get_gene_phenotypes("HGNC:3603")
print(f"FBN1 phenotype associations: {len(df)}")
print(df[["taxon", "phenotype"]].value_counts("taxon"))
Query 7: Histopheno — Phenotype Distribution for a Disease
Retrieve summarized phenotype counts by anatomical system for a disease, useful for phenotype spectrum overviews.
def get_histopheno(mondo_id: str) -> dict:
"""Retrieve summarized phenotype distribution for a disease."""
result = monarch_get(f"/histopheno/{mondo_id}")
return result
hist = get_histopheno("MONDO:0007374")
items = hist.get("items", [])
print(f"Phenotype categories for Marfan syndrome ({len(items)} systems):")
for item in sorted(items, key=lambda x: x.get("count", 0), reverse=True)[:8]:
print(f" {item.get('label', 'N/A'):<40} n={item.get('count', 0)}")
Query 8: Phenotype-to-Gene Associations
Given a set of HP phenotype terms, retrieve associated genes — the basis of phenotype-matching tools.
def get_phenotype_genes(hp_id: str, limit: int = 50) -> pd.DataFrame:
"""Return genes associated with a phenotype term."""
result = monarch_get("/association/all", params={
"object": hp_id,
"category": "biolink:GeneToPhenotypicFeatureAssociation",
"limit": limit
})
rows = []
for item in result.get("items", []):
subj = item.get("subject", {})
rows.append({
"gene_id": subj.get("id"),
"gene_symbol": subj.get("label"),
"taxon": subj.get("taxon", {}).get("label") if subj.get("taxon") else None,
})
return pd.DataFrame(rows)
df = get_phenotype_genes("HP:0001631")
print(f"Genes associated with Atrial septal defect: {len(df)}")
print(df[df["taxon"] == "Homo sapiens"]["gene_symbol"].head(8).tolist())
Key Concepts
Monarch Identifier System
Monarch uses ontology-based compact URIs (CURIEs) as identifiers:
| Prefix | Namespace | Example |
|---|
MONDO | Mondo Disease Ontology | MONDO:0007374 (Marfan syndrome) |
HP | Human Phenotype Ontology | HP:0001250 (Seizure) |
HGNC | HGNC human genes | HGNC:3603 (FBN1) |
NCBIGene | NCBI Gene IDs | NCBIGene:2200 (FBN1) |
MGI | Mouse Genome Informatics | MGI:95489 (Fbn1 mouse) |
ZFIN | Zebrafish Information Network | ZFIN:ZDB-GENE-... |
Use the /search endpoint to convert free-text names to IDs before querying associations.
Association Categories
Monarch uses biolink model categories for associations:
| Category | Meaning |
|---|
biolink:CausalGeneToDiseaseAssociation | Gene causes the disease |
biolink:DiseaseToPhenotypicFeatureAssociation | Disease → phenotype (HPO terms) |
biolink:GeneToPhenotypicFeatureAssociation | Gene → phenotype (any species) |
biolink:GeneToDiseaseAssociation | Any gene-disease link (broader) |
Use CausalGeneToDiseaseAssociation for pathogenic gene lists; use GeneToDiseaseAssociation for broader evidence including susceptibility loci.
Common Workflows
Workflow 1: Rare Disease Gene Prioritization
Goal: Given a set of HPO terms from a patient, retrieve all diseases with overlapping phenotypes and their causal genes.
import requests
import pandas as pd
import time
MONARCH_API = "https://api.monarchinitiative.org/v3/api"
def monarch_get(endpoint, params=None):
r = requests.get(f"{MONARCH_API}{endpoint}", params=params, timeout=30)
r.raise_for_status()
return r.json()
patient_hp_terms = ["HP:0001250", "HP:0000252", "HP:0001263"]
gene_scores = {}
for hp_id in patient_hp_terms:
result = monarch_get("/association/all", params={
"object": hp_id,
"category": "biolink:DiseaseToPhenotypicFeatureAssociation",
"limit": 50
})
diseases = [item.get("subject", {}).get("id") for item in result.get("items", [])]
for disease_id in diseases[:5]:
gene_result = monarch_get("/association/all", params={
"subject": disease_id,
"category": "biolink:CausalGeneToDiseaseAssociation",
"limit": 20
})
for item in gene_result.get(, []):
gene_sym = item.get(, {}).get(, )
gene_sym:
gene_scores[gene_sym] = gene_scores.get(gene_sym, ) +
time.sleep()
df = pd.DataFrame(
[(gene, score) gene, score gene_scores.items()],
columns=[, ]
).sort_values(, ascending=)
()
(df.head().to_string(index=))
df.to_csv(, index=)
Workflow 2: Disease Phenotype Profile and Visualization
Goal: Retrieve all HPO terms for a disease, summarize by anatomical category, and plot a bar chart.
import requests
import pandas as pd
import matplotlib.pyplot as plt
import time
MONARCH_API = "https://api.monarchinitiative.org/v3/api"
def monarch_get(endpoint, params=None):
r = requests.get(f"{MONARCH_API}{endpoint}", params=params, timeout=30)
r.raise_for_status()
return r.json()
mondo_id = "MONDO:0009861"
disease_info = monarch_get(f"/entity/{mondo_id}")
disease_name = disease_info.get("name", mondo_id)
result = monarch_get("/association/all", params={
"subject": mondo_id,
"category": "biolink:DiseaseToPhenotypicFeatureAssociation",
"limit": 200
})
items = result.get("items", [])
print(f"Phenotypes for {disease_name}: {len(items)}")
rows = []
for item in items:
obj = item.get("object", {})
rows.append({
"hp_id": obj.get("id"),
"phenotype": obj.get("label"),
"frequency": item.get("frequency", {}).get("label") if item.get()
})
df = pd.DataFrame(rows)
hist = monarch_get()
hist_items = (hist.get(, []), key= x: x.get(, ), reverse=)[:]
systems = [x.get(, )[:] x hist_items]
counts = [x.get(, ) x hist_items]
fig, ax = plt.subplots(figsize=(, ))
bars = ax.barh(systems[::-], counts[::-], color=)
ax.bar_label(bars, fmt=, padding=)
ax.set_xlabel()
ax.set_title()
plt.tight_layout()
plt.savefig(, dpi=, bbox_inches=)
()
df.to_csv(, index=)
(df[[, , ]].head().to_string(index=))
Workflow 3: Cross-Species Gene-Disease Network
Goal: Build a table of disease-gene associations including mouse model genes for a list of rare diseases.
import requests
import pandas as pd
import time
MONARCH_API = "https://api.monarchinitiative.org/v3/api"
def monarch_get(endpoint, params=None):
r = requests.get(f"{MONARCH_API}{endpoint}", params=params, timeout=30)
r.raise_for_status()
return r.json()
diseases = {
"MONDO:0007374": "Marfan syndrome",
"MONDO:0009861": "Cystic fibrosis",
"MONDO:0007522": "Classical EDS",
}
all_rows = []
for mondo_id, disease_name in diseases.items():
result = monarch_get("/association/all", params={
"subject": mondo_id,
"category": "biolink:CausalGeneToDiseaseAssociation",
"limit": 50
})
for item in result.get("items", []):
obj = item.get("object", {})
all_rows.append({
"disease_id": mondo_id,
"disease_name": disease_name,
"gene_id": obj.get("id"),
"gene_symbol": obj.get("label"),
"species": "Homo sapiens",
})
time.sleep(0.3)
df = pd.DataFrame(all_rows)
df.to_csv("rare_disease_gene_network.csv", index=False)
()
(df.groupby()[].apply().to_string())
Key Parameters
| Parameter | Function/Endpoint | Default | Range / Options | Effect |
|---|
category | /association/all | (none) | biolink:CausalGeneToDiseaseAssociation, biolink:DiseaseToPhenotypicFeatureAssociation, biolink:GeneToPhenotypicFeatureAssociation, biolink:GeneToDiseaseAssociation | Filters association type |
subject | /association/all | (none) | CURIE string (e.g., MONDO:0007374) | Source entity (disease or gene) |
object | /association/all | (none) | CURIE string (e.g., HP:0001250) | Target entity (phenotype or disease) |
limit | /association/all, /search | 20 | 1–500 | Max items returned per page |
offset | /association/all | 0 | integer | Pagination offset |
q | /search | (none) | free-text string | Label/synonym text search |
entity_id | /entity/{id} | (none) | CURIE string | Entity ID for metadata lookup |
mondo_id | /histopheno/{id} | (none) | MONDO CURIE | Disease ID for phenotype histogram |
Best Practices
-
Resolve names to IDs first using /search: All association queries require CURIE IDs (e.g., MONDO:0007374), not free-text. Use search_entities() to resolve "Marfan syndrome" → MONDO:0007374 before querying associations.
-
Use CausalGeneToDiseaseAssociation for gene lists, not GeneToDiseaseAssociation: The broader category includes susceptibility associations and ambiguous links. Causal associations have stronger evidence support.
-
Paginate large result sets with offset: The default limit is 20 and max is 500. Check result["total"] and paginate with offset increments to retrieve all records for diseases with many phenotypes:
total = monarch_get("/association/all", params={"subject": mondo_id, "category": "...", "limit": 1})["total"]
all_items = []
for offset in range(0, total, 200):
batch = monarch_get("/association/all", params={"subject": mondo_id, "category": "...", "limit": 200, "offset": offset})
all_items.extend(batch.get("items", []))
time.sleep(0.3)
-
Use time.sleep(0.3) between requests in batch loops: The API is publicly accessible without rate limit documentation; polite access avoids throttling for multi-disease workflows.
-
Cross-reference gene IDs with HGNC for human genes: Monarch may return HGNC:XXXX or NCBIGene:XXXX IDs. Use the HGNC prefix for downstream tools that require HGNC; use the /entity/{id} endpoint to retrieve the alternative ID.
Common Recipes
Recipe: Resolve Disease Name to MONDO ID
When to use: Convert a disease name string to the canonical MONDO identifier before querying.
import requests
MONARCH_API = "https://api.monarchinitiative.org/v3/api"
def resolve_disease(name: str, top_n: int = 5) -> list:
"""Search for disease name and return top MONDO ID candidates."""
r = requests.get(f"{MONARCH_API}/search",
params={"q": name, "category": "biolink:Disease", "limit": top_n},
timeout=15)
r.raise_for_status()
return [(h.get("id"), h.get("name")) for h in r.json().get("items", [])]
candidates = resolve_disease("Huntington disease")
for mondo_id, label in candidates:
print(f" {mondo_id:<25} {label}")
Recipe: Batch Disease-Gene Lookup
When to use: Retrieve causal genes for a list of MONDO IDs in one call each, with results combined into a single DataFrame.
import requests
import pandas as pd
import time
MONARCH_API = "https://api.monarchinitiative.org/v3/api"
def get_causal_genes(mondo_id):
r = requests.get(f"{MONARCH_API}/association/all",
params={"subject": mondo_id,
"category": "biolink:CausalGeneToDiseaseAssociation",
"limit": 100},
timeout=30)
r.raise_for_status()
data = r.json()
return [(item.get("object", {}).get("id"), item.get("object", {}).get("label"))
for item in data.get("items", [])]
disease_ids = ["MONDO:0007374", "MONDO:0009861", "MONDO:0007739"]
rows = []
for mondo_id in disease_ids:
for gene_id, gene_sym in get_causal_genes(mondo_id):
rows.append({"disease_id": mondo_id, "gene_id": gene_id, "gene_symbol": gene_sym})
time.sleep(0.3)
df = pd.DataFrame(rows)
print(df.to_string(index=False))
df.to_csv("batch_disease_genes.csv", index=False)
print(f"\nTotal disease-gene pairs: {len(df)}")
Recipe: HPO Profile Similarity Seed
When to use: Retrieve disease HPO profiles to use as input seeds for phenotype similarity tools (e.g., Phenomizer, LIRICAL).
import requests, json
MONARCH_API = "https://api.monarchinitiative.org/v3/api"
def get_hp_profile(mondo_id, limit=500):
"""Return list of HP term IDs for a disease."""
r = requests.get(f"{MONARCH_API}/association/all",
params={"subject": mondo_id,
"category": "biolink:DiseaseToPhenotypicFeatureAssociation",
"limit": limit},
timeout=30)
r.raise_for_status()
items = r.json().get("items", [])
return [item.get("object", {}).get("id") for item in items if item.get("object", {}).get("id")]
hp_terms = get_hp_profile("MONDO:0007374")
print(f"HP terms for Marfan syndrome: {len(hp_terms)}")
print(hp_terms[:8])
with open("MONDO_0007374_hp_profile.json", "w") as f:
json.dump({"disease": "MONDO:0007374", "hpo_terms": hp_terms}, f, indent=2)
print("Saved MONDO_0007374_hp_profile.json")
Troubleshooting
| Problem | Cause | Solution |
|---|
Empty items list | Wrong category string or entity has no associations of that type | Check the category name exactly; try biolink:GeneToDiseaseAssociation as a broader fallback |
404 Not Found for /entity/{id} | Malformed CURIE or deprecated ID | Verify ID format (e.g., MONDO:0007374 not MONDO_0007374); use /search to find current IDs |
total is 0 but entity exists | Subject/object direction reversed | Check whether you need subject or object parameter; gene→disease uses subject=gene_id; disease→phenotype uses subject=disease_id |
requests.exceptions.Timeout | API overloaded or network issue | Increase timeout=60; retry with exponential backoff |
Gene ID returned as NCBIGene instead of HGNC | Monarch may use either namespace | Use /entity/{id} to retrieve xrefs field for alternative IDs including HGNC, Ensembl |
| Results differ between API calls for same entity | Monarch knowledge graph is updated regularly | Pin your data collection date; note API version in methods section |
| Rate-limited or slow responses | Too many rapid requests | Add time.sleep(0.5) between batch requests; use limit=200 to reduce total requests |
Related Skills
clinvar-database — clinical pathogenicity classifications for specific variants (complements Monarch's gene-disease associations)
gwas-database — GWAS Catalog associations for common variants and traits
opentargets-database — drug-target evidence with tractability and safety scores
ensembl-database — gene/transcript annotation and cross-species orthology via Ensembl REST API
gseapy-gene-enrichment — gene set enrichment analysis using the Monarch-derived gene lists
References