<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Adrian Kereky</title>
    <description>The latest articles on DEV Community by Adrian Kereky (@adrian_kereky_23e9b987b1b).</description>
    <link>https://dev.to/adrian_kereky_23e9b987b1b</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4180333%2F4b93a4fc-5938-4dc9-a8a4-e4c1ed8a378a.png</url>
      <title>DEV Community: Adrian Kereky</title>
      <link>https://dev.to/adrian_kereky_23e9b987b1b</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/adrian_kereky_23e9b987b1b"/>
    <language>en</language>
    <item>
      <title>We loaded Synthea patients into a FHIR server: 182 of 221 resources made it</title>
      <dc:creator>Adrian Kereky</dc:creator>
      <pubDate>Tue, 13 Oct 2026 17:22:23 +0000</pubDate>
      <link>https://dev.to/adrian_kereky_23e9b987b1b/we-loaded-synthea-patients-into-a-fhir-server-182-of-221-resources-made-it-k3k</link>
      <guid>https://dev.to/adrian_kereky_23e9b987b1b/we-loaded-synthea-patients-into-a-fhir-server-182-of-221-resources-made-it-k3k</guid>
      <description>&lt;p&gt;Synthea (MITRE's open-source patient simulator) is the default source of synthetic FHIR data. We generated two patients (&lt;code&gt;java -jar synthea-with-dependencies.jar -p 2 -s 4242 Massachusetts&lt;/code&gt;) and loaded them into Anpheros, the FHIR backend I work on. The first bundle had 221 entries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What did not fit:&lt;/strong&gt; 39 entries of types the server does not store — Claim (13), ExplanationOfBenefit (13), SupplyDelivery (9), Device (2), ImagingStudy (1), MedicationRequest (1). Synthea models US billing in detail; a clinical record usually doesn't need it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The loader&lt;/strong&gt; asks the server which types it supports and posts the rest as one transaction:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;readFile&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;node:fs/promises&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Anpheros&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;apiKey&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@anpheros/sdk&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;anpheros&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Anpheros&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ANPHEROS_KEY&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;   &lt;span class="c1"&gt;// a sandbox key, sk_test_…&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SUPPORTED&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(((&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;anpheros&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fhir&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bundle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;utf8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;            &lt;span class="c1"&gt;// one Synthea patient file&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;kept&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;bundle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;SUPPORTED&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resourceType&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;out&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;anpheros&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fhir&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;bundle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;kept&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;created&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;182 resources were created in one transaction, &lt;code&gt;urn:uuid&lt;/code&gt; references resolved, and the patient's International Patient Summary came out with 15 problems, 6 immunizations, 15 results and 28 vital signs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Three things to watch&lt;/strong&gt; if you do the same with any server:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Conditional references.&lt;/strong&gt; Synthea points to practitioners and organisations as &lt;code&gt;Practitioner?identifier=…&lt;/code&gt;. Servers differ: ours stored them as written and did not resolve them. Check yours before following those links.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Removed is not converted.&lt;/strong&gt; Dropping &lt;code&gt;MedicationRequest&lt;/code&gt; means the medication disappears. Convert it to &lt;code&gt;MedicationStatement&lt;/code&gt; first if you need it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Names with numbers&lt;/strong&gt; (&lt;code&gt;Marcelo725 Gulgowski816&lt;/code&gt;) are deliberate, so no one mistakes synthetic people for real ones.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Full guide, including when to use Synthea vs hand-made personas and what good test data must contain: &lt;strong&gt;&lt;a href="https://developers.anpheros.com/guides/synthetic-patient-data" rel="noopener noreferrer"&gt;Synthetic patient data for testing&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>fhir</category>
      <category>healthtech</category>
      <category>testing</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Mapping an HL7 v2 lab result to a FHIR Observation (and the traps that create duplicates)</title>
      <dc:creator>Adrian Kereky</dc:creator>
      <pubDate>Tue, 13 Oct 2026 17:21:19 +0000</pubDate>
      <link>https://dev.to/adrian_kereky_23e9b987b1b/mapping-an-hl7-v2-lab-result-to-a-fhir-observation-and-the-traps-that-create-duplicates-kpb</link>
      <guid>https://dev.to/adrian_kereky_23e9b987b1b/mapping-an-hl7-v2-lab-result-to-a-fhir-observation-and-the-traps-that-create-duplicates-kpb</guid>
      <description>&lt;p&gt;Most labs still send results as HL7 v2 &lt;code&gt;ORU^R01&lt;/code&gt; messages. Most new apps want FHIR. The mapping looks trivial:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OBX|1|NM|2093-3^Cholesterol^LN||212|mg/dL|&amp;lt;200|H|||F|||20261002074500
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;OBX field&lt;/th&gt;
&lt;th&gt;FHIR R4 Observation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;OBX-3 &lt;code&gt;2093-3^Cholesterol^LN&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;code.coding&lt;/code&gt; (LOINC)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OBX-5 + OBX-6&lt;/td&gt;
&lt;td&gt;&lt;code&gt;valueQuantity&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OBX-7 &lt;code&gt;&amp;lt;200&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;referenceRange.high&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OBX-8 &lt;code&gt;H&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;interpretation&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OBX-11 &lt;code&gt;F&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;status = final&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OBX-14&lt;/td&gt;
&lt;td&gt;&lt;code&gt;effectiveDateTime&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The field mapping is the easy 20%. The 80% that breaks production:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Time zones.&lt;/strong&gt; &lt;code&gt;20261002074500&lt;/code&gt; has no offset. FHIR requires one whenever a time is present. Decide the sender's zone explicitly; don't let a library guess.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Local codes.&lt;/strong&gt; Many labs put their own code in OBX-3. Keep it next to the LOINC code you map to, never drop it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resends.&lt;/strong&gt; v2 senders retransmit on timeouts. Without a stable identifier per result (report id + code + time + value), your FHIR store fills with duplicates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Corrections.&lt;/strong&gt; OBX-11 &lt;code&gt;C&lt;/code&gt; means corrected. Decide whether a correction updates the earlier Observation (keeping history) or arrives as a new one, and mark the old one &lt;code&gt;entered-in-error&lt;/code&gt; if so.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Values that are not numbers.&lt;/strong&gt; &lt;code&gt;&amp;lt;5&lt;/code&gt;, &lt;code&gt;6,4&lt;/code&gt;, &lt;code&gt;positive&lt;/code&gt;: parse them deliberately, or store them as &lt;code&gt;valueString&lt;/code&gt; rather than inventing a number.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;All five are cases the lab import of Anpheros (I work on it) has to handle. The full write-up, with a real import response and the FHIR Observation it produced, is here: &lt;strong&gt;&lt;a href="https://developers.anpheros.com/guides/lab-results-api" rel="noopener noreferrer"&gt;Lab results API: HL7 v2, FHIR and LOINC&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you want to check a translated Observation quickly, there is a free &lt;a href="https://developers.anpheros.com/tools/fhir-validator" rel="noopener noreferrer"&gt;FHIR R4 validator&lt;/a&gt; that lists every structural error with its path (it does not check terminology; use the official HL7 validator for full conformance).&lt;/p&gt;

</description>
      <category>fhir</category>
      <category>healthtech</category>
      <category>hl7</category>
      <category>api</category>
    </item>
    <item>
      <title>Giving an LLM a patient's record without dumping the whole FHIR bundle</title>
      <dc:creator>Adrian Kereky</dc:creator>
      <pubDate>Mon, 12 Oct 2026 20:15:50 +0000</pubDate>
      <link>https://dev.to/adrian_kereky_23e9b987b1b/giving-an-llm-a-patients-record-without-dumping-the-whole-fhir-bundle-1kag</link>
      <guid>https://dev.to/adrian_kereky_23e9b987b1b/giving-an-llm-a-patients-record-without-dumping-the-whole-fhir-bundle-1kag</guid>
      <description>&lt;p&gt;&lt;em&gt;Disclosure: I work on &lt;a href="https://anpheros.com" rel="noopener noreferrer"&gt;Anpheros&lt;/a&gt;, the platform used in the examples. The approach (budgeted, provenance-labelled context) applies to any FHIR backend.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you have ever pushed a FHIR &lt;code&gt;$everything&lt;/code&gt; Bundle into a prompt, you know the problem: a few months of vitals is already thousands of Observations. Most of it is irrelevant to the question, all of it costs tokens, and the model has no way to tell a lab-measured value from one the patient typed in or one an earlier AI step guessed.&lt;/p&gt;

&lt;p&gt;Three things matter when a model reads a medical record:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Relevance.&lt;/strong&gt; A medication review before a cardiology visit needs blood pressure trends, current medications and a few labs, not every step count.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A budget.&lt;/strong&gt; You decide how many tokens the record may take, and you want to know what was left out.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Provenance.&lt;/strong&gt; Each fact should carry who wrote it (device, practitioner, patient, import, AI) and from where. AI-generated values should never be mixed with measured ones.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Doing it by hand
&lt;/h3&gt;

&lt;p&gt;On a plain FHIR server you would: search Observations by LOINC code and date, compute weekly trends, pull active &lt;code&gt;MedicationStatement&lt;/code&gt;s and &lt;code&gt;Condition&lt;/code&gt;s, look up each resource's &lt;code&gt;Provenance&lt;/code&gt;, rank, trim to a token count, and keep a list of what you dropped. It is all doable, and it is a week of work you will redo for every new question type.&lt;/p&gt;

&lt;h3&gt;
  
  
  Asking the backend for a context instead
&lt;/h3&gt;

&lt;p&gt;Anpheros exposes this as one call. Get a free sandbox key (sign in with Google at &lt;a href="https://platform.anpheros.com/dashboard/" rel="noopener noreferrer"&gt;platform.anpheros.com/dashboard&lt;/a&gt; → &lt;em&gt;Get a sandbox key&lt;/em&gt;); every sandbox project comes with 30 synthetic patients with six months of history.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @anpheros/sdk
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;ANPHEROS_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;sk_test_...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Anpheros&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;apiKey&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@anpheros/sdk&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;anpheros&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Anpheros&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ANPHEROS_KEY&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;patients&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;anpheros&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;patients&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;patient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;patients&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="c1"&gt;// Raw data is still there when you need it&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;labs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;anpheros&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;observations&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;patient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;laboratory&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// A budgeted context for a specific task&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;anpheros&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;patient&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;patient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;task&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;weekly check-in&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;budget_tokens&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same call over HTTP:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://platform.anpheros.com/v1/context"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$ANPHEROS_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'content-type: application/json'&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
  "patient": "'&lt;/span&gt;&lt;span class="nv"&gt;$PID&lt;/span&gt;&lt;span class="s1"&gt;'",
  "task": "medication review before a cardiology visit",
  "question": "How did blood pressure evolve over the last 3 months?",
  "budget_tokens": 1500,
  "format": "text"
}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What comes back: sections (summary, conditions, medications, allergies, labs, vitals with weekly trends and before/after-treatment markers, symptoms, timeline, documents); every item labelled with &lt;code&gt;author_type&lt;/code&gt; and &lt;code&gt;source&lt;/code&gt;; a list of what was omitted to fit the budget; warnings; and a &lt;code&gt;manifest_id&lt;/code&gt; that ties the call to the audit log, so you can later answer "what exactly did the model see?". Values produced by AI only appear under &lt;code&gt;ai_notes&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You can also be explicit: &lt;code&gt;"needs": ["labs:4548-4", "vitals:trend:85354-9", "timeline:180d"]&lt;/code&gt; (HbA1c, blood pressure trend, last 180 days).&lt;/p&gt;

