Reading and Writing
Read the record with FHIR search; write only what the patient authors.
The record plane (/v1/fhir) is where your app reads everything and writes almost nothing. The SDK's helpers are typed against @palamond/sdk/fhir, so what you get back matches what you asked for.
Read a single resource
Read by type and id, or follow a reference from another resource.
import type { Patient, Questionnaire } from '@palamond/sdk/fhir';
const patient = await palamond.readResource('Patient', patientId);
// Follow a Reference found on another resource.
const questionnaire = await palamond.readReference<Questionnaire>(task.focus);Search
searchResources returns a typed array. search returns the full Bundle (for totals and paging). searchOne returns the first match or undefined.
// The patient's observations, newest first.
const observations = await palamond.searchResources('Observation', {
category: 'vital-signs',
_sort: '-date',
_count: 50,
});
// Just the latest weight.
const latestWeight = await palamond.searchOne('Observation', {
code: '29463-7',
_sort: '-date',
});Every search is automatically scoped to the signed-in patient's record; you do not need to filter by patient yourself.
Common search parameters
_sort: sort field, prefix with-for descending (-date)._countand_offset: page size and offset._lastUpdated: filter by change time (gt2026-01-01).status,category,code: filter clinical resources by their coded fields.date: filter by clinical date, with prefixes likegeandlt.
Including related resources
Fetch related resources in one round trip: _include pulls resources this one points to, _revinclude pulls resources pointing back at it. Included entries carry search.mode: 'include' in the Bundle.
const bundle = await palamond.search('Encounter', {
_include: 'Encounter:appointment',
});The write matrix
The record accepts writes only where the patient is the author of record:
| Resource | Methods | Used for |
|---|---|---|
Patient | PUT (own resource) | The patient's demographics and contact details. |
QuestionnaireResponse | POST, PUT | The patient's questionnaire answers, including drafts. |
Everything else changes through a workflow endpoint, and a write attempt answers 405 naming the endpoint that owns the change. That makes wrong turns self-correcting: the error tells you where to go.
// Update the patient's own contact details.
const me = await palamond.readResource('Patient', palamond.getProfile()!.id!);
me.telecom = [{ system: 'email', value: '[email protected]' }];
await palamond.updateResource(me);// Author questionnaire answers (a draft the patient can come back to).
import type { QuestionnaireResponse } from '@palamond/sdk/fhir';
const draft = await palamond.createResource<QuestionnaireResponse>({
resourceType: 'QuestionnaireResponse',
status: 'in-progress',
questionnaire: `${questionnaire.url}|${questionnaire.version}`,
subject: { reference: `Patient/${patientId}` },
item: [],
});Wondering why you cannot create an Observation directly? Measurements are recorded by completing their task (POST /v1/tasks/{id}/complete), so the platform validates values and coding once, for every app. The same logic applies across the record: the workflow endpoint is the write path.
Pagination
Use _count with _offset to walk pages, or read the Bundle's total with _total=accurate when you need a count.
const page = await palamond.searchResources('Observation', {
_sort: '-date',
_count: 20,
_offset: 40,
});Next: Querying for keeping these reads fast and fresh in a UI.