Structures adverse-event mentions that OpenMed extracts into FAERS / ICH E2B(R3) reportable fields — suspect drug, reaction (MedDRA PT), seriousness criteria, and outcome. Use when the user needs to build an individual case safety report (ICSR), populate a FAERS submission, map a narrative to E2B(R3) data elements, classify seriousness (death, life-threatening, hospitalization, disability, congenital anomaly), or assign reaction outcomes. Trigger keywords: adverse event, ADR, ICSR, FAERS, E2B, E2B(R3), suspect drug, seriousness, MedDRA, reaction outcome, pharmacovigilance case. Pairs after OpenMed NER: consume Pharmaceutical/Chemical and Disease entities from openmed.analyze_text. MedDRA is licensed and user-supplied — never bundled. De-identify the narrative with openmed.deidentify before any external submission.
74
91%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
A pharmacovigilance case starts as free-text narrative ("68 yo on warfarin developed GI bleed, hospitalized"). To make it reportable you must structure it into the ICH E2B(R3) data elements that the FDA's FAERS (and EMA's EudraVigilance) expect: a suspect drug, one or more reactions coded to MedDRA Preferred Terms, seriousness criteria, and a reaction outcome.
OpenMed extracts the drug and condition spans on-device; this skill turns those spans plus the narrative into the E2B(R3) skeleton. The reaction coding step needs MedDRA, which is licensed by the MSSO and user-supplied — it is never bundled with OpenMed and must be loaded from the user's own subscription.
drugcharacterization axis FAERS uses).This skill produces a structured draft for human safety review — it does not file reports or perform causality assessment autonomously.
import openmed
narrative = (
"68-year-old patient on warfarin 5 mg daily developed a gastrointestinal "
"hemorrhage and was hospitalized. Warfarin was discontinued; the patient "
"recovered."
)
# 1) Extract drug spans (Pharmaceutical category) on-device.
drugs = openmed.analyze_text(
narrative,
model_name="pharma_detection_superclinical",
output_format="dict",
)["entities"]
# 2) Extract condition / reaction spans (Disease category).
conditions = openmed.analyze_text(
narrative,
model_name="disease_detection_superclinical",
output_format="dict",
)["entities"]
# 3) Assemble an E2B(R3)-shaped ICSR skeleton (reaction PTs filled later via MedDRA).
icsr = {
"patient": {"age": None, "sex": None}, # from de-identified demographics
"drugs": [
{
"name": e["text"],
"drugcharacterization": 1, # 1=suspect 2=concomitant 3=interacting
"action": None, # e.g. drug withdrawn / dose reduced
}
for e in drugs
],
"reactions": [
{
"verbatim": e["text"], # narrative term, pre-MedDRA
"meddra_pt": None, # coded with user's MedDRA dict
"outcome": None, # E2B reaction outcome code
}
for e in conditions
],
"seriousness": {
"serious": None, "death": False, "lifeThreatening": False,
"hospitalization": True, "disability": False, "congenitalAnomaly": False,
"otherMedicallyImportant": False,
},
}Seriousness is a set of boolean criteria (E2B E.i.3.2). A case is serious if any criterion is true:
| Criterion | E2B element | FAERS field |
|---|---|---|
| Death | E.i.3.2a | seriousnessdeath |
| Life-threatening | E.i.3.2b | seriousnesslifethreatening |
| Hospitalization / prolonged | E.i.3.2c | seriousnesshospitalization |
| Disability / incapacity | E.i.3.2d | seriousnessdisabling |
| Congenital anomaly | E.i.3.2e | seriousnesscongenitalanomali |
| Other medically important | E.i.3.2f | seriousnessother |
Reaction outcome (E2B E.i.7) is a coded value: 1 recovered/resolved,
2 recovering/resolving, 3 not recovered/not resolved, 4 recovered with
sequelae, 5 fatal, 6 unknown.
Drug characterization (E2B G.k.1): 1 suspect, 2 concomitant, 3 interacting.
openmed.deidentify(narrative, policy=...) and
work from result.deidentified_text. Patient name, MRN, and dates must be
removed/shifted before the case leaves your environment.analyze_text calls above.
Keep each entity's start/end offsets for traceability.1), concomitant (2), or
interacting (3). The drug that temporally precedes the reaction and was
acted upon (withdrawn/reduced) is usually the suspect.serious=True if any is met. "Hospitalized", "admitted", "ICU" → C.1.7c.OpenMed's analyze_text returns a dict; result["entities"] is a list whose
items carry text, label, confidence, start, end. Consume them:
extracting-clinical-entities: Pharmaceutical entities →
icsr["drugs"]; Disease entities → icsr["reactions"]. Keep offsets so each
E2B field is traceable to the source span.normalizing-rxnorm: optionally attach an RxCUI to each suspect drug
for product identification (E2B G.k.2.2) before coding.deidentifying-clinical-text (openmed.deidentify)
before the case is exported or transmitted to any safety database.detecting-pv-signals: aggregated, coded cases feed disproportionality
analysis. To querying-openfda-labels: confirm the reaction is/ isn't a
labeled event (expectedness).drugcharacterization. Do not default every drug to suspect.80da98c
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.