GALENAPI

Causal Inference

Researcher

Simulate interventions, run do-calculus queries, and explore counterfactual scenarios using formal Pearl causal inference over a Structural Causal Model.

Only in Galen

Galen is the only API that offers formal Pearl causal inference over a cancer knowledge graph. The /intervention endpoint uses BFS over a Structural Causal Model. The /do-calculus endpoint computes P(Y|do(X)) using genuine do-calculus — not statistical associations. The /counterfactual endpoint implements twin-network counterfactual inference. No other publicly accessible API provides this capability for cancer biology.

POST/causal/intervention
Researcher

Simulate a Biological Intervention

Propagate an intervention through the causal graph and return downstream effects.

Only in Galen

Uses Breadth-First Search over a Structural Causal Model to compute genuine causal downstream effects — not statistical correlations or LLM reasoning. The model propagates interventions through experimentally-validated causal edges (L2 and L3 relationships) from 10+ databases.

Parameters

Request Body

Specify the target entity, intervention type, and optional propagation parameters.

FieldTypeDescription
targetstringEntity to intervene on (gene, protein, or pathway).
intervention_typestringType of intervention: "inhibit", "activate", "knockout", or "overexpress".
max_hopsintegerMaximum propagation distance in the causal graph (1–6). Higher values capture more distant effects but increase computation time.
min_effectfloatMinimum effect size threshold (0–1). Effects below this magnitude are pruned from results.

Response Schema

targetstringThe intervened entity.
intervention_typestringThe intervention applied.
downstream_effectsarrayEntities causally affected by the intervention.
├──entitystringAffected downstream entity.
├──effect_sizefloatMagnitude of the causal effect (0–1, higher = stronger).
├──directionstringWhether the entity is upregulated ("up") or downregulated ("down").
├──path_lengthintegerNumber of causal edges between the intervention and this entity.
└──mechanismstringBrief mechanistic description of the causal propagation path.
effect_countintegerTotal number of downstream effects returned.
computation_time_msintegerServer-side computation time in milliseconds.

Example Request

import requests

resp = requests.post(
    "https://research.usegalen.com/api/v1/causal/intervention",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "target": "BRAF",
        "intervention_type": "inhibit",
        "max_hops": 3,
        "min_effect": 0.1
    },
)
data = resp.json()
for effect in data["downstream_effects"]:
    print(f"{effect['entity']}: {effect['direction']} ({effect['effect_size']:.2f})")

Example Response

{
  "target": "BRAF",
  "intervention_type": "inhibit",
  "downstream_effects": [
    {
      "entity": "MEK1",
      "effect_size": 0.92,
      "direction": "down",
      "path_length": 1,
      "mechanism": "BRAF directly phosphorylates MEK1; inhibition removes activating phosphorylation."
    },
    {
      "entity": "ERK1/2",
      "effect_size": 0.85,
      "direction": "down",
      "path_length": 2,
      "mechanism": "MEK1 phosphorylates ERK1/2; reduced MEK1 activity decreases ERK signaling."
    },
    {
      "entity": "cell_proliferation",
      "effect_size": 0.71,
      "direction": "down",
      "path_length": 3,
      "mechanism": "ERK1/2 drives transcription of proliferative genes (MYC, CCND1); reduced ERK dampens proliferation."
    },
    {
      "entity": "RSK2",
      "effect_size": 0.62,
      "direction": "down",
      "path_length": 3,
      "mechanism": "ERK1/2 phosphorylates RSK2; downstream reduction in pro-survival signaling."
    },
    {
      "entity": "DUSP6",
      "effect_size": 0.48,
      "direction": "down",
      "path_length": 3,
      "mechanism": "DUSP6 is an ERK-induced phosphatase; lower ERK reduces DUSP6 transcription."
    }
  ],
  "effect_count": 5,
  "computation_time_ms": 847
}

Try It

Request Body

Specify the target entity, intervention type, and optional propagation parameters.

POST https://research.usegalen.com/api/v1/causal/intervention
POST/causal/explain
Researcher

Explain a Causal Relationship

Trace mechanistic causal paths between two biological entities.

Only in Galen

Traces causal mechanism chains through the knowledge graph, showing each intermediate step with its evidence type and causal hierarchy layer. This is mechanistic explanation, not a text summary.

Parameters

Request Body

Source and target entities, plus the maximum number of distinct paths to return.

