AnpherosAnpheros PlatformDevelopers

Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no cardYour first API call in 2 minutes →

Your first write: an Observation and a Condition

Step 2 of the developer path: write a LOINC-coded Observation and an ICD-10 Condition to a sandbox patient with an author and an Idempotency-Key, in curl, Python and JavaScript, then check the timeline, FHIR and provenance.

Step 2 of 5. You can read the sandbox (see Your first API call); now write two of the most common things a health app stores: a measurement (an Observation, coded with LOINC) and a diagnosis already made by a clinician (a Condition, coded with ICD-10). Every write records who the author is and can be retried safely.

In short:

Observation Condition
What it is a measurement or a lab result a diagnosis or problem on record
Code system LOINC (for example 2339-0 glucose) ICD-10 (for example E11.9)
Endpoint POST /v1/patients/{id}/observations POST /v1/patients/{id}/conditions
Minimal body code, category, effective_at, value + unit code
Same data in FHIR Observation/{id} Condition/{id}
Two writes and a check
Your codeAnpheros APIPatient record1. POST observations · Idempotency-Key2. store version 1 + Provenance3. 201 · Observation/…4. POST conditions · ICD-10 E11.95. 201 · Condition/…6. GET timeline7. 200 · both entries, newest first

Before you start

You need a sandbox key with the write scope (the key from Get a sandbox key has read and write) and the id of a sandbox patient:

export ANPHEROS_KEY=sk_test_your_key_here
export PID=$(curl -s https://platform.anpheros.com/v1/patients -H "Authorization: Bearer $ANPHEROS_KEY" \
  | python3 -c "import sys, json; print(json.load(sys.stdin)['data'][0]['id'])")
echo $PID

1. Write an Observation

A fasting glucose of 112 mg/dL, measured by a device:

curl -X POST "https://platform.anpheros.com/v1/patients/$PID/observations" \
     -H "Authorization: Bearer $ANPHEROS_KEY" -H 'content-type: application/json' \
     -H "Idempotency-Key: $(uuidgen)" -d '{
  "code": "2339-0", "display": "Glucose", "category": "laboratory",
  "value": 112, "unit": "mg/dL", "effective_at": "2026-09-19T08:10:00Z",
  "author_type": "device"
}'

The answer is the stored observation, with its id, its fhir reference (Observation/…) and updated_at.

2. Write a Condition

A type 2 diabetes diagnosis, active since March 2021, entered by a clinician:

curl -X POST "https://platform.anpheros.com/v1/patients/$PID/conditions" \
     -H "Authorization: Bearer $ANPHEROS_KEY" -H 'content-type: application/json' \
     -H "Idempotency-Key: $(uuidgen)" -d '{
  "code": "E11.9", "display": "Type 2 diabetes mellitus without complications",
  "clinical_status": "active", "onset": "2021-03-01", "author_type": "practitioner"
}'
{"id":"…","patient":"…","code":"E11.9","system":"http://hl7.org/fhir/sid/icd-10","display":"Type 2 diabetes mellitus without complications","clinical_status":"active","onset":"2021-03-01","abatement":null,"note":null,"updated_at":"…","fhir":"Condition/…"}

3. The same writes in Python and JavaScript

import os, uuid, requests

BASE = "https://platform.anpheros.com"
H = {"Authorization": f"Bearer {os.environ['ANPHEROS_KEY']}"}
pid = requests.get(f"{BASE}/v1/patients", headers=H).json()["data"][0]["id"]

obs = requests.post(f"{BASE}/v1/patients/{pid}/observations",
                    headers={**H, "Idempotency-Key": str(uuid.uuid4())},
                    json={"code": "2339-0", "display": "Glucose", "category": "laboratory", "value": 112,
                          "unit": "mg/dL", "effective_at": "2026-09-19T08:10:00Z", "author_type": "device"})
