Symptom data API: concepts, FHIR terminology and patient-reported symptoms
Stable symptom identifiers mapped to ICD-10, served as REST and as FHIR CodeSystem, ValueSet and ConceptMap; how a patient-reported symptom Observation looks and how to validate one.
Anpheros gives every symptom a stable identifier (SYM-0047 is headache), maps it to ICD-10, and serves the list through a REST endpoint and as FHIR R4 terminology (CodeSystem, ValueSet, ConceptMap, $lookup). Symptoms that patients report are stored as FHIR Observations that carry both codes, the person's own words, the intensity and, when known, when the symptom started and ended. This page shows how to find a concept, how a patient-reported symptom looks, how to check one you write yourself, and what the data deliberately does not contain.
What is in the release
| Release | 2026.10.1 (every response says which) |
| Concepts | 86: 70 symptoms (ICD-10 R00–R69, plus the WHO code where WHO classifies the symptom elsewhere: G47, H53.2, H53.8, H93.1, K59.0, L29.9, M25.5, M54) and 16 findings (R70–R94) |
| Identifier system | https://anpheros.com/fhir/CodeSystem/symptom |
| Codes and English titles | checked against WHO ICD-10 Version 2019 (15 October 2026), with its inclusion and exclusion notes |
| Labels served | the WHO English title (source), the Romanian labels and match terms used by Anpheros Daily (in_use), and lay labels in 19 more languages (ai_reviewed: machine translations reviewed with AI assistance, not by a professional medical translator) |
| Clinical review | clinical_review: false — no clinician has reviewed the release; no causes or condition associations |
| Warning signs | 32, for 14 concepts, quoted word for word from CDC and NIDDK pages (review: source_verified) |
Identifiers are never reused. A concept that is withdrawn stays in the list with status: deprecated.
Find a concept (REST)
export API=https://platform.anpheros.com/v1
export KEY=sk_test_…
curl "$API/terminology/symptoms?q=headache" -H "Authorization: Bearer $KEY"
q matches the concept id, the ICD-10 code, the labels and the match terms. Other parameters: icd10=R51 (the concept for one code), kind=symptom|finding|all, lang=de (the language of display: the preferred label, else the lay label, else English), limit and offset.
{
"data": [{
"concept_id": "SYM-0047",
"system": "https://anpheros.com/fhir/CodeSystem/symptom",
"kind": "symptom",
"status": "active",
"display": "Headache",
"display_lang": "en",
"icd10": {"system": "http://hl7.org/fhir/sid/icd-10", "code": "R51", "display": "Headache", "equivalence": "equivalent"},
"labels": [
{"lang": "ro", "use": "preferred", "text": "Durere de cap (cefalee)", "review": "in_use"},
{"lang": "de", "use": "lay", "text": "Kopfschmerzen", "review": "ai_reviewed"}
],
"match_terms": [{"lang": "ro", "text": "durere de cap"}, {"lang": "ro", "text": "cefalee"}],
"clinical_review": false,
"release": "2026.10.1"
}],
"total": 1,
"release": "2026.10.1"
}
labels lists every served label (20 languages; shortened here). One concept: GET $API/terminology/symptoms/SYM-0047.
The same list as FHIR terminology
export BASE=https://platform.anpheros.com/fhir/R4
curl "$BASE/CodeSystem/anpheros-symptom" -H "Authorization: Bearer $KEY"
curl "$BASE/CodeSystem/\$lookup?system=https://anpheros.com/fhir/CodeSystem/symptom&code=SYM-0047&displayLanguage=ro" -H "Authorization: Bearer $KEY"
curl "$BASE/ValueSet/\$expand?url=https://anpheros.com/fhir/ValueSet/anpheros-symptoms&filter=cough" -H "Authorization: Bearer $KEY"
curl "$BASE/ConceptMap/anpheros-symptom-to-icd10" -H "Authorization: Bearer $KEY"
CodeSystem/anpheros-symptom—content: complete,status: draftuntil the release is clinically reviewed; propertieskind,status,icd10; Romanian labels, match terms and lay labels asdesignations.ValueSet/anpheros-symptoms— the active symptoms (findings excluded);$expandtakesfilter,displayLanguage,countandoffset.ConceptMap/anpheros-symptom-to-icd10—equivalent, orwiderwhen the ICD-10 code covers more than the concept (H53.8 "Other visual disturbances" is broader than blurred vision).- All of them are read-only and listed in the server's
CapabilityStatement(GET $BASE/metadata).
A patient-reported symptom
This is how Anpheros Daily writes a symptom a person reported as present, about themselves:
{
"resourceType": "Observation",
"status": "final",
"meta": {"profile": ["https://anpheros.com/fhir/StructureDefinition/anpheros-symptom-observation"]},
"category": [{"coding": [{"system": "urn:anpheros:observation-category", "code": "symptom"}]}],
"code": {
"text": "Mă doare capul de 3 zile",
"coding": [
{"system": "http://hl7.org/fhir/sid/icd-10", "code": "R51", "display": "Headache"},
{"system": "https://anpheros.com/fhir/CodeSystem/symptom", "code": "SYM-0047", "display": "Headache"}
]
},
"subject": {"reference": "Patient/…"},
"effectivePeriod": {"start": "2026-10-11T08:00:00+03:00", "end": "2026-10-14T18:00:00+03:00"},
"valueQuantity": {"value": 6, "unit": "1-10", "system": "http://unitsofmeasure.org", "code": "{score}"}
}
code.textis always the person's own words, in their language (Observation.language); the codes sit next to it.effectivePeriodis used when the person said when it started or ended; otherwiseeffectiveDateTimeis the moment they noted it. Times keep the offset of the phone that recorded them.valueQuantityis the intensity on a 1–10 scale; without one there is no value.- When the person edits a symptom, the same resource gets a new version — read earlier ones with
GET $BASE/Observation/{id}/_history. - Filter by category with
?category=symptom; consent scopes such aspatient/Observation.rs?category=symptomwork the same way.
What is never published as a symptom
Only symptoms that are present and about the patient become Observations, and only after the free text has been normalized. "My head no longer hurts", "maybe a fever tomorrow", "my mother has a cough" or a text the normalizer could not read do not become a patient's symptom; if a published symptom is later corrected to one of these, its Observation is withdrawn (soft delete — the history stays). Relatives' complaints are not turned into family history automatically.
Check a symptom you write
curl -X POST "$BASE/Observation/\$validate?profile=anpheros-symptom" -H "Authorization: Bearer $KEY" \
-H "Content-Type: application/fhir+json" -d @symptom.json
The anpheros-symptom profile (canonical https://anpheros.com/fhir/StructureDefinition/anpheros-symptom-observation) reports, as an OperationOutcome:
| Rule | Severity |
|---|---|
Category urn:anpheros:observation-category\|symptom (the HL7 observation-category system has no symptom code) |
error |
code.text present |
error |
| An Anpheros concept that exists and matches the ICD-10 code | error |
subject is a Patient; status final, amended, corrected or entered-in-error; effective[x] present; effectivePeriod.end not before start |
error |
Intensity as UCUM {score} between 0 and 10 |
error |
| Only free text, no codes | information (still valid) |
Like the other profiles, it reports and does not reject writes. A meta.profile you send is kept on the stored resource.
Limits
- The release is not clinically reviewed; use it for coding and search, not for medical decisions.
- Warning signs are quoted word for word from public-domain US federal pages (CDC: stroke and heart attack signs; NIDDK: diarrhea and constipation) and were checked against those pages on 15 October 2026. Each item carries the source's own heading (
context), its advice (quote), the group it applies to (applies_to), the source with licence and attribution,review: source_verifiedand the note that it is not a diagnosis and not reviewed by a clinician. The sources are American: where a quote says 9-1-1, the note adds that the emergency number in Europe is 112. - No causes or condition associations are served:
associationsstays empty until a clinician reviews an item. An association is always "may be associated with". - SNOMED CT codes are written only where the licence allows it (see FHIR code systems).
- Earlier symptom Observations receive the Anpheros concept coding the next time they are updated.
Related
- FHIR code systems: every code system per resource type
- Longitudinal patient data API
- How to store medical records using FHIR R4
- FHIR platform