&lt;h3&gt;
  
  
  Writing back, honestly
&lt;/h3&gt;

&lt;p&gt;Every write says who produced the value. A reading from a glucometer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://platform.anpheros.com/v1/patients/&lt;/span&gt;&lt;span class="nv"&gt;$PID&lt;/span&gt;&lt;span class="s2"&gt;/observations"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$ANPHEROS_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'content-type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Idempotency-Key: &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;uuidgen&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
  "code": "2339-0", "display": "Glucose", "category": "laboratory",
  "value": 112, "unit": "mg/dL", "effective_at": "2026-09-19T08:10:00Z",
  "author_type": "device"
}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A value your model produced goes in with &lt;code&gt;"author_type": "ai"&lt;/code&gt;. If you omit the field, it defaults to &lt;code&gt;import&lt;/code&gt;, never &lt;code&gt;patient&lt;/code&gt;. Every write creates a FHIR &lt;code&gt;Provenance&lt;/code&gt;, and &lt;code&gt;/fhir/R4/Observation/{id}/_history&lt;/code&gt; keeps prior versions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Real patients need consent, not keys
&lt;/h3&gt;

&lt;p&gt;API keys only see your own project's patients (its sandbox copies and the ones it created). To read a person's existing record you go through OAuth 2.1 + PKCE (SMART on FHIR standalone launch, SMART v2 scopes); the person picks what to share and for how long, and can revoke. Both SDKs implement the flow.&lt;/p&gt;

&lt;h3&gt;
  
  
  Limits worth knowing
&lt;/h3&gt;

&lt;p&gt;Sandbox data is synthetic only. The platform is in private beta; EHR launch and Bulk Data are not supported. Anpheros does not run the model; you bring your own (hosted or local).&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://developers.anpheros.com/guides/getting-started" rel="noopener noreferrer"&gt;Getting started&lt;/a&gt;: from a key to reading and writing a record&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developers.anpheros.com/guides/llm-healthcare-data" rel="noopener noreferrer"&gt;LLM applications and healthcare data&lt;/a&gt;: the context API in more depth&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/anpheros/anpheros-sdk" rel="noopener noreferrer"&gt;SDKs and runnable examples&lt;/a&gt;, including &lt;code&gt;ai-context-llm&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>fhir</category>
      <category>healthtech</category>
      <category>ai</category>
      <category>typescript</category>
    </item>
  </channel>
</rss>