FieldTypeDescription
sourcestringStarting entity for the causal trace.
targetstringEnding entity you want to explain the connection to.
max_pathsintegerMaximum number of distinct causal paths to return (1–10).

Response Schema

sourcestringThe starting entity.
targetstringThe ending entity.
pathsarrayDistinct causal paths from source to target. Each path is an ordered array of steps.
├──entitystringEntity at this step.
├──relationship_typestringType of causal relationship to the next entity (e.g. phosphorylates, activates, inhibits).
├──directionstringDirection of regulation: "up" or "down".
├──pch_layerintegerPearl Causal Hierarchy layer: 1 (observational), 2 (interventional), 3 (counterfactual).
└──confidencefloatConfidence score for this edge (0–1).
path_countintegerTotal number of causal paths returned.

Example Request

import requests

resp = requests.post(
    "https://research.usegalen.com/api/v1/causal/explain",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "source": "EGFR",
        "target": "cell_proliferation",
        "max_paths": 5
    },
)
data = resp.json()
for i, path in enumerate(data["paths"]):
    chain = " → ".join(step["entity"] for step in path)
    print(f"Path {i+1}: {chain}")

Example Response

{
  "source": "EGFR",
  "target": "cell_proliferation",
  "paths": [
    [
      {
        "entity": "EGFR",
        "relationship_type": "activates",
        "direction": "up",
        "pch_layer": 2,
        "confidence": 0.95
      },
      {
        "entity": "RAS",
        "relationship_type": "activates",
        "direction": "up",
        "pch_layer": 2,
        "confidence": 0.93
      },
      {
        "entity": "RAF",
        "relationship_type": "phosphorylates",
        "direction": "up",
        "pch_layer": 2,
        "confidence": 0.91
      },
      {
        "entity": "MEK",
        "relationship_type": "phosphorylates",
        "direction": "up",
        "pch_layer": 2,
        "confidence": 0.9
      },
      {
        "entity": "ERK",
        "relationship_type": "drives_transcription",
        "direction": "up",
        "pch_layer": 2,
        "confidence": 0.87
      },
      {
        "entity": "cell_proliferation",
        "relationship_type": "endpoint",
        "direction": "up",
        "pch_layer": 2,
        "confidence": 0.87
      }
    ],
    [
      {
        "entity": "EGFR",
        "relationship_type": "activates",
        "direction": "up",
        "pch_layer": 2,
        "confidence": 0.95
      },
      {
        "entity": "PI3K",
        "relationship_type": "activates",
        "direction": "up",
        "pch_layer": 2,
        "confidence": 0.88
      },
      {
        "entity": "AKT",
        "relationship_type": "phosphorylates",
        "direction": "up",
        "pch_layer": 2,
        "confidence": 0.86
      },
      {
        "entity": "mTOR",
        "relationship_type": "activates",
        "direction": "up",
        "pch_layer": 2,
        "confidence": 0.82
      },
      {
        "entity": "cell_proliferation",
        "relationship_type": "endpoint",
        "direction": "up",
        "pch_layer": 2,
        "confidence": 0.82
      }
    ]
  ],
  "path_count": 2
}

Try It

Request Body

Source and target entities, plus the maximum number of distinct paths to return.

POST https://research.usegalen.com/api/v1/causal/explain
POST/causal/do-calculus
Researcher

Run a Do-Calculus Query

Compute P(Y | do(X=x)) using Pearl do-calculus over the SCM.

Only in Galen

Computes P(Y | do(X=x)) using genuine Pearl do-calculus over a Structural Causal Model — the formal mathematical framework for causal inference. This is not correlation, not regression, not LLM reasoning. It answers: 'What would happen to Y if we physically intervened to set X to value x?' No other publicly accessible API offers do-calculus for cancer biology.

Parameters

Request Body

Specify the outcome variable, intervention variables with their forced values, and sampling parameters.

FieldTypeDescription
targetstringOutcome variable Y to estimate the effect on.
interventionsobjectVariables to intervene on with their forced values, e.g. {"BRAF": 0.0} to model complete BRAF inhibition.
n_samplesintegerNumber of Monte Carlo samples for estimation (10–500). Higher values give more precise estimates but take longer.

Response Schema

targetstringThe outcome variable.
interventionsobjectThe interventions applied.
expected_valuefloat | nullE[Y | do(X=x)] — the expected value of Y under the intervention. Null if the SCM cannot estimate.
std_devfloat | nullStandard deviation of the Monte Carlo estimate. Null if not estimable.
samplesintegerNumber of Monte Carlo samples used.
computation_time_msintegerServer-side computation time in milliseconds.

