Live playground — five evidence lenses, three supply-chain stages, aggregated on every /api/compound/{id} request.
Free tier: 500 requests/day, no API key required for read endpoints. Drop the SDK into your project to skip the JSON parsing.
# Python
pip install aletheia-safety
# Node.js
npm install aletheia-safety
Both SDKs ship typed responses + a webhook-signature verifier. Same aggregated risk-tier payload as the curl examples below.
Pick a compound and context, then run. The URL preview updates live.
GET /api/compound/hq-c-org-000074?context=human_adult
Glyphosate at the dog context. Notice the lower standard deviation and higher consensus strength than the contested human-adult call.
GET /api/compound/hq-c-org-000001?context=dog
from aletheia_safety import Aletheia
client = Aletheia()
result = client.compound("hq-c-org-000001", context="dog")
import { Aletheia } from "aletheia-safety";
const client = new Aletheia();
const result = await client.compound("hq-c-org-000001", { context: "dog" });
Glyphosate carcinogenicity, human-adult context. IARC classifies it Group 2A (probably carcinogenic), EPA’s Office of Pesticide Programs classifies it “not likely to be carcinogenic to humans” (2020), and EFSA finds it “unlikely to pose a carcinogenic hazard to humans” (2015). EPA’s IRIS programme is a separate assessment: Group D, not classifiable (1989). The aggregated record surfaces the disagreement directly — see consensus.exists: false and the wide source_positions spread.
GET /api/compound/hq-c-org-000001?context=human_adult
from aletheia_safety import Aletheia
client = Aletheia()
result = client.compound("hq-c-org-000001", context="human_adult")
# result["consensus"]["exists"] == False
# result["consensus"]["disagreement_magnitude"] ~ 0.42
import { Aletheia } from "aletheia-safety";
const client = new Aletheia();
const result = await client.compound("hq-c-org-000001", { context: "human_adult" });
// result.consensus.exists === false
// result.consensus.disagreement_magnitude ~ 0.42
Same compound, every available context in a single response. Use this when you need to compare risk profiles across populations or exposure routes without firing N separate calls.
GET /api/compound/hq-c-org-000001?all_contexts=true
from aletheia_safety import Aletheia
client = Aletheia()
result = client.compound("hq-c-org-000001", all_contexts=True)
# result["contexts"] = { "human_adult": {...}, "dog": {...}, ... }
import { Aletheia } from "aletheia-safety";
const client = new Aletheia();
const result = await client.compound("hq-c-org-000001", { allContexts: true });
// result.contexts = { human_adult: {...}, dog: {...}, ... }
Discover what contexts the API supports. Each context comes with a description and a list of aliases the API will accept.
GET /api/contexts
from aletheia_safety import Aletheia
client = Aletheia()
contexts = client.contexts()
# contexts = [{"context": "human_adult", "description": "...", "aliases": [...]}, ...]
import { Aletheia } from "aletheia-safety";
const client = new Aletheia();
const contexts = await client.contexts();
// contexts = [{ context: "human_adult", description: "...", aliases: [...] }, ...]
When sources don't converge, the aggregated record preserves the shape of the disagreement instead of manufacturing a midpoint. Glyphosate × human_adult is the canonical example — the three agencies span the magnitude scale almost end-to-end:
Consensus: false (disagreement_magnitude: 0.422)
Mean: 0.360, Std Dev: 0.284
95% CI: [0.082, 0.638]
Run the Disagreement tab above to see this in the live response.
consensus.exists: Boolean. True when std_dev < 0.15 AND max_distance < 0.25
consensus.strength: 0-1 scale. Higher = tighter agreement
disagreement_magnitude: Normalized max distance between any two sources
source_positions: Each source's position with its calculated weight
Read endpoints (compound lookup, cas lookup, contexts) are free with no key. Paid-tier endpoints (compounds list, batch, compare, webhooks) require an X-API-Key header.
curl -H "X-API-Key: $ALETHEIA_API_KEY" \
https://api.aletheia.holisticquality.io/api/compounds?limit=50
from aletheia_safety import Aletheia
client = Aletheia(api_key=os.environ["ALETHEIA_API_KEY"])
compounds = client.compounds(limit=50)
import { Aletheia } from "aletheia-safety";
const client = new Aletheia({ apiKey: process.env.ALETHEIA_API_KEY });
const compounds = await client.compounds({ limit: 50 });
Get a key on the dashboard or via the pricing page. The free tier issues a key on request — useful for higher quotas on the read endpoints, too.
Every error response carries a JSON body with an error code and a message string. HTTP status code matches the error class. No special parsing required.
{
"error": "Unauthorized",
"message": "API key required for /api/compounds",
"hint": "Pass via X-API-Key header"
}
{
"error": "Not found",
"message": "No compound with ID hq-c-org-999999",
"hint": "Try CAS lookup: /api/compound/cas/{cas}"
}
{
"error": "Rate limit exceeded",
"message": "Free tier: 500 requests/day per IP",
"retry_after_seconds": 3600
}
{
"error": "Invalid compound ID",
"message": "ID must match: hq-[c|m|p](-tier)-NNNN(NN)",
"hint": "e.g. hq-c-org-000001"
}
All error responses include a request_id (UUIDv7) that lets you reference the specific call when contacting support — included in the body and in the X-Request-ID response header.
The same JSON you just queried, rendered as a concentric pentagon — magnitude, confidence, recency, methodology, and specificity for three compounds across compound / material / product stages. The Looking Glass is the methodology made visible.
For free use: the read endpoints above are free forever — no key, no account, 500 requests/day per IP. Plug them straight into your app.
For higher volume or write access: Developer or Pro tiers unlock 10k/day or 100k/day, plus batch endpoints, the compounds list, comparisons, and webhooks.
For methodology: the aggregation explained, sources catalogued, and the team behind it.
For comparison: how ALETHEIA differs from PubChem and EPA CompTox for marketplace and consumer-product safety work.