cond = requests.post(f"{BASE}/v1/patients/{pid}/conditions",
                     headers={**H, "Idempotency-Key": str(uuid.uuid4())},
                     json={"code": "E11.9", "clinical_status": "active", "onset": "2021-03-01",
                           "author_type": "practitioner"})
print(obs.status_code, obs.json()["fhir"], cond.status_code, cond.json()["fhir"])
const BASE = 'https://platform.anpheros.com';
const H = { Authorization: `Bearer ${process.env.ANPHEROS_KEY}`, 'content-type': 'application/json' };
const { data } = await (await fetch(`${BASE}/v1/patients`, { headers: H })).json();
const post = (path, body) => fetch(`${BASE}${path}`, {
  method: 'POST', headers: { ...H, 'Idempotency-Key': crypto.randomUUID() }, body: JSON.stringify(body),
}).then(r => r.json());
const obs = await post(`/v1/patients/${data[0].id}/observations`, { code: '2339-0', display: 'Glucose',
  category: 'laboratory', value: 112, unit: 'mg/dL', effective_at: '2026-09-19T08:10:00Z', author_type: 'device' });
const cond = await post(`/v1/patients/${data[0].id}/conditions`, { code: 'E11.9', clinical_status: 'active',
  onset: '2021-03-01', author_type: 'practitioner' });
console.log(obs.fhir, cond.fhir);

The SDKs add the Idempotency-Key for you: anpheros.observations.create(...) in TypeScript and Dart. See SDKs.

4. Check what you wrote

# the record, newest first
curl "https://platform.anpheros.com/v1/patients/$PID/timeline" -H "Authorization: Bearer $ANPHEROS_KEY"
# the same Condition as strict FHIR R4
curl "https://platform.anpheros.com/fhir/R4/Condition?patient=$PID&code=http://hl7.org/fhir/sid/icd-10|E11.9" \
     -H "Authorization: Bearer $ANPHEROS_KEY"
# who wrote it, and when
curl "https://platform.anpheros.com/v1/patients/$PID/provenance/Observation/<observation id>" \
     -H "Authorization: Bearer $ANPHEROS_KEY"

Nothing is overwritten silently: an update creates a new version, and the history stays at /fhir/R4/{Type}/{id}/_history.

Common errors

You get Fix
403 This credential does not have the 'write' scope. Use a key with write; see Troubleshooting
422 The referenced Patient does not exist. The patient id is from another project or from before a sandbox reset: read it again
422 Idempotency-Key was already used with a different request. Use a new key for each new write
400 with a field name A required field is missing or a value is not allowed, for example a clinical_status outside the list above

Next step

Step 3: when a real person uses your app, they sign in and approve access themselves: Create an OAuth app and the consent screen.

Frequently asked questions

Do I have to use LOINC and ICD-10?

They are the defaults: LOINC for observations and ICD-10 for conditions. Codes from other systems can be sent with their system; see FHIR code systems.

Can I write with FHIR instead of /v1?

Yes. POST /fhir/R4/Observation and POST /fhir/R4/Condition take FHIR R4 resources and store them in the same record, with the same ids.

What happens if I send the same write twice?

With the same Idempotency-Key, the second request returns the first answer and nothing is duplicated. Without one, you get two resources.

Ask your AI

Paste this into Claude, ChatGPT, Cursor or Claude Code. Your assistant reads this guide and adapts it to your code.

Read https://developers.anpheros.com/guides/first-write.md and help me write my first Observation and Condition to a sandbox patient. Use the Anpheros sandbox (base URL https://platform.anpheros.com) with my API key from the ANPHEROS_KEY environment variable, never written in the code. Give me complete, runnable code, the response I should expect, and how to fix the errors in https://developers.anpheros.com/guides/troubleshooting.md if a call fails.

Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no cardYour first API call in 2 minutes →

Product updates by email

New features, guides and the end of the beta. One email a month at most.

Send me occasional Anpheros Platform updates by email (new features, API changes, guides). I'll confirm by email and can unsubscribe in one click from any email. Privacy