Example Request

import requests

resp = requests.post(
    "https://research.usegalen.com/api/v1/causal/do-calculus",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "target": "tumor_growth",
        "interventions": {"BRAF": 0.0},
        "n_samples": 50
    },
)
data = resp.json()
print(f"E[tumor_growth | do(BRAF=0)] = {data['expected_value']:.4f} ± {data['std_dev']:.4f}")

Example Response

{
  "target": "tumor_growth",
  "interventions": {
    "BRAF": 0
  },
  "expected_value": 0.1842,
  "std_dev": 0.0367,
  "samples": 50,
  "computation_time_ms": 8243
}

Try It

Request Body

Specify the outcome variable, intervention variables with their forced values, and sampling parameters.

POST https://research.usegalen.com/api/v1/causal/do-calculus
POST/causal/counterfactual
Pro

Run a Counterfactual Query

Answer 'what would have happened?' using twin-network counterfactual inference.

Only in Galen

Implements twin-network counterfactual inference — P(Y_x | X', Y'). Answers: 'Given what we observed, what WOULD have happened under a different intervention?' This is Level 3 (the highest level) of Pearl's Causal Hierarchy. Requires a Structural Causal Model with identified structural equations. No other cancer biology API provides counterfactual causal reasoning.

Parameters

Request Body

Factual evidence (what actually happened), the counterfactual intervention (what if this were different), and the target variable to reason about.

FieldTypeDescription
targetstringVariable to reason about counterfactually.
factual_evidenceobjectWhat actually happened — a mapping of variables to their observed values.
interventionobjectThe counterfactual: what if these variables had been set to different values?
n_samplesintegerNumber of Monte Carlo samples (5–200). Counterfactual queries are more expensive than do-calculus.

Response Schema

targetstringThe variable reasoned about.
factual_evidenceobjectThe factual observations provided.
interventionobjectThe counterfactual intervention applied.
counterfactual_valuefloat | nullEstimated value of the target under the counterfactual scenario. Null if not estimable.
effect_sizefloat | nullDifference between the counterfactual and factual outcome.
confidencefloat | nullConfidence in the counterfactual estimate (0–1).
pch_layerintegerAlways 3 — counterfactual is the highest causal evidence level in Pearl's hierarchy.
computation_time_msintegerServer-side computation time in milliseconds.

Example Request

import requests

resp = requests.post(
    "https://research.usegalen.com/api/v1/causal/counterfactual",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "target": "treatment_response",
        "factual_evidence": {
            "EGFR_mutation": 1.0,
            "treatment": 0.0
        },
        "intervention": {"treatment": 1.0},
        "n_samples": 15
    },
)
data = resp.json()
print(f"Counterfactual treatment response: {data['counterfactual_value']:.4f}")
print(f"Effect size: {data['effect_size']:.4f} (PCH Layer {data['pch_layer']})")

Example Response

{
  "target": "treatment_response",
  "factual_evidence": {
    "EGFR_mutation": 1,
    "treatment": 0
  },
  "intervention": {
    "treatment": 1
  },
  "counterfactual_value": 0.7823,
  "effect_size": 0.6491,
  "confidence": 0.74,
  "pch_layer": 3,
  "computation_time_ms": 24510
}

Try It

Request Body

Factual evidence (what actually happened), the counterfactual intervention (what if this were different), and the target variable to reason about.

POST https://research.usegalen.com/api/v1/causal/counterfactual
GET/causal/vulnerabilities/{disease}
Researcher

Find Causal Vulnerabilities

Identify high-impact causal intervention points for a disease or pathway.

Only in Galen

Algorithmically identifies causal vulnerability chains — sequences of entities where intervening at the top of the chain would maximally disrupt the disease. Scored by causal influence propagation through the SCM, not by literature frequency or LLM ranking.

Parameters

Path Parameters
NameTypeReqDescription
diseasestring

Disease to find causal vulnerabilities for.

Example: NSCLC

Query Parameters
NameTypeReqDescription
max_depthinteger

Maximum chain depth to explore. Longer chains may reveal upstream targets.

Default: 4

top_kinteger

Number of top vulnerability chains to return.

Default: 10

Response Schema

diseasestringThe disease or pathway analyzed.
chainsarrayRanked vulnerability chains, from most to least impactful.
├──chainarrayOrdered sequence of entity names in the causal chain.
├──scorefloatVulnerability score — higher means more promising target. Based on causal influence propagation.
└──mechanismstringNarrative summary of why this chain represents a vulnerability.
chain_countintegerTotal number of chains returned.
computation_time_msintegerServer-side computation time in milliseconds.

Example Request

import requests

resp = requests.get(
    "https://research.usegalen.com/api/v1/causal/vulnerabilities/NSCLC",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"max_depth": 4, "top_k": 10},
)
data = resp.json()
for chain in data["chains"]:
    path = " → ".join(chain["chain"])
    print(f"[{chain['score']:.2f}] {path}")
    print(f"  {chain['mechanism']}\n")

Example Response

{
  "disease": "NSCLC",
  "chains": [
    {
      "chain": [
        "EGFR",
        "RAS",
        "RAF",
        "MEK",
        "ERK"
      ],
      "score": 0.94,
      "mechanism": "EGFR is the dominant driver in ~15% of NSCLC. The EGFR→RAS→RAF→MEK→ERK cascade is the primary proliferative pathway. Inhibiting EGFR at the top propagates maximal downstream disruption."
    },
    {
      "chain": [
        "ALK",
        "RAS",
        "RAF",
        "MEK"
      ],
      "score": 0.87,
      "mechanism": "ALK fusions (EML4-ALK) drive ~5% of NSCLC via RAS→RAF→MEK activation. ALK inhibition (crizotinib, alectinib) targets this vulnerability."
    },
    {
      "chain": [
        "KRAS",
        "RAF",
        "MEK",
        "ERK"
      ],
      "score": 0.85,
      "mechanism": "KRAS G12C mutations drive ~13% of NSCLC. Direct KRAS inhibition (sotorasib, adagrasib) disrupts the downstream cascade at the source."
    },
    {
      "chain": [
        "MET",
        "PI3K",
        "AKT",
        "mTOR"
      ],
      "score": 0.72,
      "mechanism": "MET amplification provides a bypass resistance mechanism. MET→PI3K→AKT→mTOR axis drives survival signaling independent of EGFR."
    },
    {
      "chain": [
        "FGFR1",
        "RAS",
        "RAF"
      ],
      "score": 0.61,
      "mechanism": "FGFR1 amplification activates RAS/RAF signaling in squamous NSCLC. Represents an alternative entry point to the MAPK cascade."
    }
  ],
  "chain_count": 5,
  "computation_time_ms": 12340
}

Try It

Path Parameters

stringrequired

Disease to find causal vulnerabilities for.

Query Parameters

integer

Maximum chain depth to explore. Longer chains may reveal upstream targets.

integer

Number of top vulnerability chains to return.

GET https://research.usegalen.com/api/v1/causal/vulnerabilities/{disease}
POST/causal/intervention/dynamic
Pro

Run a Dynamic Causal Simulation

Simulate an intervention over time, capturing feedback loops and adaptive responses.

Only in Galen

Simulates interventions over time, modeling feedback loops and dynamic equilibria. Unlike static causal queries, this captures how biological systems adapt — including treatment resistance mechanisms and compensatory pathway activation. Essential for understanding long-term drug effects.

Parameters

Request Body

Target entity, intervention type, time horizon, and simulation parameters.

FieldTypeDescription
targetstringEntity to intervene on.
intervention_typestringType of intervention: "inhibit", "activate", "knockout", or "overexpress".
time_horizonstringSimulation time scale: "hours", "days", "weeks", "months", or "years".
max_iterationsintegerMaximum simulation iterations (1–100). More iterations increase temporal resolution.

Response Schema

targetstringThe intervened entity.
intervention_typestringThe intervention applied.
time_horizonstringThe simulated time scale.
convergedbooleanWhether the simulation reached a stable equilibrium within the iteration limit.
iterationsintegerNumber of iterations executed.
final_stateobjectVariable values at the end of the simulation.
trajectoryarrayState snapshot at each timestep, showing how variables evolve over the simulation.
feedback_loops_activatedarrayFeedback loops triggered during the simulation, indicating resistance or compensation mechanisms.
computation_time_msintegerServer-side computation time in milliseconds.

Example Request

import requests

resp = requests.post(
    "https://research.usegalen.com/api/v1/causal/intervention/dynamic",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "target": "BRAF",
        "intervention_type": "inhibit",
        "time_horizon": "months",
        "max_iterations": 50
    },
)
data = resp.json()
print(f"Converged: {data['converged']} ({data['iterations']} iterations)")
print(f"Feedback loops activated: {data['feedback_loops_activated']}")
for step in data["trajectory"][:3]:
    print(step)

Example Response

{
  "target": "BRAF",
  "intervention_type": "inhibit",
  "time_horizon": "months",
  "converged": true,
  "iterations": 38,
  "final_state": {
    "BRAF": 0.05,
    "MEK": 0.32,
    "ERK": 0.41,
    "cell_proliferation": 0.55,
    "CRAF": 0.78,
    "RAS_GTP": 0.71
  },
  "trajectory": [
    {
      "step": 0,
      "BRAF": 1,
      "MEK": 1,
      "ERK": 1,
      "cell_proliferation": 1,
      "CRAF": 0.2,
      "RAS_GTP": 0.4
    },
    {
      "step": 5,
      "BRAF": 0.05,
      "MEK": 0.12,
      "ERK": 0.15,
      "cell_proliferation": 0.22,
      "CRAF": 0.25,
      "RAS_GTP": 0.42
    },
    {
      "step": 15,
      "BRAF": 0.05,
      "MEK": 0.18,
      "ERK": 0.24,
      "cell_proliferation": 0.35,
      "CRAF": 0.48,
      "RAS_GTP": 0.58
    },
    {
      "step": 30,
      "BRAF": 0.05,
      "MEK": 0.29,
      "ERK": 0.38,
      "cell_proliferation": 0.51,
      "CRAF": 0.72,
      "RAS_GTP": 0.68
    },
    {
      "step": 38,
      "BRAF": 0.05,
      "MEK": 0.32,
      "ERK": 0.41,
      "cell_proliferation": 0.55,
      "CRAF": 0.78,
      "RAS_GTP": 0.71
    }
  ],
  "feedback_loops_activated": [
    "CRAF paradoxical activation: BRAF inhibition relieves autoinhibition of CRAF, reactivating MEK/ERK signaling",
    "RAS-GTP accumulation: Loss of ERK-mediated negative feedback on SOS1 increases RAS-GTP loading"
  ],
  "computation_time_ms": 4821
}

Try It

Request Body

Target entity, intervention type, time horizon, and simulation parameters.

POST https://research.usegalen.com/api/v1/causal/intervention/dynamic
GET/causal/feedback-loops
Researcher

Detect Feedback Loops

Find positive and negative feedback loops involving an entity or pathway.

Only in Galen

Detects cyclic causal structures in the knowledge graph — feedback loops that can amplify (positive) or dampen (negative) biological signals. Understanding feedback loops is critical for predicting treatment resistance and designing combination strategies.

Parameters

Query Parameters
NameTypeReqDescription
entitystring

Entity or pathway to detect feedback loops for.

Example: MAPK_pathway

Response Schema

loopsarrayDetected feedback loops.
├──nodesarrayOrdered sequence of entities forming the loop (last connects back to first).
├──loop_typestring"positive" (amplifying) or "negative" (dampening) feedback.
└──strengthfloatAggregate strength of the feedback loop (0–1). Higher values indicate stronger regulatory influence.
loop_countintegerTotal number of feedback loops detected.

Example Request

import requests

resp = requests.get(
    "https://research.usegalen.com/api/v1/causal/feedback-loops",
    params={"entity": "MAPK_pathway"},
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = resp.json()
for loop in data["loops"]:
    cycle = " → ".join(loop["nodes"]) + f" → {loop['nodes'][0]}"
    print(f"[{loop['loop_type']}, strength={loop['strength']:.2f}] {cycle}")

Example Response

{
  "loops": [
    {
      "nodes": [
        "RAS",
        "RAF",
        "MEK",
        "ERK",
        "SOS1"
      ],
      "loop_type": "negative",
      "strength": 0.82
    },
    {
      "nodes": [
        "ERK",
        "DUSP6"
      ],
      "loop_type": "negative",
      "strength": 0.75
    },
    {
      "nodes": [
        "ERK",
        "MYC",
        "CCND1",
        "CDK4",
        "RB1",
        "E2F1"
      ],
      "loop_type": "positive",
      "strength": 0.68
    },
    {
      "nodes": [
        "RAF",
        "MEK",
        "ERK",
        "SPRY2"
      ],
      "loop_type": "negative",
      "strength": 0.64
    }
  ],
  "loop_count": 4
}

Try It

Query Parameters

string

Entity or pathway to detect feedback loops for.

GET https://research.usegalen.com/api/v1/causal/feedback-loops