# Create Account
Source: https://docs.clinikapi.com/api-reference/accounts/create
post /v1/accounts
# Delete Account
Source: https://docs.clinikapi.com/api-reference/accounts/delete
delete /v1/accounts/{id}
# Read Account
Source: https://docs.clinikapi.com/api-reference/accounts/read
get /v1/accounts/{id}
# Search Accounts
Source: https://docs.clinikapi.com/api-reference/accounts/search
get /v1/accounts
# Update Account
Source: https://docs.clinikapi.com/api-reference/accounts/update
patch /v1/accounts/{id}
# Create Activity Definition
Source: https://docs.clinikapi.com/api-reference/activity-definitions/create
post /v1/activity-definitions
# Delete Activity Definition
Source: https://docs.clinikapi.com/api-reference/activity-definitions/delete
delete /v1/activity-definitions/{id}
# Read Activity Definition
Source: https://docs.clinikapi.com/api-reference/activity-definitions/read
get /v1/activity-definitions/{id}
# Search Activity Definitions
Source: https://docs.clinikapi.com/api-reference/activity-definitions/search
get /v1/activity-definitions
# Update Activity Definition
Source: https://docs.clinikapi.com/api-reference/activity-definitions/update
patch /v1/activity-definitions/{id}
# Create Allergy
Source: https://docs.clinikapi.com/api-reference/allergies/create
post /v1/allergies
# Delete Allergy
Source: https://docs.clinikapi.com/api-reference/allergies/delete
delete /v1/allergies/{id}
# Read Allergy
Source: https://docs.clinikapi.com/api-reference/allergies/read
get /v1/allergies/{id}
# Search Allergies
Source: https://docs.clinikapi.com/api-reference/allergies/search
get /v1/allergies
# Update Allergy
Source: https://docs.clinikapi.com/api-reference/allergies/update
patch /v1/allergies/{id}
# Create Appointment Response
Source: https://docs.clinikapi.com/api-reference/appointment-responses/create
post /v1/appointment-responses
# Delete Appointment Response
Source: https://docs.clinikapi.com/api-reference/appointment-responses/delete
delete /v1/appointment-responses/{id}
# Read Appointment Response
Source: https://docs.clinikapi.com/api-reference/appointment-responses/read
get /v1/appointment-responses/{id}
# Search Appointment Responses
Source: https://docs.clinikapi.com/api-reference/appointment-responses/search
get /v1/appointment-responses
# Update Appointment Response
Source: https://docs.clinikapi.com/api-reference/appointment-responses/update
patch /v1/appointment-responses/{id}
# Create Appointment
Source: https://docs.clinikapi.com/api-reference/appointments/create
post /v1/appointments
# Delete Appointment
Source: https://docs.clinikapi.com/api-reference/appointments/delete
delete /v1/appointments/{id}
# Read Appointment
Source: https://docs.clinikapi.com/api-reference/appointments/read
get /v1/appointments/{id}
# Search Appointments
Source: https://docs.clinikapi.com/api-reference/appointments/search
get /v1/appointments
# Update Appointment
Source: https://docs.clinikapi.com/api-reference/appointments/update
patch /v1/appointments/{id}
# Create Assessment
Source: https://docs.clinikapi.com/api-reference/assessments/create
post /v1/assessments
# Delete Assessment
Source: https://docs.clinikapi.com/api-reference/assessments/delete
delete /v1/assessments/{id}
# Read Assessment
Source: https://docs.clinikapi.com/api-reference/assessments/read
get /v1/assessments/{id}
# Search Assessments
Source: https://docs.clinikapi.com/api-reference/assessments/search
get /v1/assessments
# Update Assessment
Source: https://docs.clinikapi.com/api-reference/assessments/update
patch /v1/assessments/{id}
# Create Audit Event
Source: https://docs.clinikapi.com/api-reference/audit-events/create
post /v1/audit-events
# Delete Audit Event
Source: https://docs.clinikapi.com/api-reference/audit-events/delete
delete /v1/audit-events/{id}
# Read Audit Event
Source: https://docs.clinikapi.com/api-reference/audit-events/read
get /v1/audit-events/{id}
# Search Audit Events
Source: https://docs.clinikapi.com/api-reference/audit-events/search
get /v1/audit-events
# Bulk Export
Source: https://docs.clinikapi.com/api-reference/bulk/export
post /v1/bulk/export
Export tenant data as NDJSON. Returns a job ID for status polling. Rate limited to 5 operations per hour.
# Bulk Import
Source: https://docs.clinikapi.com/api-reference/bulk/import
post /v1/bulk/import
Import NDJSON data. Max 10,000 records per batch. Tenant tags are injected automatically.
# Bulk Job Status
Source: https://docs.clinikapi.com/api-reference/bulk/job-status
get /v1/bulk/jobs/{jobId}
# Create Care Plan
Source: https://docs.clinikapi.com/api-reference/care-plans/create
post /v1/care-plans
# Delete Care Plan
Source: https://docs.clinikapi.com/api-reference/care-plans/delete
delete /v1/care-plans/{id}
# Read Care Plan
Source: https://docs.clinikapi.com/api-reference/care-plans/read
get /v1/care-plans/{id}
# Search Care Plans
Source: https://docs.clinikapi.com/api-reference/care-plans/search
get /v1/care-plans
# Update Care Plan
Source: https://docs.clinikapi.com/api-reference/care-plans/update
patch /v1/care-plans/{id}
# Create Care Team
Source: https://docs.clinikapi.com/api-reference/care-teams/create
post /v1/care-teams
# Delete Care Team
Source: https://docs.clinikapi.com/api-reference/care-teams/delete
delete /v1/care-teams/{id}
# Read Care Team
Source: https://docs.clinikapi.com/api-reference/care-teams/read
get /v1/care-teams/{id}
# Search Care Teams
Source: https://docs.clinikapi.com/api-reference/care-teams/search
get /v1/care-teams
# Update Care Team
Source: https://docs.clinikapi.com/api-reference/care-teams/update
patch /v1/care-teams/{id}
# Create Charge Item
Source: https://docs.clinikapi.com/api-reference/charge-items/create
post /v1/charge-items
# Delete Charge Item
Source: https://docs.clinikapi.com/api-reference/charge-items/delete
delete /v1/charge-items/{id}
# Read Charge Item
Source: https://docs.clinikapi.com/api-reference/charge-items/read
get /v1/charge-items/{id}
# Search Charge Items
Source: https://docs.clinikapi.com/api-reference/charge-items/search
get /v1/charge-items
# Update Charge Item
Source: https://docs.clinikapi.com/api-reference/charge-items/update
patch /v1/charge-items/{id}
# Create Claim Response
Source: https://docs.clinikapi.com/api-reference/claim-responses/create
post /v1/claim-responses
# Delete Claim Response
Source: https://docs.clinikapi.com/api-reference/claim-responses/delete
delete /v1/claim-responses/{id}
# Read Claim Response
Source: https://docs.clinikapi.com/api-reference/claim-responses/read
get /v1/claim-responses/{id}
# Search Claim Responses
Source: https://docs.clinikapi.com/api-reference/claim-responses/search
get /v1/claim-responses
# Update Claim Response
Source: https://docs.clinikapi.com/api-reference/claim-responses/update
patch /v1/claim-responses/{id}
# Create Claim
Source: https://docs.clinikapi.com/api-reference/claims/create
post /v1/claims
# Delete Claim
Source: https://docs.clinikapi.com/api-reference/claims/delete
delete /v1/claims/{id}
# Read Claim
Source: https://docs.clinikapi.com/api-reference/claims/read
get /v1/claims/{id}
# Search Claims
Source: https://docs.clinikapi.com/api-reference/claims/search
get /v1/claims
# Update Claim
Source: https://docs.clinikapi.com/api-reference/claims/update
patch /v1/claims/{id}
# Create Condition
Source: https://docs.clinikapi.com/api-reference/conditions/create
post /v1/conditions
# Delete Condition
Source: https://docs.clinikapi.com/api-reference/conditions/delete
delete /v1/conditions/{id}
# Read Condition
Source: https://docs.clinikapi.com/api-reference/conditions/read
get /v1/conditions/{id}
# Search Conditions
Source: https://docs.clinikapi.com/api-reference/conditions/search
get /v1/conditions
# Update Condition
Source: https://docs.clinikapi.com/api-reference/conditions/update
patch /v1/conditions/{id}
# Sign Consent
Source: https://docs.clinikapi.com/api-reference/consents/create
post /v1/consents
# Delete Consent
Source: https://docs.clinikapi.com/api-reference/consents/delete
delete /v1/consents/{id}
# Read Consent
Source: https://docs.clinikapi.com/api-reference/consents/read
get /v1/consents/{id}
# Search Consents
Source: https://docs.clinikapi.com/api-reference/consents/search
get /v1/consents
# Update Consent
Source: https://docs.clinikapi.com/api-reference/consents/update
patch /v1/consents/{id}
# Create Coverage
Source: https://docs.clinikapi.com/api-reference/coverages/create
post /v1/coverages
# Delete Coverage
Source: https://docs.clinikapi.com/api-reference/coverages/delete
delete /v1/coverages/{id}
# Read Coverage
Source: https://docs.clinikapi.com/api-reference/coverages/read
get /v1/coverages/{id}
# Search Coverages
Source: https://docs.clinikapi.com/api-reference/coverages/search
get /v1/coverages
# Update Coverage
Source: https://docs.clinikapi.com/api-reference/coverages/update
patch /v1/coverages/{id}
# Create Device Request
Source: https://docs.clinikapi.com/api-reference/device-requests/create
post /v1/device-requests
# Delete Device Request
Source: https://docs.clinikapi.com/api-reference/device-requests/delete
delete /v1/device-requests/{id}
# Read Device Request
Source: https://docs.clinikapi.com/api-reference/device-requests/read
get /v1/device-requests/{id}
# Search Device Requests
Source: https://docs.clinikapi.com/api-reference/device-requests/search
get /v1/device-requests
# Update Device Request
Source: https://docs.clinikapi.com/api-reference/device-requests/update
patch /v1/device-requests/{id}
# Create Device Use Statement
Source: https://docs.clinikapi.com/api-reference/device-use-statements/create
post /v1/device-use-statements
# Delete Device Use Statement
Source: https://docs.clinikapi.com/api-reference/device-use-statements/delete
delete /v1/device-use-statements/{id}
# Read Device Use Statement
Source: https://docs.clinikapi.com/api-reference/device-use-statements/read
get /v1/device-use-statements/{id}
# Search Device Use Statements
Source: https://docs.clinikapi.com/api-reference/device-use-statements/search
get /v1/device-use-statements
# Update Device Use Statement
Source: https://docs.clinikapi.com/api-reference/device-use-statements/update
patch /v1/device-use-statements/{id}
# Create Device
Source: https://docs.clinikapi.com/api-reference/devices/create
post /v1/devices
# Delete Device
Source: https://docs.clinikapi.com/api-reference/devices/delete
delete /v1/devices/{id}
# Read Device
Source: https://docs.clinikapi.com/api-reference/devices/read
get /v1/devices/{id}
# Search Devices
Source: https://docs.clinikapi.com/api-reference/devices/search
get /v1/devices
# Update Device
Source: https://docs.clinikapi.com/api-reference/devices/update
patch /v1/devices/{id}
# Create Document
Source: https://docs.clinikapi.com/api-reference/documents/create
post /v1/documents
# Delete Document
Source: https://docs.clinikapi.com/api-reference/documents/delete
delete /v1/documents/{id}
# Read Document
Source: https://docs.clinikapi.com/api-reference/documents/read
get /v1/documents/{id}
# Search Documents
Source: https://docs.clinikapi.com/api-reference/documents/search
get /v1/documents
# Update Document
Source: https://docs.clinikapi.com/api-reference/documents/update
patch /v1/documents/{id}
# Create Eligibility Request
Source: https://docs.clinikapi.com/api-reference/eligibility-requests/create
post /v1/eligibility-requests
# Delete Eligibility Request
Source: https://docs.clinikapi.com/api-reference/eligibility-requests/delete
delete /v1/eligibility-requests/{id}
# Read Eligibility Request
Source: https://docs.clinikapi.com/api-reference/eligibility-requests/read
get /v1/eligibility-requests/{id}
# Search Eligibility Requests
Source: https://docs.clinikapi.com/api-reference/eligibility-requests/search
get /v1/eligibility-requests
# Update Eligibility Request
Source: https://docs.clinikapi.com/api-reference/eligibility-requests/update
patch /v1/eligibility-requests/{id}
# Create Eligibility Response
Source: https://docs.clinikapi.com/api-reference/eligibility-responses/create
post /v1/eligibility-responses
# Delete Eligibility Response
Source: https://docs.clinikapi.com/api-reference/eligibility-responses/delete
delete /v1/eligibility-responses/{id}
# Read Eligibility Response
Source: https://docs.clinikapi.com/api-reference/eligibility-responses/read
get /v1/eligibility-responses/{id}
# Search Eligibility Responses
Source: https://docs.clinikapi.com/api-reference/eligibility-responses/search
get /v1/eligibility-responses
# Update Eligibility Response
Source: https://docs.clinikapi.com/api-reference/eligibility-responses/update
patch /v1/eligibility-responses/{id}
# Create Encounter
Source: https://docs.clinikapi.com/api-reference/encounters/create
post /v1/encounters
# Delete Encounter
Source: https://docs.clinikapi.com/api-reference/encounters/delete
delete /v1/encounters/{id}
# Read Encounter
Source: https://docs.clinikapi.com/api-reference/encounters/read
get /v1/encounters/{id}
# Search Encounters
Source: https://docs.clinikapi.com/api-reference/encounters/search
get /v1/encounters
# Update Encounter
Source: https://docs.clinikapi.com/api-reference/encounters/update
patch /v1/encounters/{id}
# Create Enrollment Request
Source: https://docs.clinikapi.com/api-reference/enrollment-requests/create
post /v1/enrollment-requests
# Delete Enrollment Request
Source: https://docs.clinikapi.com/api-reference/enrollment-requests/delete
delete /v1/enrollment-requests/{id}
# Read Enrollment Request
Source: https://docs.clinikapi.com/api-reference/enrollment-requests/read
get /v1/enrollment-requests/{id}
# Search Enrollment Requests
Source: https://docs.clinikapi.com/api-reference/enrollment-requests/search
get /v1/enrollment-requests
# Update Enrollment Request
Source: https://docs.clinikapi.com/api-reference/enrollment-requests/update
patch /v1/enrollment-requests/{id}
# Create Enrollment Response
Source: https://docs.clinikapi.com/api-reference/enrollment-responses/create
post /v1/enrollment-responses
# Delete Enrollment Response
Source: https://docs.clinikapi.com/api-reference/enrollment-responses/delete
delete /v1/enrollment-responses/{id}
# Read Enrollment Response
Source: https://docs.clinikapi.com/api-reference/enrollment-responses/read
get /v1/enrollment-responses/{id}
# Search Enrollment Responses
Source: https://docs.clinikapi.com/api-reference/enrollment-responses/search
get /v1/enrollment-responses
# Update Enrollment Response
Source: https://docs.clinikapi.com/api-reference/enrollment-responses/update
patch /v1/enrollment-responses/{id}
# Create Explanation of Benefit
Source: https://docs.clinikapi.com/api-reference/eobs/create
post /v1/eobs
# Delete Explanation of Benefit
Source: https://docs.clinikapi.com/api-reference/eobs/delete
delete /v1/eobs/{id}
# Read Explanation of Benefit
Source: https://docs.clinikapi.com/api-reference/eobs/read
get /v1/eobs/{id}
# Search Explanations of Benefit
Source: https://docs.clinikapi.com/api-reference/eobs/search
get /v1/eobs
# Update Explanation of Benefit
Source: https://docs.clinikapi.com/api-reference/eobs/update
patch /v1/eobs/{id}
# Create Family History
Source: https://docs.clinikapi.com/api-reference/family-history/create
post /v1/family-history
# Delete Family History
Source: https://docs.clinikapi.com/api-reference/family-history/delete
delete /v1/family-history/{id}
# Read Family History
Source: https://docs.clinikapi.com/api-reference/family-history/read
get /v1/family-history/{id}
# Search Family History
Source: https://docs.clinikapi.com/api-reference/family-history/search
get /v1/family-history
# Update Family History
Source: https://docs.clinikapi.com/api-reference/family-history/update
patch /v1/family-history/{id}
# Create (FHIR)
Source: https://docs.clinikapi.com/api-reference/fhir/create
post /v1/fhir/{path}
Create a raw FHIR R4 resource.
## Create a FHIR Resource
```bash theme={null}
curl -X POST https://api.clinikapi.com/v1/fhir/Patient \
-H "x-api-key: clk_live_abc123" \
-H "Content-Type: application/fhir+json" \
-d '{
"resourceType": "Patient",
"name": [{ "family": "Smith", "given": ["John"] }],
"gender": "male",
"birthDate": "1985-06-20"
}'
```
Your tenant tag is automatically injected into `meta.tag`. You do not need to include it.
# Delete (FHIR)
Source: https://docs.clinikapi.com/api-reference/fhir/delete
delete /v1/fhir/{path}
Delete a FHIR R4 resource.
## Delete a FHIR Resource
```bash theme={null}
curl -X DELETE https://api.clinikapi.com/v1/fhir/Observation/obs_xyz789 \
-H "x-api-key: clk_live_abc123"
```
Returns `204 No Content` on success. Ownership is verified — you can only delete resources belonging to your tenant.
# FHIR Passthrough
Source: https://docs.clinikapi.com/api-reference/fhir/overview
Send raw FHIR R4 requests through the ClinikAPI gateway.
# FHIR Passthrough
The `/v1/fhir/*` endpoint lets you send raw FHIR R4 requests directly to the ClinikAPI FHIR gateway. Tenant isolation is still enforced — tenant tags are injected on creates and filtered on searches.
## Base Path
```
https://api.clinikapi.com/v1/fhir/{FhirResourcePath}
```
## Authentication
Same as all other endpoints — `x-api-key` header required.
## Supported Operations
| Method | Path | Description |
| - | - | - |
| `GET` | `/v1/fhir/{Type}` | Search resources |
| `GET` | `/v1/fhir/{Type}/{id}` | Read a resource |
| `POST` | `/v1/fhir/{Type}` | Create a resource |
| `PATCH` | `/v1/fhir/{Type}/{id}` | Update a resource |
| `DELETE` | `/v1/fhir/{Type}/{id}` | Delete a resource |
## Tenant Isolation
Even in passthrough mode:
* **Creates**: `meta.tag` with your tenant ID is automatically injected
* **Searches**: `_tag` filter is automatically appended
* **Reads/Updates/Deletes**: ownership is verified
You cannot bypass tenant isolation.
# Patch (FHIR)
Source: https://docs.clinikapi.com/api-reference/fhir/patch
patch /v1/fhir/{path}
Update a FHIR R4 resource using JSON Patch.
## Patch a FHIR Resource
```bash theme={null}
curl -X PATCH https://api.clinikapi.com/v1/fhir/Patient/pt_abc123 \
-H "x-api-key: clk_live_abc123" \
-H "Content-Type: application/json-patch+json" \
-d '[
{ "op": "replace", "path": "/name/0/family", "value": "Johnson" },
{ "op": "add", "path": "/telecom/-", "value": { "system": "phone", "value": "+1-555-0200" } }
]'
```
Uses standard [JSON Patch (RFC 6902)](https://datatracker.ietf.org/doc/html/rfc6902) operations.
# Read (FHIR)
Source: https://docs.clinikapi.com/api-reference/fhir/read
get /v1/fhir/{path}
Read a raw FHIR R4 resource by type and ID.
## Read a FHIR Resource
```bash theme={null}
curl https://api.clinikapi.com/v1/fhir/Patient/pt_abc123 \
-H "x-api-key: clk_live_abc123"
```
Returns the raw FHIR R4 resource:
```json theme={null}
{
"resourceType": "Patient",
"id": "pt_abc123",
"meta": {
"tag": [{ "system": "https://clinikapi.com/tenant", "code": "org_def456" }]
},
"name": [{ "family": "Doe", "given": ["Jane"] }],
"gender": "female",
"birthDate": "1990-03-15"
}
```
# Create Goal
Source: https://docs.clinikapi.com/api-reference/goals/create
post /v1/goals
# Delete Goal
Source: https://docs.clinikapi.com/api-reference/goals/delete
delete /v1/goals/{id}
# Read Goal
Source: https://docs.clinikapi.com/api-reference/goals/read
get /v1/goals/{id}
# Search Goals
Source: https://docs.clinikapi.com/api-reference/goals/search
get /v1/goals
# Update Goal
Source: https://docs.clinikapi.com/api-reference/goals/update
patch /v1/goals/{id}
# Create Healthcare Service
Source: https://docs.clinikapi.com/api-reference/healthcare-services/create
post /v1/healthcare-services
# Delete Healthcare Service
Source: https://docs.clinikapi.com/api-reference/healthcare-services/delete
delete /v1/healthcare-services/{id}
# Read Healthcare Service
Source: https://docs.clinikapi.com/api-reference/healthcare-services/read
get /v1/healthcare-services/{id}
# Search Healthcare Services
Source: https://docs.clinikapi.com/api-reference/healthcare-services/search
get /v1/healthcare-services
# Update Healthcare Service
Source: https://docs.clinikapi.com/api-reference/healthcare-services/update
patch /v1/healthcare-services/{id}
# Create Imaging Study
Source: https://docs.clinikapi.com/api-reference/imaging-studies/create
post /v1/imaging-studies
# Delete Imaging Study
Source: https://docs.clinikapi.com/api-reference/imaging-studies/delete
delete /v1/imaging-studies/{id}
# Read Imaging Study
Source: https://docs.clinikapi.com/api-reference/imaging-studies/read
get /v1/imaging-studies/{id}
# Search Imaging Studies
Source: https://docs.clinikapi.com/api-reference/imaging-studies/search
get /v1/imaging-studies
# Update Imaging Study
Source: https://docs.clinikapi.com/api-reference/imaging-studies/update
patch /v1/imaging-studies/{id}
# Create Immunization Evaluation
Source: https://docs.clinikapi.com/api-reference/immunization-evaluations/create
post /v1/immunization-evaluations
# Delete Immunization Evaluation
Source: https://docs.clinikapi.com/api-reference/immunization-evaluations/delete
delete /v1/immunization-evaluations/{id}
# Read Immunization Evaluation
Source: https://docs.clinikapi.com/api-reference/immunization-evaluations/read
get /v1/immunization-evaluations/{id}
# Search Immunization Evaluations
Source: https://docs.clinikapi.com/api-reference/immunization-evaluations/search
get /v1/immunization-evaluations
# Update Immunization Evaluation
Source: https://docs.clinikapi.com/api-reference/immunization-evaluations/update
patch /v1/immunization-evaluations/{id}
# Create Immunization Recommendation
Source: https://docs.clinikapi.com/api-reference/immunization-recommendations/create
post /v1/immunization-recommendations
# Delete Immunization Recommendation
Source: https://docs.clinikapi.com/api-reference/immunization-recommendations/delete
delete /v1/immunization-recommendations/{id}
# Read Immunization Recommendation
Source: https://docs.clinikapi.com/api-reference/immunization-recommendations/read
get /v1/immunization-recommendations/{id}
# Search Immunization Recommendations
Source: https://docs.clinikapi.com/api-reference/immunization-recommendations/search
get /v1/immunization-recommendations
# Create Immunization
Source: https://docs.clinikapi.com/api-reference/immunizations/create
post /v1/immunizations
# Delete Immunization
Source: https://docs.clinikapi.com/api-reference/immunizations/delete
delete /v1/immunizations/{id}
# Read Immunization
Source: https://docs.clinikapi.com/api-reference/immunizations/read
get /v1/immunizations/{id}
# Search Immunizations
Source: https://docs.clinikapi.com/api-reference/immunizations/search
get /v1/immunizations
# Update Immunization
Source: https://docs.clinikapi.com/api-reference/immunizations/update
patch /v1/immunizations/{id}
# Submit Intake
Source: https://docs.clinikapi.com/api-reference/intakes/create
post /v1/intakes
# Delete Intake
Source: https://docs.clinikapi.com/api-reference/intakes/delete
delete /v1/intakes/{id}
# Read Intake
Source: https://docs.clinikapi.com/api-reference/intakes/read
get /v1/intakes/{id}
# Search Intakes
Source: https://docs.clinikapi.com/api-reference/intakes/search
get /v1/intakes
# Update Intake
Source: https://docs.clinikapi.com/api-reference/intakes/update
patch /v1/intakes/{id}
# Create Invoice
Source: https://docs.clinikapi.com/api-reference/invoices/create
post /v1/invoices
# Delete Invoice
Source: https://docs.clinikapi.com/api-reference/invoices/delete
delete /v1/invoices/{id}
# Read Invoice
Source: https://docs.clinikapi.com/api-reference/invoices/read
get /v1/invoices/{id}
# Search Invoices
Source: https://docs.clinikapi.com/api-reference/invoices/search
get /v1/invoices
# Update Invoice
Source: https://docs.clinikapi.com/api-reference/invoices/update
patch /v1/invoices/{id}
# Create Lab Report
Source: https://docs.clinikapi.com/api-reference/labs/create
post /v1/labs
# Delete Lab Report
Source: https://docs.clinikapi.com/api-reference/labs/delete
delete /v1/labs/{id}
# Read Lab Report
Source: https://docs.clinikapi.com/api-reference/labs/read
get /v1/labs/{id}
# Search Lab Reports
Source: https://docs.clinikapi.com/api-reference/labs/search
get /v1/labs
# Update Lab Report
Source: https://docs.clinikapi.com/api-reference/labs/update
patch /v1/labs/{id}
# Create Location
Source: https://docs.clinikapi.com/api-reference/locations/create
post /v1/locations
# Delete Location
Source: https://docs.clinikapi.com/api-reference/locations/delete
delete /v1/locations/{id}
# Read Location
Source: https://docs.clinikapi.com/api-reference/locations/read
get /v1/locations/{id}
# Search Locations
Source: https://docs.clinikapi.com/api-reference/locations/search
get /v1/locations
# Update Location
Source: https://docs.clinikapi.com/api-reference/locations/update
patch /v1/locations/{id}
# Create Measure Report
Source: https://docs.clinikapi.com/api-reference/measure-reports/create
post /v1/measure-reports
# Delete Measure Report
Source: https://docs.clinikapi.com/api-reference/measure-reports/delete
delete /v1/measure-reports/{id}
# Read Measure Report
Source: https://docs.clinikapi.com/api-reference/measure-reports/read
get /v1/measure-reports/{id}
# Search Measure Reports
Source: https://docs.clinikapi.com/api-reference/measure-reports/search
get /v1/measure-reports
# Update Measure Report
Source: https://docs.clinikapi.com/api-reference/measure-reports/update
patch /v1/measure-reports/{id}
# Create Measure
Source: https://docs.clinikapi.com/api-reference/measures/create
post /v1/measures
# Delete Measure
Source: https://docs.clinikapi.com/api-reference/measures/delete
delete /v1/measures/{id}
# Read Measure
Source: https://docs.clinikapi.com/api-reference/measures/read
get /v1/measures/{id}
# Search Measures
Source: https://docs.clinikapi.com/api-reference/measures/search
get /v1/measures
# Update Measure
Source: https://docs.clinikapi.com/api-reference/measures/update
patch /v1/measures/{id}
# Create Media
Source: https://docs.clinikapi.com/api-reference/media/create
post /v1/media
# Delete Media
Source: https://docs.clinikapi.com/api-reference/media/delete
delete /v1/media/{id}
# Read Media
Source: https://docs.clinikapi.com/api-reference/media/read
get /v1/media/{id}
# Search Media
Source: https://docs.clinikapi.com/api-reference/media/search
get /v1/media
# Update Media
Source: https://docs.clinikapi.com/api-reference/media/update
patch /v1/media/{id}
# Create Medication Dispense
Source: https://docs.clinikapi.com/api-reference/medication-dispenses/create
post /v1/medication-dispenses
# Delete Medication Dispense
Source: https://docs.clinikapi.com/api-reference/medication-dispenses/delete
delete /v1/medication-dispenses/{id}
# Read Medication Dispense
Source: https://docs.clinikapi.com/api-reference/medication-dispenses/read
get /v1/medication-dispenses/{id}
# Search Medication Dispenses
Source: https://docs.clinikapi.com/api-reference/medication-dispenses/search
get /v1/medication-dispenses
# Update Medication Dispense
Source: https://docs.clinikapi.com/api-reference/medication-dispenses/update
patch /v1/medication-dispenses/{id}
# Create Medication Knowledge
Source: https://docs.clinikapi.com/api-reference/medication-knowledge/create
post /v1/medication-knowledge
# Delete Medication Knowledge
Source: https://docs.clinikapi.com/api-reference/medication-knowledge/delete
delete /v1/medication-knowledge/{id}
# Read Medication Knowledge
Source: https://docs.clinikapi.com/api-reference/medication-knowledge/read
get /v1/medication-knowledge/{id}
# Search Medication Knowledge
Source: https://docs.clinikapi.com/api-reference/medication-knowledge/search
get /v1/medication-knowledge
# Update Medication Knowledge
Source: https://docs.clinikapi.com/api-reference/medication-knowledge/update
patch /v1/medication-knowledge/{id}
# Create Medication Statement
Source: https://docs.clinikapi.com/api-reference/medication-statements/create
post /v1/medication-statements
# Delete Medication Statement
Source: https://docs.clinikapi.com/api-reference/medication-statements/delete
delete /v1/medication-statements/{id}
# Read Medication Statement
Source: https://docs.clinikapi.com/api-reference/medication-statements/read
get /v1/medication-statements/{id}
# Search Medication Statements
Source: https://docs.clinikapi.com/api-reference/medication-statements/search
get /v1/medication-statements
# Update Medication Statement
Source: https://docs.clinikapi.com/api-reference/medication-statements/update
patch /v1/medication-statements/{id}
# Create Medication
Source: https://docs.clinikapi.com/api-reference/medications/create
post /v1/medications
# Delete Medication
Source: https://docs.clinikapi.com/api-reference/medications/delete
delete /v1/medications/{id}
# Read Medication
Source: https://docs.clinikapi.com/api-reference/medications/read
get /v1/medications/{id}
# Search Medications
Source: https://docs.clinikapi.com/api-reference/medications/search
get /v1/medications
# Update Medication
Source: https://docs.clinikapi.com/api-reference/medications/update
patch /v1/medications/{id}
# Create Note
Source: https://docs.clinikapi.com/api-reference/notes/create
post /v1/notes
# Delete Note
Source: https://docs.clinikapi.com/api-reference/notes/delete
delete /v1/notes/{id}
# Read Note
Source: https://docs.clinikapi.com/api-reference/notes/read
get /v1/notes/{id}
# Search Notes
Source: https://docs.clinikapi.com/api-reference/notes/search
get /v1/notes
# Update Note
Source: https://docs.clinikapi.com/api-reference/notes/update
patch /v1/notes/{id}
# Create Nutrition Order
Source: https://docs.clinikapi.com/api-reference/nutrition-orders/create
post /v1/nutrition-orders
# Delete Nutrition Order
Source: https://docs.clinikapi.com/api-reference/nutrition-orders/delete
delete /v1/nutrition-orders/{id}
# Read Nutrition Order
Source: https://docs.clinikapi.com/api-reference/nutrition-orders/read
get /v1/nutrition-orders/{id}
# Search Nutrition Orders
Source: https://docs.clinikapi.com/api-reference/nutrition-orders/search
get /v1/nutrition-orders
# Update Nutrition Order
Source: https://docs.clinikapi.com/api-reference/nutrition-orders/update
patch /v1/nutrition-orders/{id}
# Create Observation
Source: https://docs.clinikapi.com/api-reference/observations/create
post /v1/observations
# Delete Observation
Source: https://docs.clinikapi.com/api-reference/observations/delete
delete /v1/observations/{id}
# Read Observation
Source: https://docs.clinikapi.com/api-reference/observations/read
get /v1/observations/{id}
# Search Observations
Source: https://docs.clinikapi.com/api-reference/observations/search
get /v1/observations
# Update Observation
Source: https://docs.clinikapi.com/api-reference/observations/update
patch /v1/observations/{id}
# Create Organization
Source: https://docs.clinikapi.com/api-reference/organizations/create
post /v1/organizations
# Delete Organization
Source: https://docs.clinikapi.com/api-reference/organizations/delete
delete /v1/organizations/{id}
# Read Organization
Source: https://docs.clinikapi.com/api-reference/organizations/read
get /v1/organizations/{id}
# Search Organizations
Source: https://docs.clinikapi.com/api-reference/organizations/search
get /v1/organizations
# Update Organization
Source: https://docs.clinikapi.com/api-reference/organizations/update
patch /v1/organizations/{id}
# API Reference Overview
Source: https://docs.clinikapi.com/api-reference/overview
REST API endpoints, authentication, and response format.
# API Reference
The ClinikAPI REST API provides CRUD + search operations for 14 FHIR R4 resource types, plus bulk operations and a FHIR passthrough.
## Base URL
```
https://api.clinikapi.com
```
## Authentication
All endpoints (except `/health` and `/v1/metadata`) require an API key:
```bash theme={null}
curl -H "x-api-key: clk_live_abc123" https://api.clinikapi.com/v1/patients
```
## Response Envelope
Every response is wrapped in:
```json theme={null}
{
"data": { ... },
"meta": {
"requestId": "req_k8f3a7x2",
"timestamp": "2025-01-15T09:15:00.000Z",
"status": 200,
"rateLimitTotal": 500,
"rateLimitRemaining": 498,
"rateLimitReset": 3600
}
}
```
## Pagination
List endpoints return paginated results:
```json theme={null}
{
"data": {
"data": [ ... ],
"total": 150,
"cursor": "20",
"hasMore": true
}
}
```
Use `count` (default: 20, max: 100) and `cursor` query parameters to paginate.
`count` is clamped rather than rejected: a value above 100 returns 100, and a
missing, zero, negative or non-numeric value returns the default 20. A `cursor`
that isn't a positive number starts from the beginning. Read `hasMore` and the
returned `cursor` rather than assuming you got the page size you asked for.
## Content Types
| Header | Value |
| - | - |
| Request body | `application/json` |
| PATCH body | `application/json-patch+json` |
| FHIR passthrough | `application/fhir+json` |
## Endpoints
| Method | Path | Description |
| - | - | - |
| `GET` | `/health` | Health check (no auth) |
| `GET` | `/v1/metadata` | FHIR CapabilityStatement (no auth) |
| `POST` | `/v1/{resource}` | Create a resource |
| `GET` | `/v1/{resource}` | Search resources |
| `GET` | `/v1/{resource}/{id}` | Read a resource |
| `PATCH` | `/v1/{resource}/{id}` | Update a resource |
| `DELETE` | `/v1/{resource}/{id}` | Delete a resource |
| `POST` | `/v1/bulk/export` | Start bulk export |
| `POST` | `/v1/bulk/import` | Start bulk import |
| `GET` | `/v1/bulk/jobs/{jobId}` | Check bulk job status |
| `*` | `/v1/fhir/{path}` | FHIR passthrough |
### Resource Paths
| Path | FHIR Type |
| - | - |
| `/v1/patients` | Patient |
| `/v1/practitioners` | Practitioner |
| `/v1/practitioner-roles` | PractitionerRole |
| `/v1/encounters` | Encounter |
| `/v1/observations` | Observation |
| `/v1/medications` | Medication |
| `/v1/prescriptions` | MedicationRequest |
| `/v1/appointments` | Appointment |
| `/v1/intakes` | QuestionnaireResponse |
| `/v1/consents` | Consent |
| `/v1/labs` | DiagnosticReport |
| `/v1/notes` | DocumentReference |
| `/v1/assessments` | ClinicalImpression |
| `/v1/documents` | Composition |
# Create Patient
Source: https://docs.clinikapi.com/api-reference/patients/create
post /v1/patients
# Delete Patient
Source: https://docs.clinikapi.com/api-reference/patients/delete
delete /v1/patients/{id}
# Read Patient
Source: https://docs.clinikapi.com/api-reference/patients/read
get /v1/patients/{id}
# Search Patients
Source: https://docs.clinikapi.com/api-reference/patients/search
get /v1/patients
# Update Patient
Source: https://docs.clinikapi.com/api-reference/patients/update
patch /v1/patients/{id}
# Create Payment Notice
Source: https://docs.clinikapi.com/api-reference/payment-notices/create
post /v1/payment-notices
# Delete Payment Notice
Source: https://docs.clinikapi.com/api-reference/payment-notices/delete
delete /v1/payment-notices/{id}
# Read Payment Notice
Source: https://docs.clinikapi.com/api-reference/payment-notices/read
get /v1/payment-notices/{id}
# Search Payment Notices
Source: https://docs.clinikapi.com/api-reference/payment-notices/search
get /v1/payment-notices
# Update Payment Notice
Source: https://docs.clinikapi.com/api-reference/payment-notices/update
patch /v1/payment-notices/{id}
# Create Payment Reconciliation
Source: https://docs.clinikapi.com/api-reference/payment-reconciliations/create
post /v1/payment-reconciliations
# Delete Payment Reconciliation
Source: https://docs.clinikapi.com/api-reference/payment-reconciliations/delete
delete /v1/payment-reconciliations/{id}
# Read Payment Reconciliation
Source: https://docs.clinikapi.com/api-reference/payment-reconciliations/read
get /v1/payment-reconciliations/{id}
# Search Payment Reconciliations
Source: https://docs.clinikapi.com/api-reference/payment-reconciliations/search
get /v1/payment-reconciliations
# Update Payment Reconciliation
Source: https://docs.clinikapi.com/api-reference/payment-reconciliations/update
patch /v1/payment-reconciliations/{id}
# Create Person
Source: https://docs.clinikapi.com/api-reference/persons/create
post /v1/persons
# Delete Person
Source: https://docs.clinikapi.com/api-reference/persons/delete
delete /v1/persons/{id}
# Read Person
Source: https://docs.clinikapi.com/api-reference/persons/read
get /v1/persons/{id}
# Search Persons
Source: https://docs.clinikapi.com/api-reference/persons/search
get /v1/persons
# Update Person
Source: https://docs.clinikapi.com/api-reference/persons/update
patch /v1/persons/{id}
# Create Plan Definition
Source: https://docs.clinikapi.com/api-reference/plan-definitions/create
post /v1/plan-definitions
# Delete Plan Definition
Source: https://docs.clinikapi.com/api-reference/plan-definitions/delete
delete /v1/plan-definitions/{id}
# Read Plan Definition
Source: https://docs.clinikapi.com/api-reference/plan-definitions/read
get /v1/plan-definitions/{id}
# Search Plan Definitions
Source: https://docs.clinikapi.com/api-reference/plan-definitions/search
get /v1/plan-definitions
# Update Plan Definition
Source: https://docs.clinikapi.com/api-reference/plan-definitions/update
patch /v1/plan-definitions/{id}
# Create Practitioner Role
Source: https://docs.clinikapi.com/api-reference/practitioner-roles/create
post /v1/practitioner-roles
# Delete Practitioner Role
Source: https://docs.clinikapi.com/api-reference/practitioner-roles/delete
delete /v1/practitioner-roles/{id}
# Read Practitioner Role
Source: https://docs.clinikapi.com/api-reference/practitioner-roles/read
get /v1/practitioner-roles/{id}
# Search Practitioner Roles
Source: https://docs.clinikapi.com/api-reference/practitioner-roles/search
get /v1/practitioner-roles
# Update Practitioner Role
Source: https://docs.clinikapi.com/api-reference/practitioner-roles/update
patch /v1/practitioner-roles/{id}
# Create Practitioner
Source: https://docs.clinikapi.com/api-reference/practitioners/create
post /v1/practitioners
# Delete Practitioner
Source: https://docs.clinikapi.com/api-reference/practitioners/delete
delete /v1/practitioners/{id}
# Read Practitioner
Source: https://docs.clinikapi.com/api-reference/practitioners/read
get /v1/practitioners/{id}
# Search Practitioners
Source: https://docs.clinikapi.com/api-reference/practitioners/search
get /v1/practitioners
# Update Practitioner
Source: https://docs.clinikapi.com/api-reference/practitioners/update
patch /v1/practitioners/{id}
# Create Prescription
Source: https://docs.clinikapi.com/api-reference/prescriptions/create
post /v1/prescriptions
# Delete Prescription
Source: https://docs.clinikapi.com/api-reference/prescriptions/delete
delete /v1/prescriptions/{id}
# Read Prescription
Source: https://docs.clinikapi.com/api-reference/prescriptions/read
get /v1/prescriptions/{id}
# Search Prescriptions
Source: https://docs.clinikapi.com/api-reference/prescriptions/search
get /v1/prescriptions
# Update Prescription
Source: https://docs.clinikapi.com/api-reference/prescriptions/update
patch /v1/prescriptions/{id}
# Create Risk Assessment
Source: https://docs.clinikapi.com/api-reference/risk-assessments/create
post /v1/risk-assessments
# Delete Risk Assessment
Source: https://docs.clinikapi.com/api-reference/risk-assessments/delete
delete /v1/risk-assessments/{id}
# Read Risk Assessment
Source: https://docs.clinikapi.com/api-reference/risk-assessments/read
get /v1/risk-assessments/{id}
# Search Risk Assessments
Source: https://docs.clinikapi.com/api-reference/risk-assessments/search
get /v1/risk-assessments
# Update Risk Assessment
Source: https://docs.clinikapi.com/api-reference/risk-assessments/update
patch /v1/risk-assessments/{id}
# Create Schedule
Source: https://docs.clinikapi.com/api-reference/schedules/create
post /v1/schedules
# Delete Schedule
Source: https://docs.clinikapi.com/api-reference/schedules/delete
delete /v1/schedules/{id}
# Read Schedule
Source: https://docs.clinikapi.com/api-reference/schedules/read
get /v1/schedules/{id}
# Search Schedules
Source: https://docs.clinikapi.com/api-reference/schedules/search
get /v1/schedules
# Update Schedule
Source: https://docs.clinikapi.com/api-reference/schedules/update
patch /v1/schedules/{id}
# Create Service Request
Source: https://docs.clinikapi.com/api-reference/service-requests/create
post /v1/service-requests
# Delete Service Request
Source: https://docs.clinikapi.com/api-reference/service-requests/delete
delete /v1/service-requests/{id}
# Read Service Request
Source: https://docs.clinikapi.com/api-reference/service-requests/read
get /v1/service-requests/{id}
# Search Service Requests
Source: https://docs.clinikapi.com/api-reference/service-requests/search
get /v1/service-requests
# Update Service Request
Source: https://docs.clinikapi.com/api-reference/service-requests/update
patch /v1/service-requests/{id}
# Create Slot
Source: https://docs.clinikapi.com/api-reference/slots/create
post /v1/slots
# Delete Slot
Source: https://docs.clinikapi.com/api-reference/slots/delete
delete /v1/slots/{id}
# Read Slot
Source: https://docs.clinikapi.com/api-reference/slots/read
get /v1/slots/{id}
# Search Slots
Source: https://docs.clinikapi.com/api-reference/slots/search
get /v1/slots
# Update Slot
Source: https://docs.clinikapi.com/api-reference/slots/update
patch /v1/slots/{id}
# Create Specimen
Source: https://docs.clinikapi.com/api-reference/specimens/create
post /v1/specimens
# Delete Specimen
Source: https://docs.clinikapi.com/api-reference/specimens/delete
delete /v1/specimens/{id}
# Read Specimen
Source: https://docs.clinikapi.com/api-reference/specimens/read
get /v1/specimens/{id}
# Search Specimens
Source: https://docs.clinikapi.com/api-reference/specimens/search
get /v1/specimens
# Update Specimen
Source: https://docs.clinikapi.com/api-reference/specimens/update
patch /v1/specimens/{id}
# Create Task
Source: https://docs.clinikapi.com/api-reference/tasks/create
post /v1/tasks
# Delete Task
Source: https://docs.clinikapi.com/api-reference/tasks/delete
delete /v1/tasks/{id}
# Read Task
Source: https://docs.clinikapi.com/api-reference/tasks/read
get /v1/tasks/{id}
# Search Tasks
Source: https://docs.clinikapi.com/api-reference/tasks/search
get /v1/tasks
# Update Task
Source: https://docs.clinikapi.com/api-reference/tasks/update
patch /v1/tasks/{id}
# Create Vision Prescription
Source: https://docs.clinikapi.com/api-reference/vision-prescriptions/create
post /v1/vision-prescriptions
# Delete Vision Prescription
Source: https://docs.clinikapi.com/api-reference/vision-prescriptions/delete
delete /v1/vision-prescriptions/{id}
# Read Vision Prescription
Source: https://docs.clinikapi.com/api-reference/vision-prescriptions/read
get /v1/vision-prescriptions/{id}
# Search Vision Prescriptions
Source: https://docs.clinikapi.com/api-reference/vision-prescriptions/search
get /v1/vision-prescriptions
# Update Vision Prescription
Source: https://docs.clinikapi.com/api-reference/vision-prescriptions/update
patch /v1/vision-prescriptions/{id}
# Authentication
Source: https://docs.clinikapi.com/authentication
API key authentication, tenant isolation, and multi-datastore routing.
# Authentication
ClinikAPI uses API key authentication via the `x-api-key` header. Every request must include a valid key.
## API Keys
Keys are created in the [Developer Dashboard](https://dashboard.clinikapi.com) and follow this format:
| Format | Environment | Use Case |
| - | - | - |
| `clk_test_*` | Test | Development, staging, CI/CD |
| `clk_live_*` | Production | Live patient data |
```bash theme={null}
curl -X GET https://api.clinikapi.com/v1/patients \
-H "x-api-key: clk_test_abc123def456"
```
```ts theme={null}
import { Clinik } from '@clinikapi/sdk';
const clinik = new Clinik(process.env.CLINIKAPI_SECRET_KEY!);
```
## ClinikAPI is a Data API
ClinikAPI does **not** handle end-user authentication. You bring your own auth provider (Clerk, Auth0, Firebase, etc.) and use ClinikAPI purely for clinical data storage and retrieval.
```
Patient (browser) → Your Auth (Clerk/Auth0) → Your Backend → ClinikAPI SDK → ClinikAPI
```
The SDK runs on your server. Your backend authenticates the end user, then calls ClinikAPI with your secret key.
## Tenant Isolation
Every resource stored in ClinikAPI is tagged with your organization's tenant ID:
```json theme={null}
{
"meta": {
"tag": [
{
"system": "https://clinikapi.com/tenant",
"code": "org_abc123"
}
]
}
}
```
* **On create**: the tenant tag is automatically injected
* **On search**: a `_tag` filter is automatically applied — you can only see your own data
* **On read/update/delete**: ownership is verified before the operation proceeds
There is no way to access another tenant's data through the API.
## Multi-Datastore Routing
Requests are routed to different datastores based on your key and plan:
| Key Type | Plan | Datastore |
| - | - | - |
| `clk_test_*` | Any | Shared test datastore |
| `clk_live_*` | Sandbox / Starter / Pro / Team | Shared production datastore |
| `clk_live_*` | Enterprise | Dedicated datastore |
Enterprise customers get a fully isolated datastore provisioned in their preferred region.
## Key Validation Flow
For minimal latency, API keys are validated against a co-located PostgreSQL database that mirrors your dashboard data:
1. You create/revoke keys in the Dashboard
2. Key changes are automatically synced to the co-located database
3. The API validates keys locally — no cross-region round trips
Keys are cached for 60 seconds to minimize database lookups.
## Key Scopes
API keys can be scoped to specific permissions:
* `read` — GET operations only
* `write` — POST, PATCH, DELETE operations
* `*` — full access (default)
Scopes are set when creating the key in the Dashboard.
## Security Best Practices
Never expose your API key in client-side code, Git repositories, or logs.
* Store keys in environment variables (`CLINIKAPI_SECRET_KEY`)
* Use `clk_test_*` keys for development — they route to an isolated test datastore
* Rotate keys periodically from the Dashboard
* Use scoped keys when possible (e.g., read-only for analytics services)
* For client-side UI, use `@clinikapi/react` with the [proxy pattern](/components/overview)
# AllergyRecorder
Source: https://docs.clinikapi.com/components/allergy-recorder
Record patient allergies and intolerances with reaction details.
# AllergyRecorder
Record patient allergies and intolerances as FHIR AllergyIntolerance resources. Supports allergen categorization, criticality levels, and detailed reaction tracking.
## Usage
```tsx theme={null}
import { AllergyRecorder } from '@clinikapi/react';
```
## Props
| Prop | Type | Required | Description |
| - | - | - | - |
| `proxyUrl` | `string` | Yes | Backend proxy URL |
| `patientId` | `string` | Yes | Patient ID |
| `theme` | `'light' \| 'dark'` | No | Color theme |
## Form Fields
| Field | Description |
| - | - |
| Code | Allergen name (e.g. "Penicillin", "Peanuts") |
| Type | allergy, intolerance |
| Category | food, medication, environment, biologic |
| Criticality | low, high |
| Clinical status | active, inactive, resolved |
| Reaction manifestation | Observed reaction (e.g. "Hives", "Anaphylaxis") |
| Reaction severity | mild, moderate, severe |
## Categories
| Category | Description |
| - | - |
| `food` | Food allergens (e.g. peanuts, shellfish) |
| `medication` | Drug allergens (e.g. penicillin, sulfa) |
| `environment` | Environmental allergens (e.g. pollen, dust) |
| `biologic` | Biologic substances (e.g. vaccines, blood products) |
## Proxy Action
The widget sends `allergies.create` with:
```json theme={null}
{
"action": "allergies.create",
"data": {
"patientId": "pt_abc123",
"code": "Penicillin",
"type": "allergy",
"category": ["medication"],
"criticality": "high",
"clinicalStatus": "active",
"reaction": [
{
"manifestation": ["Anaphylaxis"],
"severity": "severe"
}
]
}
}
```
# AppointmentScheduler
Source: https://docs.clinikapi.com/components/appointment-scheduler
Book and manage patient appointments with service type, specialty, and priority.
# AppointmentScheduler
A scheduling widget for creating patient appointments with full FHIR R4 field support.
## Usage
```tsx theme={null}
import { AppointmentScheduler } from '@clinikapi/react';
```
## Props
| Prop | Type | Required | Description |
| - | - | - | - |
| `proxyUrl` | `string` | Yes | Backend proxy URL |
| `patientId` | `string` | Yes | Patient ID |
| `practitionerId` | `string` | No | Default practitioner |
| `theme` | `'light' \| 'dark'` | No | Color theme |
## Form Fields
The scheduler collects:
| Field | Description |
| - | - |
| Date & Time | Appointment start time |
| Duration | 15, 30, 45, 60, or 90 minutes |
| Appointment type | Routine, follow-up, urgent, walk-in, check-up |
| Service type | What service is being booked (e.g. "Cardiology consultation") |
| Specialty | Required specialty (e.g. "Cardiology", "Dermatology") |
| Priority | Routine (0), low (1), medium (5), high (9) urgency |
| Description | Subject line for the appointment |
| Reason | Reason for the visit |
| Patient instructions | Instructions for the patient (e.g. "Fast for 12 hours") |
## Proxy Action
The widget sends `appointments.create` with:
```json theme={null}
{
"action": "appointments.create",
"data": {
"status": "booked",
"patientId": "pt_abc123",
"practitionerId": "prac_def456",
"start": "2025-02-01T14:00:00Z",
"end": "2025-02-01T14:30:00Z",
"minutesDuration": 30,
"appointmentType": "followup",
"serviceType": "Cardiology consultation",
"specialty": "Cardiology",
"priority": 0,
"description": "Follow-up for hypertension",
"reasonCode": "Blood pressure check",
"patientInstruction": "Bring home BP log"
}
}
```
# CarePlanBuilder
Source: https://docs.clinikapi.com/components/care-plan-builder
Create structured care plans with status, intent, and category.
# CarePlanBuilder
Create structured patient care plans as FHIR CarePlan resources. Supports plan status management, intent classification, category tagging, and optional author attribution.
## Usage
```tsx theme={null}
import { CarePlanBuilder } from '@clinikapi/react';
```
## Props
| Prop | Type | Required | Description |
| - | - | - | - |
| `proxyUrl` | `string` | Yes | Backend proxy URL |
| `patientId` | `string` | Yes | Patient ID |
| `authorId` | `string` | No | Practitioner who authored the plan |
| `theme` | `'light' \| 'dark'` | No | Color theme |
## Form Fields
| Field | Description |
| - | - |
| Title | Care plan title |
| Description | Detailed description of the care plan |
| Status | draft, active |
| Intent | plan, order |
| Category | Care plan category (e.g. "diabetes-management", "post-surgical") |
| Note | Additional clinical notes |
## Status Values
| Status | Description |
| - | - |
| `draft` | Care plan is being developed |
| `active` | Care plan is currently in effect |
## Intent Values
| Intent | Description |
| - | - |
| `plan` | A suggested care plan |
| `order` | An authoritative care plan |
## Proxy Action
The widget sends `care-plans.create` with:
```json theme={null}
{
"action": "care-plans.create",
"data": {
"patientId": "pt_abc123",
"authorId": "prac_def456",
"title": "Diabetes Management Plan",
"description": "Comprehensive plan for Type 2 diabetes management including diet, exercise, and medication adherence.",
"status": "active",
"intent": "plan",
"category": ["diabetes-management"],
"note": "Patient agreed to follow-up in 3 months"
}
}
```
# ConditionTracker
Source: https://docs.clinikapi.com/components/condition-tracker
Record conditions and diagnoses with clinical status, severity, and onset tracking.
# ConditionTracker
Record patient conditions and diagnoses as FHIR Condition resources. Supports clinical status tracking, severity levels, verification status, and onset date recording.
## Usage
```tsx theme={null}
import { ConditionTracker } from '@clinikapi/react';
```
## Props
| Prop | Type | Required | Description |
| - | - | - | - |
| `proxyUrl` | `string` | Yes | Backend proxy URL |
| `patientId` | `string` | Yes | Patient ID |
| `theme` | `'light' \| 'dark'` | No | Color theme |
## Form Fields
| Field | Description |
| - | - |
| Code | Condition name or ICD-10 code (e.g. "Hypertension", "I10") |
| Clinical status | active, inactive, resolved |
| Verification status | confirmed, unconfirmed |
| Severity | mild, moderate, severe |
| Onset date/time | When the condition started |
| Note | Additional clinical notes |
## Clinical Status Values
| Status | Description |
| - | - |
| `active` | Condition is currently active |
| `inactive` | Condition is no longer active but not resolved |
| `resolved` | Condition has been resolved |
## Proxy Action
The widget sends `conditions.create` with:
```json theme={null}
{
"action": "conditions.create",
"data": {
"patientId": "pt_abc123",
"code": "Hypertension",
"clinicalStatus": "active",
"verificationStatus": "confirmed",
"severity": "moderate",
"onsetDateTime": "2025-01-15T10:00:00Z",
"note": "Patient reports elevated blood pressure over the past 3 months"
}
}
```
# ConsentManager
Source: https://docs.clinikapi.com/components/consent-manager
Consent signing and management widget with scope, verification, and provisions.
# ConsentManager
A widget for displaying, signing, and managing patient consent documents. Supports all four FHIR consent scopes, multiple verifications, and provision rules.
## Usage
```tsx theme={null}
import { ConsentManager } from '@clinikapi/react';
```
## Props
| Prop | Type | Required | Description |
| - | - | - | - |
| `proxyUrl` | `string` | Yes | Backend proxy URL |
| `patientId` | `string` | Yes | Patient ID |
| `theme` | `'light' \| 'dark'` | No | Color theme |
## Consent Scopes
| Scope | Description |
| - | - |
| `patient-privacy` | Privacy and data sharing (HIPAA notices) |
| `research` | Research participation |
| `treatment` | Treatment consent |
| `adr` | Advance directive |
## Features
* Consent document display with scope and category
* Digital signature capture
* Status tracking (draft → proposed → active → rejected → inactive)
* Multiple verification entries
* Policy URI linking
* Provision rules (permit/deny) with nested exceptions
* Source document attachment support
## Proxy Action
The widget sends `consents.sign` with:
```json theme={null}
{
"action": "consents.sign",
"data": {
"patientId": "pt_abc123",
"status": "active",
"scope": "patient-privacy",
"category": "hipaa-notice",
"policyRule": "hipaa-auth"
}
}
```
Every Consent must carry a `policyRule` or a `policyUri` — FHIR invariant
ppc-1 rejects one that has neither. Pass your own policy reference from the
proxy if `hipaa-auth` isn't the right identifier for your organization.
## Advanced: Provisions with Data Control
For more complex consent scenarios, your proxy can pass full provision rules:
```json theme={null}
{
"provision": {
"type": "permit",
"period": { "start": "2025-01-01", "end": "2025-12-31" },
"purpose": [{ "code": "TREAT", "display": "Treatment" }],
"action": [{ "code": "access", "display": "Access" }],
"data": [
{ "meaning": "instance", "reference": "DiagnosticReport/lab_001" }
]
}
}
```
# GoalSetter
Source: https://docs.clinikapi.com/components/goal-setter
Set and track patient goals with lifecycle status, achievement tracking, and target dates.
# GoalSetter
Set and track patient goals as FHIR Goal resources. Supports lifecycle status management, achievement tracking, priority levels, and target date scheduling.
## Usage
```tsx theme={null}
import { GoalSetter } from '@clinikapi/react';
```
## Props
| Prop | Type | Required | Description |
| - | - | - | - |
| `proxyUrl` | `string` | Yes | Backend proxy URL |
| `patientId` | `string` | Yes | Patient ID |
| `expressedById` | `string` | No | Who expressed the goal (practitioner or patient) |
| `theme` | `'light' \| 'dark'` | No | Color theme |
## Form Fields
| Field | Description |
| - | - |
| Description | Goal description (e.g. "Reduce HbA1c to below 7%") |
| Lifecycle status | proposed, accepted, active, completed, cancelled |
| Achievement status | in-progress, improving, worsening, no-change, achieved, not-achieved |
| Priority | high-priority, medium-priority, low-priority |
| Start date | When to begin working toward the goal |
| Target due date | Target date for goal achievement |
| Note | Additional notes about the goal |
## Lifecycle Status Values
| Status | Description |
| - | - |
| `proposed` | Goal has been suggested |
| `accepted` | Goal has been accepted by the patient |
| `active` | Goal is being actively pursued |
| `completed` | Goal tracking is complete |
| `cancelled` | Goal has been cancelled |
## Achievement Status Values
| Status | Description |
| - | - |
| `in-progress` | Goal is being worked on |
| `improving` | Progress is being made |
| `worsening` | Moving away from the goal |
| `no-change` | No progress detected |
| `achieved` | Goal has been met |
| `not-achieved` | Goal was not met |
## Proxy Action
The widget sends `goals.create` with:
```json theme={null}
{
"action": "goals.create",
"data": {
"patientId": "pt_abc123",
"expressedById": "prac_def456",
"description": "Reduce HbA1c to below 7%",
"lifecycleStatus": "active",
"achievementStatus": "in-progress",
"priority": "high-priority",
"startDate": "2025-01-15",
"target": [{ "dueDate": "2025-07-15" }],
"note": "Patient motivated to improve diabetes control through diet and exercise"
}
}
```
# ImmunizationLogger
Source: https://docs.clinikapi.com/components/immunization-logger
Log immunization records with vaccine details, lot tracking, and administration site.
# ImmunizationLogger
Log patient immunization records as FHIR Immunization resources. Supports vaccine code entry, lot number tracking, manufacturer details, and administration site recording.
## Usage
```tsx theme={null}
import { ImmunizationLogger } from '@clinikapi/react';
```
## Props
| Prop | Type | Required | Description |
| - | - | - | - |
| `proxyUrl` | `string` | Yes | Backend proxy URL |
| `patientId` | `string` | Yes | Patient ID |
| `theme` | `'light' \| 'dark'` | No | Color theme |
## Form Fields
| Field | Description |
| - | - |
| Vaccine code | Vaccine name or CVX code (e.g. "COVID-19 mRNA", "Influenza") |
| Status | completed, not-done |
| Site | Administration body site (e.g. "Left arm", "Right deltoid") |
| Route | Administration route (e.g. "Intramuscular", "Subcutaneous") |
| Lot number | Vaccine lot number for tracking |
| Manufacturer | Vaccine manufacturer name |
| Note | Additional notes about the immunization |
## Status Values
| Status | Description |
| - | - |
| `completed` | Immunization was administered |
| `not-done` | Immunization was not administered (e.g. patient refused) |
## Proxy Action
The widget sends `immunizations.create` with:
```json theme={null}
{
"action": "immunizations.create",
"data": {
"patientId": "pt_abc123",
"vaccineCode": "COVID-19 mRNA",
"status": "completed",
"site": "Left deltoid",
"route": "Intramuscular",
"lotNumber": "EW0150",
"manufacturer": "Moderna",
"note": "No adverse reactions observed"
}
}
```
# IntakeForm
Source: https://docs.clinikapi.com/components/intake-form
Patient intake questionnaire widget with structured FHIR answers.
# IntakeForm
A dynamic intake form that submits responses as FHIR QuestionnaireResponse resources. Supports all FHIR answer types including text, boolean, integer, decimal, date, time, coded values, quantities, and URIs.
## Usage
```tsx theme={null}
import { IntakeForm } from '@clinikapi/react';
```
## Props
| Prop | Type | Required | Description |
| - | - | - | - |
| `proxyUrl` | `string` | Yes | Backend proxy URL |
| `patientId` | `string` | Yes | Patient ID |
| `theme` | `'light' \| 'dark'` | No | Color theme |
## Supported Answer Types
The intake form maps to FHIR QuestionnaireResponse answer types:
| Type | Field | Example |
| - | - | - |
| Text | `valueString` | Free-text answers |
| Yes/No | `valueBoolean` | `true` / `false` |
| Integer | `valueInteger` | Whole numbers |
| Decimal | `valueDecimal` | Decimal numbers |
| Date | `valueDate` | `"2024-06-15"` |
| Date-Time | `valueDateTime` | `"2025-01-15T10:00:00Z"` |
| Time | `valueTime` | `"14:30:00"` |
| Coded | `valueCoding` | SNOMED, ICD codes |
| Measurement | `valueQuantity` | `{ value: 165, unit: "lbs" }` |
| URI | `valueUri` | External references |
## Features
* Dynamic question rendering
* Nested question groups (unlimited depth)
* Multiple answer types per question
* Auto-save as `in-progress`, submit as `completed`
* Support for `basedOn` (ServiceRequest/CarePlan references)
* Support for `partOf` (Observation/Procedure references)
## Proxy Action
The widget sends `intakes.submit` with:
```json theme={null}
{
"action": "intakes.submit",
"data": {
"patientId": "pt_abc123",
"status": "completed",
"items": [
{
"linkId": "chief-complaint",
"text": "Primary reason for visit",
"answer": [{ "valueString": "Annual physical exam" }]
},
{
"linkId": "pain-level",
"text": "Current pain level (0-10)",
"answer": [{ "valueInteger": 3 }]
}
]
}
}
```
# LabResultsWidget
Source: https://docs.clinikapi.com/components/lab-results
Lab report ordering widget with LOINC codes and category support.
# LabResultsWidget
Orders lab reports (FHIR DiagnosticReport) with LOINC coding, category classification, and effective date/period support.
## Usage
```tsx theme={null}
import { LabResultsWidget } from '@clinikapi/react';
```
## Props
| Prop | Type | Required | Description |
| - | - | - | - |
| `proxyUrl` | `string` | Yes | Backend proxy URL |
| `patientId` | `string` | Yes | Patient ID |
| `theme` | `'light' \| 'dark'` | No | Color theme |
## Features
* Lab order creation with LOINC codes
* Category classification (LAB, RAD, PAT)
* Status tracking (registered → preliminary → final)
* Support for `effectiveDateTime` and `effectivePeriod`
* `basedOn` references to ServiceRequest orders
* Media/image attachments
* Conclusion text and coded findings
* Linked observation results (`resultIds`)
* Specimen references
* Attached documents (`presentedForm`)
## Proxy Action
The widget sends `labs.create` with:
```json theme={null}
{
"action": "labs.create",
"data": {
"patientId": "pt_abc123",
"status": "preliminary",
"code": {
"system": "http://loinc.org",
"code": "24331-1",
"display": "Lipid Panel"
},
"category": "LAB",
"effectiveDateTime": "2025-01-15T10:30:00Z"
}
}
```
## Categories
| Code | Description |
| - | - |
| `LAB` | Laboratory |
| `RAD` | Radiology |
| `PAT` | Pathology |
## Reading Lab Results
For displaying lab results, your proxy should return enriched data:
```ts theme={null}
// Proxy endpoint for reading labs
const { data } = await clinik.labs.read(labId, {
include: ['Observation'],
});
// Returns: report with linked observations, conclusion, effectivePeriod, etc.
```
# NoteEditor
Source: https://docs.clinikapi.com/components/note-editor
Clinical note editor with note type, category, and practice setting.
# NoteEditor
A clinical note editor supporting multiple note types, document status management, category tagging, and practice setting.
## Usage
```tsx theme={null}
import { NoteEditor } from '@clinikapi/react';
```
## Props
| Prop | Type | Required | Description |
| - | - | - | - |
| `proxyUrl` | `string` | Yes | Backend proxy URL |
| `patientId` | `string` | Yes | Patient ID |
| `authorId` | `string` | No | Practitioner who authored the note |
| `encounterId` | `string` | No | Associated encounter |
| `theme` | `'light' \| 'dark'` | No | Color theme |
## Form Fields
| Field | Description |
| - | - |
| Note type | Progress note, consultation, discharge summary, H\&P, operative, procedure, referral, transfer summary |
| Document status | Draft (preliminary), final, amended |
| Category | Free-text category tag (e.g. "cardiology", "oncology") |
| Practice setting | Clinical specialty context (e.g. "cardiology", "family-medicine") |
| Title | Note title / description |
| Content | Clinical note content (supports plain text and markdown) |
## Note Types
| Type | LOINC Code | Description |
| - | - | - |
| `progress-note` | 11506-3 | Standard visit documentation |
| `consultation-note` | 11488-4 | Specialist consultation |
| `discharge-summary` | 18842-5 | Hospital discharge summary |
| `history-and-physical` | 34117-2 | H\&P documentation |
| `operative-note` | 11504-8 | Surgical procedure note |
| `procedure-note` | 28570-0 | Non-surgical procedure note |
| `referral-note` | 57133-1 | Referral documentation |
| `transfer-summary` | 18761-7 | Patient transfer summary |
## Proxy Action
The widget sends `notes.create` with:
```json theme={null}
{
"action": "notes.create",
"data": {
"patientId": "pt_abc123",
"authorId": "prac_def456",
"encounterId": "enc_xyz789",
"title": "Follow-up Visit - Hypertension",
"content": "## Subjective\nPatient reports...",
"type": "progress-note",
"docStatus": "final",
"category": "cardiology",
"practiceSetting": "cardiology"
}
}
```
# React Components
Source: https://docs.clinikapi.com/components/overview
Drop-in clinical UI widgets for your frontend using the proxy pattern.
# React Components
`@clinikapi/react` provides 14 pre-built clinical UI widgets that communicate through your backend proxy — never directly to ClinikAPI.
```bash theme={null}
npm install @clinikapi/react
```
Then import the stylesheet once, anywhere in your app:
```ts theme={null}
import '@clinikapi/react/styles.css';
```
That is the entire setup. The widgets are built on [shadcn/ui](https://ui.shadcn.com) + Radix, and every rule in the stylesheet is scoped to the widgets' own root element — it cannot restyle your pages, and you do not need Tailwind (or any particular build setup) to use it.
**Upgrading from 0.2.x?** The widgets were rebuilt on shadcn/ui in 0.3.0. Add the `styles.css` import above — without it they render unstyled. No component props changed.
## Theming
Widgets read a set of `--ck-*` CSS custom properties, so you can match your brand without touching component code. Values are HSL channels, the same convention shadcn/ui uses:
```css theme={null}
.clinik-root {
--ck-primary: 173 80% 40%; /* teal */
--ck-radius: 0.375rem; /* squarer corners */
}
```
Every widget also takes a `theme` prop — `'light'` (default), `'dark'`, `'glassmorphism'`, or `'inherit'`. Pass `theme="inherit"` in an app that already uses shadcn/ui and the widgets map straight onto your own `--primary` / `--border` / `--radius` variables:
```tsx theme={null}
```
This is opt-in rather than automatic, because an app that is not using shadcn/ui may define `--primary` in a different format (a hex, say), which would render the widgets incorrectly.
## The Proxy Pattern
React widgets run in the browser and cannot use the SDK directly (that would expose your API key). Instead, they talk to your backend through a `proxyUrl`:
```
Browser Widget → Your Backend Proxy → ClinikAPI SDK → ClinikAPI
```
### Setting Up a Proxy
```ts theme={null}
// Your backend (e.g. Next.js API route)
import { Clinik } from '@clinikapi/sdk';
const clinik = new Clinik(process.env.CLINIKAPI_SECRET_KEY!);
export async function POST(req: Request) {
const { action, data } = await req.json();
// Authenticate the user with YOUR auth system first
// Then proxy to ClinikAPI based on the action
switch (action) {
case 'patients.read':
return Response.json(await clinik.patients.read(data.id, { include: data.include }));
case 'patients.create':
return Response.json(await clinik.patients.create(data));
case 'appointments.create':
return Response.json(await clinik.appointments.create(data));
case 'prescriptions.create':
return Response.json(await clinik.prescriptions.create(data));
case 'notes.create':
return Response.json(await clinik.notes.create(data));
case 'intakes.submit':
return Response.json(await clinik.intakes.submit(data));
case 'consents.sign':
return Response.json(await clinik.consents.sign(data));
case 'observations.create':
return Response.json(await clinik.observations.create(data));
case 'labs.create':
return Response.json(await clinik.labs.create(data));
default:
return Response.json({ error: 'Unknown action' }, { status: 400 });
}
}
```
### Using a Widget
```tsx theme={null}
import { PatientDashboard } from '@clinikapi/react';
export default function PatientPage({ patientId }: { patientId: string }) {
return (
);
}
```
## Available Widgets
| Widget | Description | Key Fields |
| - | - | - |
| [PatientDashboard](/components/patient-dashboard) | Full patient overview with encounters, vitals, meds, labs, notes | demographics, appointments, prescriptions, labs, notes |
| [AppointmentScheduler](/components/appointment-scheduler) | Book and manage appointments | date, time, type, serviceType, specialty, priority, description |
| [PrescriptionForm](/components/prescription-form) | Create prescriptions with full dosage | medication, dosage, priority, category, courseOfTherapy, substitution |
| [NoteEditor](/components/note-editor) | Clinical note editor with type and category | title, content, type, docStatus, category, practiceSetting |
| [IntakeForm](/components/intake-form) | Patient intake questionnaire | items with nested answers (text, boolean, integer, coded, quantity) |
| [ConsentManager](/components/consent-manager) | Consent signing and management | scope, category, verification, provision |
| [VitalsWidget](/components/vitals-widget) | Vital signs recording | heart rate, blood pressure, temperature |
| [LabResultsWidget](/components/lab-results) | Lab report ordering | code, category, effectiveDateTime/Period |
| [PrescriptionWidget](/components/prescription-widget) | Quick medication entry | medication name, status |
| [ConditionTracker](/components/condition-tracker) | Record conditions and diagnoses | code, clinicalStatus, severity, onset |
| [AllergyRecorder](/components/allergy-recorder) | Record allergies and intolerances | allergen, type, category, criticality, reaction |
| [ImmunizationLogger](/components/immunization-logger) | Log immunizations | vaccine, site, route, lot number, manufacturer |
| [CarePlanBuilder](/components/care-plan-builder) | Create care plans | title, description, status, intent, category |
| [GoalSetter](/components/goal-setter) | Set patient goals | description, lifecycle, achievement, priority, target date |
## Common Props
All widgets accept:
| Prop | Type | Required | Description |
| - | - | - | - |
| `proxyUrl` | `string` | Yes | Your backend proxy endpoint (or `'demo'` for demo mode) |
| `patientId` | `string` | Yes | Patient ID |
| `theme` | `'light' \| 'dark'` | No | Color theme (default: light) |
## Demo Mode
Set `proxyUrl="demo"` to run any widget in demo mode — no backend needed, no API calls made. Useful for prototyping and showcasing.
```tsx theme={null}
```
## Security
* Widgets never receive your API key
* All data flows through your backend proxy
* You control authentication and authorization on your proxy
* `proxyUrl` is validated to prevent open redirect attacks — must be a relative path or same-origin URL
# PatientDashboard
Source: https://docs.clinikapi.com/components/patient-dashboard
Full patient overview widget with encounters, vitals, medications, labs, notes, and prescriptions.
# PatientDashboard
A comprehensive patient overview displaying demographics, appointments, lab reports, prescriptions, and clinical notes. Supports light, dark, and glassmorphism themes.
## Usage
```tsx theme={null}
import { PatientDashboard } from '@clinikapi/react';
```
## Props
| Prop | Type | Required | Description |
| - | - | - | - |
| `proxyUrl` | `string` | Yes | Backend proxy URL (or `'demo'` for demo mode) |
| `patientId` | `string` | No | Patient ID to load (if omitted, shows create form) |
| `theme` | `'light' \| 'dark' \| 'glassmorphism'` | No | Color theme |
## Views
The dashboard has three views:
1. **Create** — Patient creation form (firstName, lastName, email)
2. **Profile** — Patient overview with all related resources
3. **Edit** — Inline patient update form
## What It Displays
The profile view shows the patient's destructured FHIR bundle:
| Section | FHIR Resource | Enriched Fields |
| - | - | - |
| Patient info | Patient | name, email, photo, maritalStatus, languages, contacts |
| Appointments | Appointment | status, appointmentType, serviceType, specialty, priority, created |
| Labs & Diagnostics | DiagnosticReport | code, status, category, effectiveDateTime/Period, conclusion |
| Prescriptions | MedicationRequest | medication, status, priority, category, dosageText, courseOfTherapy |
| Clinical Notes | DocumentReference | title, docStatus, type, category, practiceSetting |
## Proxy Endpoint
Your proxy should handle the `patients.read` action with included resources:
```ts theme={null}
// Handle patients.read action
case 'patients.read':
const { data } = await clinik.patients.read(body.data.id, {
include: body.data.include || [
'Encounter', 'Observation', 'MedicationRequest',
'Appointment', 'DiagnosticReport', 'DocumentReference',
],
});
return Response.json({ data });
```
The SDK returns a `PatientReadResponse` with:
```ts theme={null}
{
patient: Patient;
encounters: Encounter[];
observations: Observation[];
medications: Medication[];
appointments: Appointment[];
intakes: QuestionnaireResponse[];
consents: Consent[];
labs: DiagnosticReport[];
prescriptions: MedicationRequest[];
notes: DocumentReference[];
assessments: ClinicalImpression[];
documents: Composition[];
}
```
## Actions
The dashboard can trigger:
* `patients.create` — Create a new patient
* `patients.read` — Load patient with included resources
* `patients.update` — Update patient demographics
* `appointments.create` — Schedule an appointment
# PrescriptionForm
Source: https://docs.clinikapi.com/components/prescription-form
Create medication prescriptions with dosage, priority, category, and course of therapy.
# PrescriptionForm
A form widget for creating medication prescriptions with full FHIR MedicationRequest field support.
## Usage
```tsx theme={null}
import { PrescriptionForm } from '@clinikapi/react';
```
## Props
| Prop | Type | Required | Description |
| - | - | - | - |
| `proxyUrl` | `string` | Yes | Backend proxy URL |
| `patientId` | `string` | Yes | Patient ID |
| `prescriberId` | `string` | No | Prescribing practitioner ID |
| `theme` | `'light' \| 'dark'` | No | Color theme |
## Form Fields
| Field | Description |
| - | - |
| Medication | Medication name or RxNorm code |
| Dosage | Human-readable dosage instructions |
| Priority | Routine, urgent, asap, stat |
| Category | Outpatient, inpatient, community, discharge |
| Frequency | Once, twice, three, or four times daily |
| Duration | Number of days |
| Quantity | Number of units to dispense |
| Refills | Number of refills (0-12) |
| Course of therapy | Continuous, acute, seasonal |
| Generic substitution | Allow/disallow generic substitution |
| Pharmacist notes | Additional notes for the pharmacist |
## Proxy Action
The widget sends `prescriptions.create` with:
```json theme={null}
{
"action": "prescriptions.create",
"data": {
"patientId": "pt_abc123",
"prescriberId": "prac_def456",
"medication": "Amoxicillin 500mg",
"status": "active",
"intent": "order",
"priority": "routine",
"category": "outpatient",
"courseOfTherapy": "acute",
"substitutionAllowed": true,
"dosageText": "Take 1 capsule three times daily",
"dosage": { "frequency": 3, "period": 7, "periodUnit": "d" },
"refills": 0,
"quantity": { "value": 21, "unit": "tablets" },
"supplyDays": 7
}
}
```
# PrescriptionWidget
Source: https://docs.clinikapi.com/components/prescription-widget
Quick medication entry widget for creating medication records.
# PrescriptionWidget
A quick-entry widget for creating medication records. For full prescription creation with dosage, priority, and category, use [PrescriptionForm](/components/prescription-form).
## Usage
```tsx theme={null}
import { PrescriptionWidget } from '@clinikapi/react';
```
## Props
| Prop | Type | Required | Description |
| - | - | - | - |
| `proxyUrl` | `string` | Yes | Backend proxy URL |
| `patientId` | `string` | Yes | Patient ID |
| `prescriberId` | `string` | No | Prescribing practitioner ID |
| `theme` | `'light' \| 'dark'` | No | Color theme |
## Features
* Quick medication name entry
* Creates a prescription (MedicationRequest) linked to the patient
* Supports free-text medication names and RxNorm codes
* Dosage, refills and priority available via PrescriptionForm or the SDK
## PrescriptionWidget vs PrescriptionForm
| Widget | Use Case |
| - | - |
| PrescriptionWidget | Quick one-field prescribing — medication name only |
| PrescriptionForm | Full prescription with dosage, priority, category, refills |
Both write a **MedicationRequest**. To add to the medication *catalog* instead,
call `medications.create` from your own backend — no widget does that.
## Proxy Action
The widget sends `prescriptions.create` with:
```json theme={null}
{
"action": "prescriptions.create",
"data": {
"patientId": "pt_abc123",
"prescriberId": "prac_def456",
"medication": "Amoxicillin 500mg",
"status": "active",
"intent": "order"
}
}
```
When `prescriberId` isn't supplied the widget sends `"unknown"`, so allowlist
the action and fill in the real prescriber from your session in the proxy.
# VitalsWidget
Source: https://docs.clinikapi.com/components/vitals-widget
Vital signs recording widget with heart rate and blood pressure input.
# VitalsWidget
Records patient vital signs as FHIR Observation resources. Supports heart rate, blood pressure, and other vital measurements with validation.
## Usage
```tsx theme={null}
import { VitalsWidget } from '@clinikapi/react';
```
## Props
| Prop | Type | Required | Description |
| - | - | - | - |
| `proxyUrl` | `string` | Yes | Backend proxy URL |
| `patientId` | `string` | Yes | Patient ID |
| `theme` | `'light' \| 'dark'` | No | Color theme |
## Form Fields
| Field | Validation | FHIR Mapping |
| - | - | - |
| Heart Rate | 20-250 bpm | Observation (LOINC 8867-4) |
| Blood Pressure | Required format | Observation (LOINC 85354-9) with systolic/diastolic components |
## Supported Observation Fields
The widget creates observations using the enriched Observation schema:
* `status` — always `final`
* `code` — LOINC vital sign code
* `patientId` — patient reference
* `category` — `vital-signs`
* `valueQuantity` — numeric value with unit
* `component` — for multi-component observations (e.g. BP systolic/diastolic)
* `interpretation` — H (high), L (low), N (normal)
* `referenceRange` — normal reference ranges
* `effectiveDateTime` — when the measurement was taken
* `issued` — when this version was made available
## Proxy Action
The widget sends `observations.create` with both readings as components of a
single vitals panel:
```json theme={null}
{
"action": "observations.create",
"data": {
"patientId": "pt_abc123",
"status": "final",
"code": "Vitals Panel",
"category": "vital-signs",
"component": [
{ "code": "Heart rate", "valueQuantity": { "value": 72, "unit": "beats/min" } },
{ "code": "Blood pressure", "valueString": "120/80 mmHg" }
]
}
}
```
To record LOINC-coded observations one per measurement instead, call
`observations.create` yourself with a `code` object and `valueQuantity` — the
schema supports both shapes.
# Data Consistency
Source: https://docs.clinikapi.com/data-consistency
What is immediately consistent, what is eventually consistent, and how to write code that never notices the difference
ClinikAPI's FHIR data store gives different consistency guarantees for
different operations, and your integration should be written with them in
mind.
## The rules
| Operation | Consistency |
| - | - |
| `create` → response | **Immediate** — the returned resource includes its permanent `id` |
| `read(id)` | **Immediate** — a resource is readable by ID the moment `create` returns |
| `update` / `patch` → `read(id)` | **Immediate** |
| `search(...)` / `list(...)` | **Eventually consistent** — new or changed resources typically appear in results within seconds (commonly \~10s), not instantly |
| `delete` → `search` | **Eventually consistent** — a deleted resource may briefly linger in search results (but `read(id)` returns 404 immediately) |
## What this means for your code
**Golden rule: use the `id` you were given.** Every `create` returns the
resource with its permanent `id`. Read-after-write must always go through
`read(id)` — never through `search` — and you should never poll `search` to
confirm that a create succeeded. If `create` returned `200`, the resource
exists.
```ts theme={null}
// ✅ Correct: read-after-write by ID
const { data: patient } = await clinik.patients.create({
firstName: 'Jane',
lastName: 'Doe',
});
const { data: fresh } = await clinik.patients.read(patient.id!); // always works
// ❌ Wrong: searching for something you just created
await clinik.patients.create({ firstName: 'Jane', lastName: 'Doe' });
const { data: results } = await clinik.patients.search({ name: 'Doe' });
// results may not include the new patient yet — this is not a bug
```
## Practical patterns
* **After a form submit**, render the confirmation screen from the `create`
response itself (you already have the full resource) instead of re-querying
a list.
* **List screens** that need to show a just-created item immediately should
merge the `create` response into their local state (optimistic append), then
reconcile on the next natural refresh.
* **Batch imports**: track the returned IDs as your source of truth for what
was written; use search only for later exploration, not verification.
* **Deletes**: hide the row locally on a successful `delete` — don't wait for
it to disappear from search results.
## Why
FHIR search runs against an index that is updated asynchronously — the
standard trade-off that lets search stay fast over millions of resources. The
document store itself (create/read/update/delete by ID) is strongly
consistent.
# Errors
Source: https://docs.clinikapi.com/errors
Error codes, response format, and handling strategies.
# Errors
ClinikAPI uses standard HTTP status codes and returns structured error responses.
## Error Response Format
```json theme={null}
{
"error": "Validation Error",
"code": "VALIDATION_ERROR",
"requestId": "req_k8f3a7x2",
"issues": [
{
"severity": "error",
"code": "invalid",
"diagnostics": "firstName: Required"
}
]
}
```
## HTTP Status Codes
| Status | Meaning |
| - | - |
| `400` | Bad Request — malformed JSON or invalid parameters |
| `401` | Unauthorized — missing or invalid API key |
| `403` | Forbidden — key doesn't have required scope |
| `404` | Not Found — resource doesn't exist or belongs to another tenant |
| `409` | Conflict — resource version conflict |
| `422` | Validation Error — request body failed Zod validation |
| `429` | Rate Limited — too many requests for your plan |
| `500` | Internal Error — something went wrong on our end |
## Error Codes
| Code | Description |
| - | - |
| `UNAUTHORIZED` | Missing `x-api-key` header |
| `INVALID_KEY_FORMAT` | Key doesn't match `clk_live_*` or `clk_test_*` pattern |
| `INVALID_KEY` | Key not found in the database |
| `KEY_REVOKED` | Key has been revoked |
| `KEY_EXPIRED` | Key has passed its expiration date |
| `VALIDATION_ERROR` | Request body failed schema validation |
| `INVALID_JSON` | Request body was not valid JSON |
| `METHOD_OVERRIDE_REJECTED` | Request carried an HTTP method-override header |
| `SANDBOX_QUOTA_EXCEEDED` | Monthly sandbox (test-key) allowance used up |
| `RATE_LIMITED` | Plan request limit exceeded |
| `NOT_FOUND` | Resource not found |
| `INTERNAL_ERROR` | Unexpected server error |
## Method Override Is Not Supported
Send the HTTP method you mean. Requests carrying `X-HTTP-Method-Override`,
`X-HTTP-Method` or `X-Method-Override` are rejected with `400` and
`METHOD_OVERRIDE_REJECTED`, whatever the value.
A request whose real method disagrees with the one being executed breaks two
guarantees this API depends on: that a `GET` never modifies data, and that the
audit log records the operation that actually happened. The SDK never sends
these headers.
## SDK Error Handling
The SDK throws typed errors that you can catch:
```ts theme={null}
import { Clinik } from '@clinikapi/sdk';
const clinik = new Clinik(process.env.CLINIKAPI_SECRET_KEY!);
try {
const { data } = await clinik.patients.create({
firstName: 'Jane',
lastName: 'Doe',
});
} catch (err) {
if (err.name === 'ClinikValidationError') {
console.error('Validation issues:', err.issues);
} else if (err.name === 'ClinikRateLimitError') {
console.error('Rate limited. Retry after:', err.retryAfter, 'seconds');
} else if (err.name === 'ClinikApiError') {
console.error('API error:', err.code, err.message);
console.error('Request ID:', err.requestId);
}
}
```
## Automatic Retries
The SDK automatically retries on `5xx` errors and `429` (rate limit) responses with jittered exponential backoff:
* Default: 2 retries
* Backoff: random jitter up to `min(1000 * 2^attempt, 10000)` ms
* Configurable via `retries` option:
```ts theme={null}
const clinik = new Clinik(process.env.CLINIKAPI_SECRET_KEY!, {
retries: 3, // max retry attempts
timeout: 15000, // request timeout in ms
});
```
## Rate Limits
The rate limit is a **per-minute** ceiling on how fast you can call the API. The
window is 60 seconds and rolling — exhaust it and the next minute starts fresh.
| Plan | Requests per minute |
| - | - |
| Sandbox (free) | 100 |
| Starter | 200 |
| Pro | 1,000 |
| Team | 5,000 |
| Enterprise | 10,000 |
It applies to **all** traffic, test and live alike, and is shared across every
key in the organization. Exceeding it returns `429` with code `RATE_LIMITED`.
The current state comes back on every response:
| Header | Description |
| - | - |
| `X-RateLimit-Limit` | Requests allowed per minute on your plan |
| `X-RateLimit-Remaining` | Requests remaining in the current minute |
| `X-RateLimit-Reset` | Seconds until the window resets |
The rate limit and the monthly quota are different limits that both return
`429`. The rate limit is about **speed** (per minute); the quota below is about
**volume** (per month). Check the error `code` to tell them apart:
`RATE_LIMITED` versus `MONTHLY_QUOTA_EXCEEDED`.
The SDK exposes these in `meta`:
```ts theme={null}
const { data, meta } = await clinik.patients.search();
console.log(meta.rateLimitRemaining); // 498
```
## Monthly Quotas & Overage
Separate from the per-minute rate limit, every organization has **one shared monthly request pool** — all API keys and all sub-organizations draw from the same quota. On paid plans only **live** requests are billable; test traffic is metered but free. On the Sandbox plan every request counts. The pool resets on the 1st of each month (UTC).
| Plan | Included requests per month | Counts test traffic? |
| - | - | - |
| Sandbox (free) | 1,000 | Yes — every request |
| Starter | 60,000 | No — live only |
| Pro | 600,000 | No — live only |
| Team | 3,000,000 | No — live only |
| Enterprise | Unlimited | No — live only |
### The sandbox pool
Test traffic is free, but not unlimited. Every paid plan gets a **separate
monthly sandbox allowance equal to its live allowance** — Pro includes 600,000
live requests *and* 600,000 sandbox requests. They are independent pools:
spending one never touches the other.
| Plan | Live requests | Sandbox requests |
| - | - | - |
| Sandbox (free) | — | 1,000 (the shared pool above) |
| Starter | 60,000 | 60,000 |
| Pro | 600,000 | 600,000 |
| Team | 3,000,000 | 3,000,000 |
| Enterprise | Unlimited | Unlimited |
Sandbox usage comes back on responses to a test key:
| Header | Description |
| - | - |
| `X-Sandbox-Limit` | Sandbox requests included per month |
| `X-Sandbox-Used` | Sandbox requests used this month (org-wide) |
| `X-Sandbox-Remaining` | Sandbox requests left before the cap |
Exhausting it returns `429` with code `SANDBOX_QUOTA_EXCEEDED`. **Overage
billing does not extend it** — sandbox traffic is never billed, so there is
nothing to invoice; the pool simply resets on the 1st. On the Sandbox plan
there is no separate pool at all, because test requests are already what
consume the 1,000.
Quota state is returned on every authenticated response:
| Header | Description |
| - | - |
| `X-Quota-Limit` | Requests included in your plan per month |
| `X-Quota-Used` | Billable requests used this month (org-wide) |
| `X-Quota-Remaining` | Billable requests left before the limit |
| `X-Quota-Billable` | Whether this request counted against the pool |
| `X-Quota-Overage` | Requests past the limit this month (only when over) |
| `X-Quota-Reset` | ISO timestamp when the pool resets |
What happens at the limit depends on your **overage billing** setting (Dashboard → Billing):
* **Overage billing off** (default): requests past the quota are rejected with `429` and code `MONTHLY_QUOTA_EXCEEDED` until the month resets. Your bill never exceeds your plan price.
* **Overage billing on** (paid plans): traffic keeps flowing and extra requests are added to your next invoice at your plan's overage rate (\$0.003/request).
The Sandbox plan always hard-blocks — overage billing is a paid-plan setting, so
a free organization can never be charged. And because overage is calculated from
live traffic only, sandbox requests can never appear on an invoice on any plan.
```json theme={null}
{
"error": "Quota exceeded",
"message": "Monthly request quota reached (600,000 included requests). Enable overage billing or upgrade your plan at https://dashboard.clinikapi.com/billing to keep serving traffic.",
"code": "MONTHLY_QUOTA_EXCEEDED"
}
```
## PHI Sanitization
Error responses never contain Protected Health Information (PHI). Field values are stripped from validation error messages — only field names and constraint descriptions are included.
# Accounts
Source: https://docs.clinikapi.com/guides/accounts
Track billing accounts, insurance coverage, and guarantors.
# Accounts
Accounts (FHIR `Account`) track billing and financial information for patients — insurance coverage, guarantors, service periods, and account status.
## Create a Patient Account
```ts theme={null}
const { data: account } = await clinik.accounts.create({
status: 'active',
type: 'patient',
name: 'Jane Doe - Primary Account',
patientId: 'pt_abc123',
servicePeriod: { start: '2025-01-01', end: '2025-12-31' },
ownerId: 'org_sunrise_medical',
coverage: [
{ coverageId: 'cov_bcbs_001', priority: 1 },
{ coverageId: 'cov_dental_001', priority: 2 },
],
guarantor: [{
partyId: 'Patient/pt_abc123',
onHold: false,
}],
description: 'Primary billing account for outpatient services',
});
```
## Account Status
| Status | Description |
| - | - |
| `active` | Account is in use |
| `inactive` | Account is closed |
| `on-hold` | Account is temporarily suspended |
## Sub-Accounts
Create child accounts for specific service lines:
```ts theme={null}
const { data: subAccount } = await clinik.accounts.create({
status: 'active',
type: 'expense',
name: 'Cardiology Services',
patientId: 'pt_abc123',
partOfId: account.id,
});
```
## Search Accounts
```ts theme={null}
const { data } = await clinik.accounts.search({
patientId: 'pt_abc123',
status: 'active',
});
```
# Activity Definitions
Source: https://docs.clinikapi.com/guides/activity-definitions
Define reusable clinical activity templates — order templates, procedure definitions, and standardized workflows.
# Activity Definitions
Activity definitions (FHIR `ActivityDefinition`) are reusable templates that describe clinical activities. They define what should happen — the kind of resource to create, the code, timing, participants, and other details — so that clinical protocols and order sets can reference them.
## Create an Activity Definition
```ts theme={null}
const { data: activity } = await clinik.activityDefinitions.create({
status: 'active',
name: 'hba1c-lab-order',
title: 'HbA1c Lab Order',
kind: 'ServiceRequest',
code: {
system: 'http://loinc.org',
code: '4548-4',
display: 'Hemoglobin A1c/Hemoglobin.total in Blood',
},
intent: 'order',
priority: 'routine',
description: 'Standard HbA1c lab order for diabetes monitoring',
participant: [{ type: 'practitioner', role: 'Lab Technician' }],
topic: ['diabetes', 'laboratory'],
});
```
## Common Use Cases
### Medication Order Template
```ts theme={null}
const { data } = await clinik.activityDefinitions.create({
status: 'active',
name: 'metformin-500mg-bid',
title: 'Metformin 500mg BID',
kind: 'MedicationRequest',
code: 'Metformin 500mg',
intent: 'order',
description: 'Standard starting dose of Metformin for Type 2 Diabetes',
quantity: { value: 60, unit: 'tablets' },
topic: ['diabetes', 'medication'],
});
```
### Appointment Template
```ts theme={null}
const { data } = await clinik.activityDefinitions.create({
status: 'active',
name: 'diabetes-followup-visit',
title: 'Diabetes Follow-up Visit',
kind: 'Appointment',
intent: 'plan',
priority: 'routine',
description: 'Quarterly follow-up for diabetes management',
participant: [
{ type: 'practitioner', role: 'Primary Care Physician' },
{ type: 'patient' },
],
});
```
### Do Not Perform
```ts theme={null}
const { data } = await clinik.activityDefinitions.create({
status: 'active',
name: 'no-aspirin-allergy',
title: 'Do Not Administer Aspirin',
kind: 'MedicationRequest',
code: 'Aspirin',
doNotPerform: true,
description: 'Contraindicated due to aspirin allergy',
});
```
## Search Activity Definitions
```ts theme={null}
const { data } = await clinik.activityDefinitions.search({
status: 'active',
kind: 'ServiceRequest',
name: 'hba1c',
});
```
## Advanced Features
For advanced ActivityDefinition features like `dynamicValue`, `expression`, `library`, or `relatedArtifact`, use the [FHIR Passthrough](/sdk/fhir-passthrough):
```ts theme={null}
const { data } = await clinik.fhir.request('POST', '/ActivityDefinition', {
resourceType: 'ActivityDefinition',
status: 'active',
// ... full FHIR R4 ActivityDefinition
});
```
# Allergies
Source: https://docs.clinikapi.com/guides/allergies
Record and manage patient allergies and intolerances.
# Allergies
Allergies (FHIR `AllergyIntolerance`) record a patient's known allergies and adverse reactions to substances including medications, foods, and environmental agents. They track clinical status, criticality, and detailed reaction history.
## Record an Allergy
```ts theme={null}
const { data: allergy } = await clinik.allergies.create({
patientId: 'pt_abc123',
clinicalStatus: 'active',
verificationStatus: 'confirmed',
type: 'allergy',
category: ['medication'],
criticality: 'high',
code: {
system: 'http://www.nlm.nih.gov/research/umls/rxnorm',
code: '7980',
display: 'Penicillin',
},
onsetDateTime: '2019-06-15',
recordedDate: '2024-01-10',
recorderId: 'pract_dr456',
reaction: [
{
substance: 'Amoxicillin',
manifestation: ['Hives', 'Angioedema'],
severity: 'severe',
onset: '2019-06-15T14:30:00Z',
exposureRoute: 'Oral',
note: 'Patient developed hives within 30 minutes of first dose.',
},
],
note: 'Confirmed penicillin allergy — avoid all beta-lactam antibiotics.',
});
```
## Food Allergy with Multiple Reactions
```ts theme={null}
const { data: peanutAllergy } = await clinik.allergies.create({
patientId: 'pt_abc123',
clinicalStatus: 'active',
verificationStatus: 'confirmed',
type: 'allergy',
category: ['food'],
criticality: 'high',
code: 'Peanut',
reaction: [
{
substance: 'Peanut butter',
manifestation: ['Anaphylaxis', 'Throat swelling', 'Difficulty breathing'],
severity: 'severe',
description: 'Severe anaphylactic reaction requiring epinephrine.',
},
{
substance: 'Peanut oil',
manifestation: ['Skin rash', 'Itching'],
severity: 'mild',
},
],
});
```
## Update Clinical Status
Mark an allergy as resolved:
```ts theme={null}
await clinik.allergies.update(allergy.id, {
clinicalStatus: 'resolved',
note: 'Patient completed desensitization therapy. No longer reactive.',
});
```
## Search Allergies
```ts theme={null}
// All active allergies for a patient
const { data } = await clinik.allergies.search({
patientId: 'pt_abc123',
clinicalStatus: 'active',
});
// High-criticality medication allergies
const { data: critical } = await clinik.allergies.search({
patientId: 'pt_abc123',
category: 'medication',
criticality: 'high',
});
```
## Allergy Categories
| Category | Description |
| - | - |
| `food` | Food substances (peanuts, shellfish, dairy) |
| `medication` | Medications (penicillin, sulfa drugs) |
| `environment` | Environmental agents (pollen, dust, latex) |
| `biologic` | Biological substances (vaccines, blood products) |
## Criticality Levels
| Level | Description |
| - | - |
| `low` | Low risk — reaction is not life-threatening |
| `high` | High risk — potential for life-threatening reaction |
| `unable-to-assess` | Unable to assess the criticality |
# Appointment Responses
Source: https://docs.clinikapi.com/guides/appointment-responses
Manage participant responses to appointments — accept, decline, or propose new times.
# Appointment Responses
Appointment responses (FHIR `AppointmentResponse`) represent a participant's reply to an appointment invitation. Practitioners, patients, or other participants can accept, decline, tentatively accept, or propose alternative times.
## Accept an Appointment
```ts theme={null}
const { data } = await clinik.appointmentResponses.create({
appointmentId: 'appt_abc123',
participantStatus: 'accepted',
actorId: 'Practitioner/prac_def456',
comment: 'Confirmed — see you then.',
});
```
## Decline an Appointment
```ts theme={null}
const { data } = await clinik.appointmentResponses.create({
appointmentId: 'appt_abc123',
participantStatus: 'declined',
actorId: 'Patient/pt_xyz789',
comment: 'Unable to attend — please reschedule.',
});
```
## Propose a New Time
```ts theme={null}
const { data } = await clinik.appointmentResponses.create({
appointmentId: 'appt_abc123',
participantStatus: 'tentative',
actorId: 'Patient/pt_xyz789',
start: '2025-02-03T10:00:00Z',
end: '2025-02-03T10:30:00Z',
comment: 'Can we move to Monday morning?',
});
```
## Participant Status Values
| Status | Description |
| - | - |
| `accepted` | Participant has accepted |
| `declined` | Participant has declined |
| `tentative` | Tentatively accepted (may propose new time) |
| `needs-action` | Awaiting response |
## Search Responses
```ts theme={null}
// All responses for an appointment
const { data } = await clinik.appointmentResponses.search({
appointmentId: 'appt_abc123',
});
// Responses from a specific participant
const { data: byActor } = await clinik.appointmentResponses.search({
actorId: 'Practitioner/prac_def456',
participantStatus: 'accepted',
});
```
## Workflow
1. Create an `Appointment` with status `proposed` or `pending`
2. Each participant creates an `AppointmentResponse` (accepted/declined/tentative)
3. Once all required participants accept, update the appointment to `booked`
# Appointments
Source: https://docs.clinikapi.com/guides/appointments
Schedule, manage, and track patient appointments.
# Appointments
Appointments represent scheduled clinical interactions between patients and practitioners.
## Create an Appointment
```ts theme={null}
const { data: appt } = await clinik.appointments.create({
status: 'booked',
patientId: 'pt_abc123',
practitionerId: 'prac_def456',
start: '2025-02-01T14:00:00Z',
end: '2025-02-01T14:30:00Z',
minutesDuration: 30,
appointmentType: 'followup',
serviceType: 'Cardiology consultation',
serviceCategory: 'specialist',
specialty: 'Cardiology',
reasonCode: 'Blood pressure follow-up',
priority: 0,
description: 'Follow-up visit for hypertension management',
patientInstruction: 'Please bring your home BP log',
});
```
## New Fields
### Based On (ServiceRequest)
Link an appointment to the ServiceRequest it was created to assess:
```ts theme={null}
const { data } = await clinik.appointments.create({
status: 'proposed',
patientId: 'pt_abc123',
practitionerId: 'prac_def456',
basedOnId: 'sr_referral789',
serviceType: 'Orthopedic consultation',
description: 'Referral follow-up for knee pain',
// ...
});
```
### Requested Period
Specify preferred time windows when the patient is available:
```ts theme={null}
const { data } = await clinik.appointments.create({
status: 'proposed',
patientId: 'pt_abc123',
practitionerId: 'prac_def456',
requestedPeriod: [
{ start: '2025-02-03T09:00:00Z', end: '2025-02-03T12:00:00Z' },
{ start: '2025-02-04T14:00:00Z', end: '2025-02-04T17:00:00Z' },
],
description: 'Patient prefers morning or afternoon slots',
// ...
});
```
### Created Timestamp
Track when the appointment was initially created (defaults to now):
```ts theme={null}
const { data } = await clinik.appointments.create({
status: 'booked',
patientId: 'pt_abc123',
practitionerId: 'prac_def456',
start: '2025-02-01T14:00:00Z',
end: '2025-02-01T14:30:00Z',
created: '2025-01-20T08:30:00Z', // when the booking was made
// ...
});
```
## Status Lifecycle
```
proposed → pending → booked → checked-in → arrived → fulfilled
↘ cancelled / noshow
```
| Status | Description |
| - | - |
| `proposed` | Suggested but not confirmed |
| `pending` | Awaiting confirmation |
| `booked` | Confirmed and scheduled |
| `checked-in` | Patient has checked in |
| `arrived` | Patient is at the facility |
| `fulfilled` | Appointment completed |
| `cancelled` | Cancelled before completion |
| `noshow` | Patient did not attend |
| `waitlist` | On a waitlist |
## Update an Appointment
```ts theme={null}
// Check in a patient
await clinik.appointments.update('appt_xyz789', {
status: 'checked-in',
});
// Cancel with reason
await clinik.appointments.update('appt_xyz789', {
status: 'cancelled',
cancelationReason: 'Patient requested reschedule',
});
// Reschedule with updated service details
await clinik.appointments.update('appt_xyz789', {
start: '2025-02-03T10:00:00Z',
end: '2025-02-03T10:30:00Z',
appointmentType: 'followup',
serviceType: 'General checkup',
specialty: 'Family Medicine',
reasonCode: 'Annual wellness visit',
priority: 0,
comment: 'Rescheduled from Feb 1 per patient request',
});
```
## Search Appointments
```ts theme={null}
// Upcoming appointments for a patient
const { data: upcoming } = await clinik.appointments.search({
patientId: 'pt_abc123',
status: 'booked',
dateFrom: new Date().toISOString().split('T')[0],
sort: 'date',
count: 10,
});
// All appointments for a practitioner today
const today = new Date().toISOString().split('T')[0];
const { data: schedule } = await clinik.appointments.search({
dateFrom: today,
dateTo: today,
sort: 'date',
});
```
## Priority
Priority is an integer from 0-9:
| Value | Meaning |
| - | - |
| `0` | Routine (default) |
| `1-3` | Low urgency |
| `4-6` | Medium urgency |
| `7-9` | High urgency |
## Complete Field Reference
| Field | Type | Required | Description |
| - | - | - | - |
| `status` | `string` | Yes | proposed, pending, booked, arrived, fulfilled, cancelled, noshow, checked-in, waitlist |
| `patientId` | `string` | Yes | Patient reference |
| `practitionerId` | `string` | No | Practitioner reference |
| `start` | `string` | No | Start time (ISO 8601) |
| `end` | `string` | No | End time (ISO 8601) |
| `minutesDuration` | `number` | No | Duration in minutes (max 1440) |
| `appointmentType` | `string` | No | routine, walkin, urgent, followup |
| `serviceType` | `string` | No | Service being booked |
| `serviceCategory` | `string` | No | Service category |
| `specialty` | `string` | No | Required specialty |
| `reasonCode` | `string` | No | Reason for appointment |
| `priority` | `number` | No | 0 (routine) to 9 (urgent) |
| `description` | `string` | No | Subject line |
| `comment` | `string` | No | Additional comments |
| `patientInstruction` | `string` | No | Instructions for patient |
| `cancelationReason` | `string` | No | Reason for cancellation |
| `basedOnId` | `string` | No | ServiceRequest this appointment assesses |
| `requestedPeriod` | `Array<{ start?, end? }>` | No | Preferred time windows |
| `created` | `string` | No | When initially created (defaults to now) |
# Assessments
Source: https://docs.clinikapi.com/guides/assessments
Record clinical impressions, findings, investigations, and prognosis.
# Assessments
Assessments (FHIR ClinicalImpression) capture a clinician's overall evaluation of a patient — findings, diagnoses, investigations, prognosis, and clinical summary. They're typically created during or after an encounter.
## Create an Assessment
```ts theme={null}
const { data: assessment } = await clinik.assessments.create({
status: 'completed',
code: 'initial-assessment',
patientId: 'pt_abc123',
encounterId: 'enc_xyz789',
practitionerId: 'prac_def456',
description: 'Annual wellness assessment',
summary: 'Patient presents with well-controlled hypertension and type 2 diabetes. '
+ 'No signs of end-organ damage. Continue current medication regimen. '
+ 'Recommend dietary counseling and increased physical activity.',
findings: [
{ code: 'I10', text: 'Essential hypertension — well controlled on lisinopril 10mg', basis: 'BP readings over 3 months' },
{ code: 'E11.9', text: 'Type 2 diabetes mellitus — HbA1c 6.8%, at goal', basis: 'Lab panel from today' },
{ text: 'BMI 28.5 — overweight, recommend weight management' },
{ text: 'No peripheral neuropathy on exam' },
],
investigations: [
{ name: 'Lab panel', itemIds: ['obs_cmp_001', 'obs_hba1c_001'] },
{ name: 'Vitals', itemIds: ['obs_bp_001', 'obs_bmi_001'] },
],
problemIds: ['cond_hypertension', 'cond_diabetes'],
prognosis: [
{ text: 'Good — well controlled with current regimen' },
{ code: 'favorable', text: 'Favorable with continued compliance' },
],
note: 'Follow up in 3 months. Order HbA1c and CMP at next visit.',
effectiveDateTime: '2025-01-15T10:00:00Z',
});
```
## Assessment Code
Classify the type of assessment:
```ts theme={null}
const { data } = await clinik.assessments.create({
status: 'completed',
code: 'discharge', // initial-assessment, follow-up, discharge, pre-operative
patientId: 'pt_abc123',
summary: 'Patient stable for discharge...',
// ...
});
```
## Status Reason
Explain why an assessment is still in progress:
```ts theme={null}
const { data } = await clinik.assessments.create({
status: 'in-progress',
statusReason: 'Awaiting lab results before finalizing',
patientId: 'pt_abc123',
summary: 'Preliminary assessment — pending CMP results.',
// ...
});
```
## Findings with Basis
Document which investigations support each finding:
```ts theme={null}
findings: [
{
code: 'I10',
text: 'Essential hypertension',
basis: 'Blood pressure 148/92 on three separate readings',
},
{
code: 'E11.9',
text: 'Type 2 diabetes mellitus',
basis: 'HbA1c 7.2% (lab panel obs_hba1c_001)',
},
{
text: 'Patient reports improved energy levels',
},
]
```
## Investigations
Group related clinical investigations:
```ts theme={null}
investigations: [
{
name: 'Initial labs',
itemIds: ['obs_glucose', 'obs_creatinine', 'obs_hba1c'],
},
{
name: 'Imaging',
itemIds: ['dr_chest_xray_001'],
},
{
name: 'Patient-reported',
itemIds: ['intake_symptoms_001'],
},
]
```
## Previous Assessment
Link to a prior assessment for longitudinal tracking:
```ts theme={null}
const { data } = await clinik.assessments.create({
status: 'completed',
code: 'follow-up',
patientId: 'pt_abc123',
previousAssessmentId: 'assess_initial_001',
summary: 'Follow-up: Blood pressure improved since last visit.',
// ...
});
```
## Problem List
Reference the conditions being assessed:
```ts theme={null}
const { data } = await clinik.assessments.create({
status: 'completed',
patientId: 'pt_abc123',
problemIds: ['cond_hypertension', 'cond_diabetes', 'allergy_penicillin'],
summary: 'Reviewed active problem list...',
// ...
});
```
## Prognosis
Document the expected outcome:
```ts theme={null}
prognosis: [
{ text: 'Good — well controlled with current regimen' },
{ code: 'guarded', text: 'Guarded if medication compliance declines' },
]
```
## Status Values
| Status | Description |
| - | - |
| `in-progress` | Assessment is being conducted |
| `completed` | Assessment is finalized |
## Update an Assessment
```ts theme={null}
await clinik.assessments.update('assess_abc123', {
status: 'completed',
statusReason: 'Lab results received',
summary: 'Updated summary with lab findings...',
findings: [
{ code: 'I10', text: 'Essential hypertension — well controlled', basis: 'BP 128/82' },
{ code: 'E11.9', text: 'Type 2 diabetes — at goal', basis: 'HbA1c 6.8%' },
{ text: 'New finding: mild vitamin D deficiency', basis: 'Vitamin D level 22 ng/mL' },
],
investigations: [
{ name: 'Updated labs', itemIds: ['obs_cmp_002', 'obs_vitd_001'] },
],
prognosis: [{ text: 'Good with vitamin D supplementation' }],
note: 'Added vitamin D 2000 IU daily to plan.',
});
```
## Search Assessments
```ts theme={null}
// All assessments for a patient
const { data } = await clinik.assessments.search({
patientId: 'pt_abc123',
status: 'completed',
sort: '-date',
});
// Assessments by a specific practitioner
const { data: byDoc } = await clinik.assessments.search({
practitionerId: 'prac_def456',
dateFrom: '2025-01-01',
});
```
## Assessments vs Notes
| Resource | Purpose |
| - | - |
| Assessment (ClinicalImpression) | Structured clinical evaluation with coded findings, investigations, prognosis |
| Note (DocumentReference) | Narrative documentation (SOAP notes, discharge summaries) |
Use assessments for structured clinical reasoning. Use notes for narrative documentation. They often complement each other — an encounter might have both a progress note and a clinical assessment.
# Audit Events
Source: https://docs.clinikapi.com/guides/audit-events
Record and query security-relevant events for compliance and audit trails.
# Audit Events
Audit Events (FHIR `AuditEvent`) record security-relevant events in your healthcare system. They are essential for HIPAA compliance, tracking who accessed what data and when. Audit events are **immutable** — once created, they cannot be modified.
## Record a REST Access Event
```ts theme={null}
const { data: event } = await clinik.auditEvents.create({
type: 'rest',
subtype: ['read'],
action: 'R',
recorded: new Date().toISOString(),
outcome: '0',
agent: [{
who: 'prac_dr456',
name: 'Dr. Sarah Chen',
requestor: true,
role: 'Practitioner',
networkAddress: '10.0.1.42',
}],
source: {
observer: 'EHR Application',
site: 'Main Campus',
type: 'Application Server',
},
entity: [{
what: 'Patient/pt_abc123',
type: '1',
role: '1',
name: 'Patient Record',
description: 'Accessed patient demographics',
}],
});
```
## Record a Login Event
```ts theme={null}
const { data } = await clinik.auditEvents.create({
type: 'login',
action: 'E',
recorded: '2024-06-15T08:30:00Z',
outcome: '0',
agent: [{
who: 'user_nurse789',
name: 'Nurse Johnson',
requestor: true,
role: 'Nurse',
networkAddress: '192.168.1.50',
}],
source: {
observer: 'Authentication Service',
site: 'Cloud',
},
});
```
## Record a Failed Access Attempt
```ts theme={null}
const { data } = await clinik.auditEvents.create({
type: 'rest',
action: 'R',
recorded: new Date().toISOString(),
outcome: '8',
outcomeDesc: 'Access denied — insufficient privileges for restricted record',
agent: [{
who: 'user_intern001',
name: 'Medical Intern',
requestor: true,
role: 'Intern',
}],
source: {
observer: 'Authorization Service',
site: 'Cloud',
},
entity: [{
what: 'Patient/pt_restricted999',
type: '1',
role: '1',
name: 'Restricted Patient Record',
}],
});
```
## Record a Data Export Event
```ts theme={null}
const { data } = await clinik.auditEvents.create({
type: 'export',
action: 'R',
recorded: new Date().toISOString(),
outcome: '0',
purposeOfEvent: ['HIPAA Operations', 'Quality Reporting'],
agent: [{
who: 'admin_user001',
name: 'System Administrator',
requestor: true,
role: 'Admin',
}],
source: {
observer: 'Bulk Export Service',
site: 'Cloud',
type: 'Application Server',
},
entity: [{
type: '2',
role: '3',
name: 'Bulk Export Job',
description: 'Exported 1,200 patient records for quality reporting',
}],
});
```
## Search Audit Events
```ts theme={null}
// All events with a specific action
const { data } = await clinik.auditEvents.search({
action: 'R',
});
// Failed events
const { data: failures } = await clinik.auditEvents.search({
outcome: '8',
});
// Events in a date range
const { data: recent } = await clinik.auditEvents.search({
dateFrom: '2024-06-01',
dateTo: '2024-06-30',
});
```
# Bulk Operations
Source: https://docs.clinikapi.com/guides/bulk-operations
Import and export large datasets in NDJSON format.
# Bulk Operations
Bulk operations let you import and export large volumes of clinical data using NDJSON (newline-delimited JSON) format.
## Bulk Export
Start an export job for one or more resource types:
```bash theme={null}
curl -X POST https://api.clinikapi.com/v1/bulk/export \
-H "x-api-key: clk_live_abc123" \
-H "Content-Type: application/json" \
-d '{
"resourceTypes": ["Patient", "Encounter", "Observation"],
"since": "2025-01-01T00:00:00Z"
}'
```
Response:
```json theme={null}
{
"data": {
"jobId": "job_abc123",
"status": "pending",
"message": "Export job started"
}
}
```
### Poll for Completion
```bash theme={null}
curl https://api.clinikapi.com/v1/bulk/jobs/job_abc123 \
-H "x-api-key: clk_live_abc123"
```
```json theme={null}
{
"data": {
"id": "job_abc123",
"type": "export",
"status": "completed",
"totalRecords": 1250,
"processedRecords": 1250,
"downloadUrl": "https://exports.clinikapi.com/clinikapi-exports/...",
"errors": []
}
}
```
The `downloadUrl` is a pre-signed URL valid for 1 hour.
## Bulk Import
Import NDJSON data — one JSON resource per line, max 10,000 records per batch:
```bash theme={null}
curl -X POST https://api.clinikapi.com/v1/bulk/import \
-H "x-api-key: clk_live_abc123" \
-H "Content-Type: application/json" \
-d '{
"resourceType": "Patient",
"data": "{\"firstName\":\"Jane\",\"lastName\":\"Doe\",\"gender\":\"female\"}\n{\"firstName\":\"John\",\"lastName\":\"Smith\",\"gender\":\"male\"}"
}'
```
### Import Rules
* Max **10,000 records** per batch
* Tenant tags are automatically injected — you cannot override them
* Invalid records are skipped and reported in the job's `errors` array
* Rate limited to **5 bulk operations per hour** per tenant
## Job Statuses
| Status | Description |
| - | - |
| `pending` | Job is queued |
| `processing` | Job is running |
| `completed` | Job finished successfully |
| `failed` | Job failed (check `errors` array) |
## NDJSON Format
Each line is a complete JSON object:
```
{"firstName":"Jane","lastName":"Doe","gender":"female","birthDate":"1990-01-15"}
{"firstName":"John","lastName":"Smith","gender":"male","birthDate":"1985-06-20"}
{"firstName":"Maria","lastName":"Garcia","gender":"female","birthDate":"1978-11-03"}
```
Bulk operations count against your plan's request limit. Each record in an import counts as one request.
# Care Plans
Source: https://docs.clinikapi.com/guides/care-plans
Create and manage patient care plans with activities, goals, and care team coordination.
# Care Plans
Care Plans (FHIR `CarePlan`) represent planned healthcare activities for a patient. They coordinate goals, activities, and care teams to manage conditions like chronic diseases, post-surgical recovery, or preventive care.
## Create a Care Plan
```ts theme={null}
const { data: plan } = await clinik.carePlans.create({
status: 'active',
intent: 'plan',
patientId: 'pt_abc123',
title: 'Post-Surgical Recovery Plan',
description: 'Recovery plan following knee replacement surgery',
category: ['post-surgical'],
authorId: 'prac_surgeon456',
period: {
start: '2024-03-15',
end: '2024-06-15',
},
activity: [
{
description: 'Physical therapy sessions — 3x per week',
status: 'scheduled',
code: 'physical-therapy',
scheduledString: 'Mon/Wed/Fri at 10:00 AM',
performerId: 'prac_pt789',
},
{
description: 'Wound care assessment',
status: 'not-started',
scheduledString: 'Weekly for first 4 weeks',
},
{
description: 'Pain management follow-up',
status: 'not-started',
scheduledString: '2 weeks post-op',
performerId: 'prac_surgeon456',
},
],
note: 'Patient is motivated and has good family support at home',
});
```
## Chronic Disease Management
Care plans are ideal for managing ongoing conditions:
```ts theme={null}
const { data: diabetesPlan } = await clinik.carePlans.create({
status: 'active',
intent: 'plan',
patientId: 'pt_abc123',
title: 'Type 2 Diabetes Management',
category: ['chronic-disease', 'diabetes'],
authorId: 'prac_pcp456',
contributorIds: ['prac_endo789', 'prac_dietitian012'],
goalIds: ['goal_a1c_target', 'goal_weight_loss'],
addressesIds: ['condition_diabetes_e119'],
activity: [
{
description: 'HbA1c monitoring',
status: 'scheduled',
code: 'lab-monitoring',
scheduledString: 'Every 3 months',
},
{
description: 'Metformin 500mg twice daily',
status: 'in-progress',
code: 'medication',
},
{
description: 'Nutritional counseling',
status: 'scheduled',
scheduledString: 'Monthly',
performerId: 'prac_dietitian012',
},
],
});
```
## Update Activity Status
```ts theme={null}
const { data: updated } = await clinik.carePlans.update(plan.id, {
activity: [
{
description: 'Physical therapy sessions — 3x per week',
status: 'in-progress',
code: 'physical-therapy',
scheduledString: 'Mon/Wed/Fri at 10:00 AM',
performerId: 'prac_pt789',
},
{
description: 'Wound care assessment',
status: 'completed',
scheduledString: 'Weekly for first 4 weeks',
},
],
});
```
## Search Care Plans
```ts theme={null}
// Find all active care plans for a patient
const { data } = await clinik.carePlans.search({
patientId: 'pt_abc123',
status: 'active',
});
// Find care plans by category
const { data: diabetesPlans } = await clinik.carePlans.search({
patientId: 'pt_abc123',
category: 'diabetes',
});
```
## Care Plan Statuses
| Status | Description |
| - | - |
| `draft` | Plan is being developed |
| `active` | Plan is in effect |
| `on-hold` | Plan is temporarily paused |
| `revoked` | Plan has been cancelled |
| `completed` | Plan activities are finished |
# Care Teams
Source: https://docs.clinikapi.com/guides/care-teams
Organize multidisciplinary care teams for coordinated patient care.
# Care Teams
Care Teams (FHIR `CareTeam`) represent groups of practitioners and organizations collaborating on a patient's care. They define roles, responsibilities, and the period of team involvement.
## Create a Care Team
```ts theme={null}
const { data: team } = await clinik.careTeams.create({
name: 'Diabetes Management Team',
status: 'active',
category: ['longitudinal-care'],
patientId: 'pt_abc123',
participant: [
{
role: 'Primary Care Physician',
memberId: 'Practitioner/pract_dr456',
},
{
role: 'Endocrinologist',
memberId: 'Practitioner/pract_dr789',
},
{
role: 'Diabetes Educator',
memberId: 'Practitioner/pract_nurse101',
onBehalfOfId: 'org_sunrise',
},
{
role: 'Dietitian',
memberId: 'Practitioner/pract_diet202',
period: { start: '2024-01-01', end: '2024-06-30' },
},
],
reasonCode: ['Type 2 Diabetes Mellitus'],
managingOrganizationIds: ['org_sunrise'],
phone: '555-0200',
email: 'diabetes-team@sunrise-medical.com',
note: 'Weekly team huddle every Monday at 9am.',
});
```
## Encounter-Based Team
Create a team for a specific encounter:
```ts theme={null}
const { data: surgeryTeam } = await clinik.careTeams.create({
name: 'Knee Replacement Surgery Team',
status: 'active',
category: ['encounter-based'],
patientId: 'pt_abc123',
encounterId: 'enc_surgery789',
participant: [
{ role: 'Lead Surgeon', memberId: 'Practitioner/pract_surgeon01' },
{ role: 'Anesthesiologist', memberId: 'Practitioner/pract_anesthesia02' },
{ role: 'Surgical Nurse', memberId: 'Practitioner/pract_nurse03' },
],
period: { start: '2024-03-15', end: '2024-03-15' },
});
```
## Update Team Members
```ts theme={null}
await clinik.careTeams.update(team.id, {
participant: [
{ role: 'Primary Care Physician', memberId: 'Practitioner/pract_dr456' },
{ role: 'Endocrinologist', memberId: 'Practitioner/pract_dr789' },
{ role: 'Diabetes Educator', memberId: 'Practitioner/pract_nurse101' },
{ role: 'Pharmacist', memberId: 'Practitioner/pract_pharm303' },
],
note: 'Added pharmacist for medication management review.',
});
```
## Search Care Teams
```ts theme={null}
// All active teams for a patient
const { data } = await clinik.careTeams.search({
patientId: 'pt_abc123',
status: 'active',
});
// Teams by category
const { data: longitudinal } = await clinik.careTeams.search({
category: 'longitudinal-care',
});
```
## Team Statuses
| Status | Description |
| - | - |
| `proposed` | Team has been suggested but not yet formed |
| `active` | Team is currently active and providing care |
| `suspended` | Team is temporarily paused |
| `inactive` | Team is no longer active |
# Charge Items
Source: https://docs.clinikapi.com/guides/charge-items
Track billable services and charges for patient encounters.
# Charge Items
Charge Items (FHIR `ChargeItem`) represent individual billable services, procedures, or supplies provided to a patient. They capture pricing, performers, and link charges to accounts for billing workflows.
## Create a Charge Item
```ts theme={null}
const { data: charge } = await clinik.chargeItems.create({
status: 'billable',
code: {
system: 'http://www.ama-assn.org/go/cpt',
code: '99213',
display: 'Office visit, established patient, low complexity',
},
patientId: 'pt_abc123',
encounterId: 'enc_visit456',
occurrenceDateTime: '2024-01-15T10:30:00Z',
performer: [
{ function: 'Primary performer', actorId: 'Practitioner/pract_dr456' },
],
performingOrganizationId: 'org_sunrise',
priceOverride: { value: 150.00, currency: 'USD' },
accountIds: ['acct_billing789'],
note: 'Routine follow-up visit for diabetes management.',
});
```
## Lab Service Charge
```ts theme={null}
const { data: labCharge } = await clinik.chargeItems.create({
status: 'billable',
code: {
system: 'http://www.ama-assn.org/go/cpt',
code: '80053',
display: 'Comprehensive metabolic panel',
},
patientId: 'pt_abc123',
encounterId: 'enc_visit456',
occurrenceDateTime: '2024-01-15T11:00:00Z',
quantity: { value: 1, unit: 'test' },
priceOverride: { value: 45.00, currency: 'USD' },
reason: ['Annual metabolic screening'],
});
```
## Procedure Charge with Multiple Performers
```ts theme={null}
const { data: procedureCharge } = await clinik.chargeItems.create({
status: 'billable',
code: {
system: 'http://www.ama-assn.org/go/cpt',
code: '27447',
display: 'Total knee replacement',
},
patientId: 'pt_abc123',
encounterId: 'enc_surgery789',
occurrencePeriod: {
start: '2024-03-15T08:00:00Z',
end: '2024-03-15T11:30:00Z',
},
performer: [
{ function: 'Lead Surgeon', actorId: 'Practitioner/pract_surgeon01' },
{ function: 'Anesthesiologist', actorId: 'Practitioner/pract_anesthesia02' },
],
bodySite: ['Right knee'],
priceOverride: { value: 28500.00, currency: 'USD' },
overrideReason: 'Negotiated rate per contract',
accountIds: ['acct_billing789'],
});
```
## Update Charge Status
```ts theme={null}
// Mark as billed after claim submission
await clinik.chargeItems.update(charge.id, {
status: 'billed',
note: 'Claim submitted to insurance on 2024-01-20.',
});
```
## Search Charge Items
```ts theme={null}
// All billable charges for a patient
const { data } = await clinik.chargeItems.search({
patientId: 'pt_abc123',
status: 'billable',
});
// Charges by date range
const { data: recent } = await clinik.chargeItems.search({
patientId: 'pt_abc123',
dateFrom: '2024-01-01',
dateTo: '2024-01-31',
});
// Search by billing code
const { data: visits } = await clinik.chargeItems.search({
code: '99213',
});
```
## Charge Item Statuses
| Status | Description |
| - | - |
| `planned` | Charge is planned but not yet incurred |
| `billable` | Charge is ready to be billed |
| `not-billable` | Charge is not billable (e.g. courtesy service) |
| `aborted` | Charge was cancelled before completion |
| `billed` | Charge has been submitted for billing |
# Claim Responses
Source: https://docs.clinikapi.com/guides/claim-responses
Process and track insurance adjudication results for submitted claims.
# Claim Responses
Claim Responses (FHIR `ClaimResponse`) represent adjudication results from insurers. They contain the outcome of a submitted claim including payment details, adjudicated line items, and processing notes.
## Create a Claim Response
```ts theme={null}
const { data: response } = await clinik.claimResponses.create({
status: 'active',
type: 'professional',
use: 'claim',
patientId: 'pt_abc123',
insurerId: 'org_ins789',
requestId: 'claim_xyz456',
outcome: 'complete',
disposition: 'Claim adjudicated per contract terms',
item: [
{
itemSequence: 1,
adjudication: [
{ category: 'submitted', amount: { value: 200.00, currency: 'USD' } },
{ category: 'eligible', amount: { value: 180.00, currency: 'USD' } },
{ category: 'benefit', amount: { value: 144.00, currency: 'USD' } },
{ category: 'copay', amount: { value: 36.00, currency: 'USD' } },
],
},
{
itemSequence: 2,
adjudication: [
{ category: 'submitted', amount: { value: 45.00, currency: 'USD' } },
{ category: 'eligible', amount: { value: 45.00, currency: 'USD' } },
{ category: 'benefit', amount: { value: 36.00, currency: 'USD' } },
{ category: 'copay', amount: { value: 9.00, currency: 'USD' } },
],
},
],
total: [
{ category: 'submitted', amount: { value: 245.00, currency: 'USD' } },
{ category: 'eligible', amount: { value: 225.00, currency: 'USD' } },
{ category: 'benefit', amount: { value: 180.00, currency: 'USD' } },
{ category: 'patient', amount: { value: 45.00, currency: 'USD' } },
],
payment: {
type: 'complete',
amount: { value: 180.00, currency: 'USD' },
date: '2024-04-15',
},
processNote: [
{ number: 1, text: 'Line 1 reduced to contracted rate per provider agreement' },
],
});
```
## Pre-Authorization Response
```ts theme={null}
const { data: preAuthResp } = await clinik.claimResponses.create({
status: 'active',
type: 'professional',
use: 'preauthorization',
patientId: 'pt_abc123',
insurerId: 'org_ins789',
requestId: 'claim_preauth123',
outcome: 'complete',
disposition: 'Pre-authorization approved',
preAuthRef: 'PA-2024-00456',
processNote: [
{ number: 1, text: 'Approved for total knee replacement. Valid for 90 days.' },
],
});
```
## Denied Claim
```ts theme={null}
const { data: denied } = await clinik.claimResponses.create({
status: 'active',
type: 'professional',
use: 'claim',
patientId: 'pt_abc123',
insurerId: 'org_ins789',
requestId: 'claim_denied789',
outcome: 'error',
disposition: 'Claim denied — service not covered under current plan',
processNote: [
{ number: 1, text: 'CPT 99215 requires prior authorization for this plan type' },
],
});
```
## Search Claim Responses
```ts theme={null}
// All responses for a patient
const { data } = await clinik.claimResponses.search({
patientId: 'pt_abc123',
});
// Find response for a specific claim
const { data: forClaim } = await clinik.claimResponses.search({
requestId: 'claim_xyz456',
});
// Filter by outcome
const { data: errors } = await clinik.claimResponses.search({
patientId: 'pt_abc123',
outcome: 'error',
});
```
## Outcome Types
| Outcome | Description |
| - | - |
| `queued` | Claim is queued for processing |
| `complete` | Processing is complete |
| `error` | Claim was denied or had errors |
| `partial` | Partially processed |
# Claims
Source: https://docs.clinikapi.com/guides/claims
Submit and manage healthcare billing claims for insurance reimbursement.
# Claims
Claims (FHIR `Claim`) represent healthcare billing requests submitted to insurers for reimbursement. ClinikAPI simplifies the most common claim fields — for advanced scenarios like coordination of benefits or detailed sub-items, use the [FHIR passthrough](/guides/raw-fhir).
## Submit a Professional Claim
```ts theme={null}
const { data: claim } = await clinik.claims.create({
status: 'active',
type: 'professional',
use: 'claim',
patientId: 'pt_abc123',
providerId: 'Practitioner/prac_dr456',
priority: 'normal',
billablePeriod: {
start: '2024-03-15',
end: '2024-03-15',
},
insurance: [
{ sequence: 1, focal: true, coverageId: 'cov_primary789' },
],
diagnosis: [
{ sequence: 1, code: 'E11.9' }, // Type 2 diabetes
{ sequence: 2, code: 'I10' }, // Essential hypertension
],
item: [
{
sequence: 1,
productOrService: '99214',
unitPrice: { value: 200.00, currency: 'USD' },
net: { value: 200.00, currency: 'USD' },
},
{
sequence: 2,
productOrService: '85025',
quantity: { value: 1, unit: 'test' },
unitPrice: { value: 45.00, currency: 'USD' },
net: { value: 45.00, currency: 'USD' },
},
],
total: { value: 245.00, currency: 'USD' },
});
```
## Pre-Authorization Request
```ts theme={null}
const { data: preAuth } = await clinik.claims.create({
status: 'active',
type: 'professional',
use: 'preauthorization',
patientId: 'pt_abc123',
providerId: 'Practitioner/prac_surgeon456',
priority: 'normal',
insurance: [
{ sequence: 1, focal: true, coverageId: 'cov_primary789' },
],
diagnosis: [
{ sequence: 1, code: 'M17.11' }, // Primary osteoarthritis, right knee
],
procedure: [
{ sequence: 1, code: '27447', date: '2024-04-15' }, // Total knee replacement
],
item: [
{
sequence: 1,
productOrService: '27447',
unitPrice: { value: 35000.00, currency: 'USD' },
net: { value: 35000.00, currency: 'USD' },
},
],
total: { value: 35000.00, currency: 'USD' },
note: 'Conservative treatment failed after 6 months of physical therapy',
});
```
## Search Claims
```ts theme={null}
// All claims for a patient
const { data } = await clinik.claims.search({
patientId: 'pt_abc123',
});
// Filter by status and use
const { data: activeClaims } = await clinik.claims.search({
patientId: 'pt_abc123',
status: 'active',
use: 'claim',
});
// Filter by date range
const { data: recent } = await clinik.claims.search({
dateFrom: '2024-01-01',
dateTo: '2024-03-31',
providerId: 'Practitioner/prac_dr456',
});
```
## Claim Types
| Type | Description |
| - | - |
| `institutional` | Hospital / facility claims |
| `oral` | Dental claims |
| `pharmacy` | Pharmacy claims |
| `professional` | Physician / provider claims |
| `vision` | Vision care claims |
# Conditions
Source: https://docs.clinikapi.com/guides/conditions
Record and track patient diagnoses, problems, and health concerns.
# Conditions
Conditions (FHIR `Condition`) represent clinical diagnoses, problems, and health concerns. They support the problem list, encounter diagnoses, staging, and evidence tracking throughout the condition lifecycle.
## Record a Diagnosis
```ts theme={null}
const { data: condition } = await clinik.conditions.create({
patientId: 'pt_abc123',
clinicalStatus: 'active',
verificationStatus: 'confirmed',
category: ['encounter-diagnosis'],
severity: 'moderate',
code: {
system: 'http://hl7.org/fhir/sid/icd-10-cm',
code: 'E11.9',
display: 'Type 2 diabetes mellitus without complications',
},
encounterId: 'enc_visit456',
onsetDateTime: '2023-08-15',
recordedDate: '2024-01-10',
recorderId: 'pract_dr456',
note: 'Patient presents with elevated HbA1c of 7.8%. Starting metformin.',
});
```
## Problem List Entry
```ts theme={null}
const { data: problem } = await clinik.conditions.create({
patientId: 'pt_abc123',
clinicalStatus: 'active',
verificationStatus: 'confirmed',
category: ['problem-list-item'],
code: {
system: 'http://snomed.info/sct',
code: '38341003',
display: 'Hypertension',
},
onsetString: 'Diagnosed in 2020',
stage: [
{ summary: 'Stage 2', type: 'clinical' },
],
evidence: [
{ code: ['Elevated blood pressure readings'] },
],
});
```
## Condition with Staging and Evidence
```ts theme={null}
const { data: cancer } = await clinik.conditions.create({
patientId: 'pt_abc123',
clinicalStatus: 'active',
verificationStatus: 'confirmed',
category: ['problem-list-item'],
severity: 'severe',
code: {
system: 'http://snomed.info/sct',
code: '254837009',
display: 'Malignant neoplasm of breast',
},
bodySite: ['Left breast'],
onsetDateTime: '2024-02-01',
recordedDate: '2024-02-15',
stage: [
{ summary: 'Stage IIA', type: 'pathological' },
],
evidence: [
{ code: ['Mammography findings', 'Biopsy results'] },
{ detailIds: ['obs_mammo123', 'obs_biopsy456'] },
],
});
```
## Mark a Condition as Resolved
```ts theme={null}
await clinik.conditions.update(condition.id, {
clinicalStatus: 'resolved',
abatementDateTime: '2024-06-01',
note: 'HbA1c normalized. Condition resolved with lifestyle changes.',
});
```
## Search Conditions
```ts theme={null}
// Active conditions for a patient
const { data } = await clinik.conditions.search({
patientId: 'pt_abc123',
clinicalStatus: 'active',
});
// Problem list items
const { data: problems } = await clinik.conditions.search({
patientId: 'pt_abc123',
category: 'problem-list-item',
});
// Search by ICD-10 code
const { data: diabetes } = await clinik.conditions.search({
code: 'E11.9',
});
```
## Clinical Status Lifecycle
| Status | Description |
| - | - |
| `active` | Condition is currently active |
| `recurrence` | Condition has recurred after resolution |
| `relapse` | Condition has relapsed after remission |
| `inactive` | Condition is no longer active |
| `remission` | Condition is in remission |
| `resolved` | Condition is fully resolved |
# Consents
Source: https://docs.clinikapi.com/guides/consents
Manage patient consent documents for privacy, treatment, and research.
# Consents
Consents track patient agreements to privacy policies, treatment plans, research participation, and advance directives.
## Sign a Consent
```ts theme={null}
// HIPAA privacy notice
const { data: hipaa } = await clinik.consents.sign({
patientId: 'pt_abc123',
status: 'active',
scope: 'patient-privacy',
category: 'hipaa-notice',
policyUri: 'https://clinic.com/hipaa-notice',
policyRule: 'HIPAA-Auth',
verification: [{
verified: true,
verifiedWith: 'pt_abc123',
verificationDate: '2025-01-15T10:00:00Z',
}],
});
// Treatment consent with provisions and attestation
const { data: treatment } = await clinik.consents.sign({
patientId: 'pt_abc123',
status: 'active',
scope: 'treatment',
category: ['treatment-consent', 'surgical-consent'],
performerId: 'prac_def456',
organizationId: 'org_ghi789',
policies: [
{ authority: 'https://clinic.com', uri: 'https://clinic.com/treatment-policy' },
{ authority: 'https://clinic.com', uri: 'https://clinic.com/surgical-policy' },
],
provision: {
type: 'permit',
period: {
start: '2025-01-15',
end: '2025-07-15',
},
purpose: [
{ system: 'http://terminology.hl7.org/CodeSystem/v3-ActReason', code: 'TREAT', display: 'Treatment' },
],
action: [
{ code: 'access', display: 'Access' },
{ code: 'use', display: 'Use' },
],
},
});
```
## Source Documents
Link a consent to its source document:
```ts theme={null}
// From an attachment
const { data } = await clinik.consents.sign({
patientId: 'pt_abc123',
scope: 'treatment',
category: 'surgical-consent',
sourceAttachment: {
contentType: 'application/pdf',
url: 'https://storage.clinic.com/consents/signed-form.pdf',
title: 'Signed Surgical Consent Form',
},
// ...
});
// From a reference (e.g. a QuestionnaireResponse)
const { data: fromForm } = await clinik.consents.sign({
patientId: 'pt_abc123',
scope: 'research',
category: 'research-participation',
sourceReferenceId: 'QuestionnaireResponse/intake_consent_form',
// ...
});
```
## Multiple Verifications
Track multiple verification events:
```ts theme={null}
const { data } = await clinik.consents.sign({
patientId: 'pt_abc123',
scope: 'treatment',
category: 'surgical-consent',
verification: [
{
verified: true,
verifiedWith: 'pt_abc123',
verificationDate: '2025-01-15T09:00:00Z',
},
{
verified: true,
verifiedWith: 'related_person_spouse',
verificationDate: '2025-01-15T09:30:00Z',
},
],
// ...
});
```
## Provisions with Data Control
Control access to specific data:
```ts theme={null}
provision: {
type: 'permit',
period: { start: '2025-01-01', end: '2025-12-31' },
purpose: [
{ code: 'TREAT', display: 'Treatment' },
{ code: 'HPAYMT', display: 'Healthcare Payment' },
],
action: [
{ code: 'access', display: 'Access' },
{ code: 'use', display: 'Use' },
],
securityLabel: [
{ system: 'http://terminology.hl7.org/CodeSystem/v3-Confidentiality', code: 'R', display: 'Restricted' },
],
data: [
{ meaning: 'instance', reference: 'DiagnosticReport/lab_hiv_001' },
{ meaning: 'related', reference: 'Condition/cond_mental_health' },
],
dataPeriod: { start: '2024-01-01', end: '2025-12-31' },
// Nested exception: deny research use
provision: [{
type: 'deny',
purpose: [{ code: 'HRESCH', display: 'Healthcare Research' }],
}],
}
```
## Consent Scopes
| Scope | Description | Examples |
| - | - | - |
| `patient-privacy` | Privacy and data sharing | HIPAA notice, data sharing agreement |
| `treatment` | Treatment authorization | Surgical consent, procedure consent |
| `research` | Research participation | Clinical trial enrollment |
| `adr` | Advance directive | Living will, DNR |
## Status Lifecycle
`draft` → `proposed` → `active` → `inactive` / `rejected`
## Revoke a Consent
```ts theme={null}
await clinik.consents.update('consent_abc123', {
status: 'inactive',
});
```
## Search Consents
```ts theme={null}
const { data } = await clinik.consents.search({
patientId: 'pt_abc123',
status: 'active',
});
```
# Coverages
Source: https://docs.clinikapi.com/guides/coverages
Manage insurance coverage records for patients.
# Coverages
Coverages (FHIR `Coverage`) represent a patient's insurance plan details — the payor, subscriber info, plan class, and coverage period. ClinikAPI simplifies the most common coverage fields — for advanced scenarios like cost-to-beneficiary or exception details, use the [FHIR passthrough](/guides/raw-fhir).
## Create a Coverage
```ts theme={null}
const { data: coverage } = await clinik.coverages.create({
status: 'active',
patientId: 'pt_abc123',
type: 'medical',
subscriberId: 'SUB-98765',
subscriberRef: 'Patient/pt_abc123',
relationship: 'self',
payorIds: ['org_ins_bluecross'],
period: {
start: '2024-01-01',
end: '2024-12-31',
},
class: [
{ type: 'group', value: 'GRP-100', name: 'Employer Group Plan' },
{ type: 'plan', value: 'PLN-GOLD', name: 'Gold PPO' },
],
network: 'PPO Network',
});
```
## Dependent Coverage
```ts theme={null}
const { data: dependent } = await clinik.coverages.create({
status: 'active',
patientId: 'pt_child456',
type: 'medical',
subscriberId: 'SUB-98765',
subscriberRef: 'Patient/pt_abc123',
policyHolderRef: 'Patient/pt_abc123',
relationship: 'child',
payorIds: ['org_ins_bluecross'],
period: {
start: '2024-01-01',
end: '2024-12-31',
},
class: [
{ type: 'group', value: 'GRP-100', name: 'Employer Group Plan' },
{ type: 'plan', value: 'PLN-GOLD', name: 'Gold PPO' },
],
dependent: '1',
order: 1,
});
```
## Search Coverages
```ts theme={null}
// All coverages for a patient
const { data } = await clinik.coverages.search({
patientId: 'pt_abc123',
});
// Active coverages only
const { data: active } = await clinik.coverages.search({
patientId: 'pt_abc123',
status: 'active',
});
// Filter by type
const { data: dental } = await clinik.coverages.search({
patientId: 'pt_abc123',
type: 'dental',
});
```
## Update a Coverage
```ts theme={null}
const { data: updated } = await clinik.coverages.update('cov_abc123', {
status: 'cancelled',
});
```
## Coverage Types
| Type | Description |
| - | - |
| `medical` | Medical/health insurance |
| `dental` | Dental insurance |
| `vision` | Vision insurance |
| `pharmacy` | Pharmacy benefits |
# Device Requests
Source: https://docs.clinikapi.com/guides/device-requests
Order and request devices for patient care.
# Device Requests
Device Requests (FHIR `DeviceRequest`) represent orders or proposals for a device to be provided or used for a patient. They support the full ordering lifecycle from proposal through completion.
## Create a Device Request
```ts theme={null}
const { data: request } = await clinik.deviceRequests.create({
intent: 'order',
code: 'Continuous Glucose Monitor',
patientId: 'pt_abc123',
status: 'active',
priority: 'routine',
requesterId: 'prac_dr456',
occurrenceDateTime: '2024-03-01',
reasonCode: ['Type 2 Diabetes — glucose monitoring'],
note: 'Patient to use CGM for 14-day glucose monitoring cycle',
});
```
## Using Coded Devices
You can use coded values for precise device identification:
```ts theme={null}
const { data } = await clinik.deviceRequests.create({
intent: 'order',
code: {
system: 'http://snomed.info/sct',
code: '706689003',
display: 'Continuous glucose monitoring system',
},
patientId: 'pt_abc123',
priority: 'urgent',
requesterId: 'prac_dr456',
});
```
## Request Lifecycle
```ts theme={null}
// Draft → Active → Completed
await clinik.deviceRequests.update(request.id, {
status: 'completed',
note: 'CGM delivered and activated for patient',
});
```
## Search Device Requests
```ts theme={null}
// Find all active device requests for a patient
const { data } = await clinik.deviceRequests.search({
patientId: 'pt_abc123',
status: 'active',
});
// Find all orders
const { data: orders } = await clinik.deviceRequests.search({
intent: 'order',
status: 'active',
});
```
## Intent Values
| Intent | Description |
| - | - |
| `proposal` | Suggestion for device use |
| `plan` | Planned device use |
| `directive` | Patient or related person request |
| `order` | Formal order for device |
| `original-order` | Original order from requester |
| `reflex-order` | Auto-generated order |
| `filler-order` | Order from fulfiller |
| `instance-order` | Specific instance of an order |
| `option` | Option for consideration |
# Device Use Statements
Source: https://docs.clinikapi.com/guides/device-use-statements
Record when and how devices are used on patients.
# Device Use Statements
Device Use Statements (FHIR `DeviceUseStatement`) record the actual use of a device on a patient. While Device Requests capture the order, Device Use Statements capture what actually happened.
## Record Device Use
```ts theme={null}
const { data: statement } = await clinik.deviceUseStatements.create({
status: 'active',
patientId: 'pt_abc123',
deviceId: 'dev_pacemaker789',
timingPeriod: {
start: '2024-01-15',
},
bodySite: 'Left chest wall',
reasonCode: ['Bradycardia management'],
sourceId: 'prac_dr456',
note: 'Dual-chamber pacemaker implanted, functioning normally',
});
```
## Record Completed Device Use
```ts theme={null}
const { data } = await clinik.deviceUseStatements.create({
status: 'completed',
patientId: 'pt_abc123',
deviceId: 'dev_cgm456',
timingPeriod: {
start: '2024-02-01',
end: '2024-02-14',
},
recordedOn: '2024-02-15',
reasonCode: ['Glucose monitoring for diabetes management'],
note: '14-day CGM cycle completed. Average glucose: 142 mg/dL',
});
```
## Update Statement Status
```ts theme={null}
await clinik.deviceUseStatements.update(statement.id, {
status: 'completed',
note: 'Pacemaker removed due to device recall',
});
```
## Search Device Use Statements
```ts theme={null}
// Find all active device use for a patient
const { data } = await clinik.deviceUseStatements.search({
patientId: 'pt_abc123',
status: 'active',
});
// Find all uses of a specific device
const { data: uses } = await clinik.deviceUseStatements.search({
deviceId: 'dev_pacemaker789',
});
```
## Status Values
| Status | Description |
| - | - |
| `active` | Device is currently in use |
| `completed` | Device use has ended |
| `on-hold` | Device use is temporarily paused |
| `intended` | Device use is planned but not started |
| `stopped` | Device use was stopped early |
| `not-done` | Device use was not performed |
# Devices
Source: https://docs.clinikapi.com/guides/devices
Track medical devices, equipment, and implantable hardware.
# Devices
Devices (FHIR `Device`) represent medical equipment, implantable hardware, and other devices used in patient care. They can be tracked by manufacturer, model, serial number, and UDI (Unique Device Identifier).
## Register a Device
```ts theme={null}
const { data: device } = await clinik.devices.create({
deviceName: 'Medtronic Pacemaker Model X200',
status: 'active',
manufacturer: 'Medtronic',
modelNumber: 'X200',
serialNumber: 'SN-2024-78432',
lotNumber: 'LOT-2024-A',
type: 'cardiac-pacemaker',
patientId: 'pt_abc123',
ownerId: 'org_sunrise456',
udiCarrier: [
{
deviceIdentifier: '08717648200274',
carrierHRF: '(01)08717648200274(17)240630(10)LOT-2024-A(21)SN-2024-78432',
},
],
safety: ['MR Conditional'],
});
```
## Device Hierarchy
Track parent-child relationships between devices:
```ts theme={null}
const { data: lead } = await clinik.devices.create({
deviceName: 'Pacemaker Lead - Right Ventricle',
status: 'active',
manufacturer: 'Medtronic',
type: 'pacemaker-lead',
parentId: device.id,
patientId: 'pt_abc123',
});
```
## Update Device Location
```ts theme={null}
await clinik.devices.update(device.id, {
locationId: 'loc_cardiology789',
note: 'Transferred to cardiology department for monitoring',
});
```
## Search Devices
```ts theme={null}
// Find all active devices for a patient
const { data } = await clinik.devices.search({
patientId: 'pt_abc123',
status: 'active',
});
// Find devices by manufacturer
const { data: medtronicDevices } = await clinik.devices.search({
manufacturer: 'Medtronic',
type: 'cardiac-pacemaker',
});
```
## Common Device Types
| Type | Description |
| - | - |
| `cardiac-pacemaker` | Implantable cardiac pacemaker |
| `insulin-pump` | Insulin delivery pump |
| `cgm` | Continuous glucose monitor |
| `ventilator` | Mechanical ventilator |
| `infusion-pump` | IV infusion pump |
| `prosthesis` | Prosthetic device |
| `hearing-aid` | Hearing aid device |
| `wheelchair` | Wheelchair or mobility device |
# Documents
Source: https://docs.clinikapi.com/guides/documents
Create structured clinical documents with sections — discharge summaries, care plans, referral letters.
# Documents
Documents (FHIR Composition) are structured clinical documents with titled sections. They're used for discharge summaries, referral letters, care plans, and other multi-section clinical documents.
## Create a Document
```ts theme={null}
const { data: doc } = await clinik.documents.create({
status: 'final',
type: 'discharge-summary',
category: ['clinical', 'inpatient'],
patientId: 'pt_abc123',
encounterId: 'enc_xyz789',
practitionerId: 'prac_def456',
title: 'Discharge Summary - Jane Doe - Jan 15, 2025',
date: '2025-01-15',
confidentiality: 'N',
attester: [{
mode: 'professional',
time: '2025-01-15T16:00:00Z',
partyId: 'prac_attending',
}],
custodianId: 'org_hospital',
event: [{
code: [{ code: 'inpatient-stay', display: 'Inpatient Stay' }],
period: { start: '2025-01-12', end: '2025-01-15' },
}],
sections: [
{
title: 'Chief Complaint',
code: 'chief-complaint',
text: 'Patient admitted for evaluation of acute chest pain.',
},
{
title: 'Hospital Course',
code: 'hospital-course',
text: 'Cardiac workup negative. Discharged in stable condition.',
authorId: 'prac_resident', // Resident wrote this section
},
{
title: 'Discharge Medications',
code: 'medications',
text: 'Continue aspirin 81mg daily, atorvastatin 20mg daily.',
resourceIds: ['rx_aspirin', 'rx_statin'],
},
{
title: 'Follow-up',
code: 'follow-up',
text: 'PCP: 1 week. Cardiology: 4 weeks.',
},
],
});
```
## Nested Sections
Sections can contain sub-sections for complex documents:
```ts theme={null}
sections: [
{
title: 'Physical Examination',
code: 'physical-exam',
text: 'General examination findings.',
sections: [
{
title: 'Cardiovascular',
code: 'cardiovascular',
text: 'Regular rate and rhythm. No murmurs, gallops, or rubs.',
},
{
title: 'Respiratory',
code: 'respiratory',
text: 'Clear to auscultation bilaterally. No wheezes or crackles.',
},
{
title: 'Neurological',
code: 'neurological',
text: 'Alert and oriented x3. Cranial nerves II-XII intact.',
},
],
},
]
```
## Document Attestation
Track who attested to the document's accuracy:
```ts theme={null}
attester: [
{
mode: 'professional',
time: '2025-01-15T16:00:00Z',
partyId: 'prac_attending',
},
{
mode: 'legal',
time: '2025-01-15T17:00:00Z',
partyId: 'prac_chief_medical_officer',
},
]
```
| Mode | Description |
| - | - |
| `personal` | Attested by the individual |
| `professional` | Attested in a professional capacity |
| `legal` | Legally attested |
| `official` | Officially attested |
## Document Relationships
Link documents to other compositions they replace or append:
```ts theme={null}
// Create an amended version
const { data } = await clinik.documents.create({
status: 'amended',
type: 'discharge-summary',
patientId: 'pt_abc123',
practitionerId: 'prac_def456',
title: 'Discharge Summary - Amended',
relatesTo: [{
code: 'replaces',
targetId: 'doc_original_001',
}],
sections: [/* ... */],
});
```
## Clinical Events
Document the clinical services being described:
```ts theme={null}
event: [
{
code: [{ code: 'surgical-procedure', display: 'Surgical Procedure' }],
period: { start: '2025-01-14T08:00:00Z', end: '2025-01-14T11:30:00Z' },
detailIds: ['proc_knee_replacement'],
},
]
```
## Document Types
| Type | Description |
| - | - |
| `discharge-summary` | Hospital discharge documentation |
| `referral-letter` | Referral to another provider |
| `care-plan` | Patient care plan |
| `operative-report` | Surgical operation report |
| `transfer-summary` | Patient transfer documentation |
| `consultation-report` | Specialist consultation report |
## Confidentiality Levels
| Code | Level | Description |
| - | - | - |
| `N` | Normal | Standard clinical document |
| `R` | Restricted | Limited access |
| `V` | Very Restricted | Highly sensitive |
## Update a Document
```ts theme={null}
await clinik.documents.update('doc_abc123', {
status: 'amended',
attester: [{
mode: 'professional',
time: new Date().toISOString(),
partyId: 'prac_attending',
}],
sections: [
{
title: 'Addendum',
code: 'addendum',
text: 'Patient called post-discharge reporting mild nausea.',
},
],
});
```
## Search Documents
```ts theme={null}
const { data } = await clinik.documents.search({
patientId: 'pt_abc123',
type: 'discharge-summary',
status: 'final',
sort: '-date',
});
```
## Documents vs Notes
| Resource | FHIR Type | Structure | Use Case |
| - | - | - | - |
| Note | DocumentReference | Single content block | Progress notes, SOAP notes |
| Document | Composition | Multiple titled sections | Discharge summaries, care plans |
# Eligibility Requests
Source: https://docs.clinikapi.com/guides/eligibility-requests
Check insurance eligibility and benefits for patients.
# Eligibility Requests
Eligibility Requests (FHIR `CoverageEligibilityRequest`) are used to check whether a patient's insurance covers specific services. ClinikAPI simplifies the most common fields — for advanced scenarios, use the [FHIR passthrough](/guides/raw-fhir).
## Check Benefits
```ts theme={null}
const { data: request } = await clinik.eligibilityRequests.create({
status: 'active',
purpose: ['benefits'],
patientId: 'pt_abc123',
insurerId: 'org_ins_bluecross',
providerId: 'Practitioner/prac_dr456',
servicedDate: '2024-06-15',
insurance: [
{ focal: true, coverageId: 'cov_primary789' },
],
});
```
## Pre-Authorization Check
```ts theme={null}
const { data: preAuth } = await clinik.eligibilityRequests.create({
status: 'active',
purpose: ['auth-requirements'],
patientId: 'pt_abc123',
insurerId: 'org_ins_bluecross',
providerId: 'Practitioner/prac_surgeon456',
servicedPeriod: {
start: '2024-07-01',
end: '2024-07-01',
},
insurance: [
{ focal: true, coverageId: 'cov_primary789' },
],
item: [
{ category: 'surgical', productOrService: '27447' },
],
});
```
## Discovery Request
```ts theme={null}
const { data: discovery } = await clinik.eligibilityRequests.create({
status: 'active',
purpose: ['discovery'],
patientId: 'pt_abc123',
insurerId: 'org_ins_bluecross',
});
```
## Search Eligibility Requests
```ts theme={null}
// All requests for a patient
const { data } = await clinik.eligibilityRequests.search({
patientId: 'pt_abc123',
});
// Filter by date range
const { data: recent } = await clinik.eligibilityRequests.search({
patientId: 'pt_abc123',
dateFrom: '2024-01-01',
dateTo: '2024-06-30',
});
```
## Purpose Codes
| Purpose | Description |
| - | - |
| `auth-requirements` | Check authorization requirements |
| `benefits` | Check benefit coverage |
| `discovery` | Discover available coverage |
| `validation` | Validate coverage is active |
# Eligibility Responses
Source: https://docs.clinikapi.com/guides/eligibility-responses
Process insurance eligibility check results.
# Eligibility Responses
Eligibility Responses (FHIR `CoverageEligibilityResponse`) contain the results of an eligibility check — whether coverage is active, what benefits are available, and any errors. ClinikAPI simplifies the most common fields — for advanced benefit detail scenarios, use the [FHIR passthrough](/guides/raw-fhir).
## Create an Eligibility Response
```ts theme={null}
const { data: response } = await clinik.eligibilityResponses.create({
status: 'active',
purpose: ['benefits'],
patientId: 'pt_abc123',
insurerId: 'org_ins_bluecross',
requestId: 'eligreq_xyz456',
outcome: 'complete',
disposition: 'Coverage is active with standard benefits',
insurance: [
{
coverageId: 'cov_primary789',
inforce: true,
benefitPeriod: {
start: '2024-01-01',
end: '2024-12-31',
},
},
],
});
```
## Eligibility Error
```ts theme={null}
const { data: errorResp } = await clinik.eligibilityResponses.create({
status: 'active',
purpose: ['validation'],
patientId: 'pt_abc123',
insurerId: 'org_ins_bluecross',
requestId: 'eligreq_check789',
outcome: 'error',
disposition: 'Coverage not found for subscriber',
error: [
{ code: 'subscriber-not-found' },
],
});
```
## Pre-Auth Response
```ts theme={null}
const { data: preAuthResp } = await clinik.eligibilityResponses.create({
status: 'active',
purpose: ['auth-requirements'],
patientId: 'pt_abc123',
insurerId: 'org_ins_bluecross',
requestId: 'eligreq_preauth123',
outcome: 'complete',
disposition: 'Prior authorization required for this procedure',
preAuthRef: 'PA-REQ-2024-00789',
insurance: [
{
coverageId: 'cov_primary789',
inforce: true,
},
],
});
```
## Search Eligibility Responses
```ts theme={null}
// All responses for a patient
const { data } = await clinik.eligibilityResponses.search({
patientId: 'pt_abc123',
});
// Find response for a specific request
const { data: forRequest } = await clinik.eligibilityResponses.search({
requestId: 'eligreq_xyz456',
});
// Filter by outcome
const { data: errors } = await clinik.eligibilityResponses.search({
patientId: 'pt_abc123',
outcome: 'error',
});
```
## Outcome Types
| Outcome | Description |
| - | - |
| `queued` | Request is queued for processing |
| `complete` | Processing is complete |
| `error` | Request had errors |
| `partial` | Partially processed |
# Encounters
Source: https://docs.clinikapi.com/guides/encounters
Track clinical visits, admissions, and telehealth sessions.
# Encounters
An encounter represents a clinical interaction — an office visit, hospital admission, telehealth session, or emergency room visit.
## Create an Encounter
```ts theme={null}
const { data: encounter } = await clinik.encounters.create({
status: 'in-progress',
class: 'AMB', // ambulatory
patientId: 'pt_abc123',
practitionerId: 'prac_def456',
participants: [
{ practitionerId: 'prac_nurse01', role: 'nurse' },
],
type: 'Annual wellness visit',
serviceType: 'General Practice',
reasonCode: 'Routine health maintenance',
period: {
start: '2025-01-15T09:00:00Z',
},
location: 'Main Clinic - Room 204',
serviceProvider: 'Austin Family Medicine',
appointmentId: 'appt_abc123',
diagnosis: [
{ condition: 'Essential hypertension', use: 'AD', rank: 1 },
{ condition: 'Type 2 diabetes mellitus', use: 'DD', rank: 2 },
],
});
```
### Encounter Classes
| Code | Description |
| - | - |
| `AMB` | Ambulatory (outpatient visit) |
| `IMP` | Inpatient (hospital admission) |
| `EMER` | Emergency |
| `HH` | Home health |
| `VR` | Virtual / telehealth |
### Status Values
`planned` → `arrived` → `triaged` → `in-progress` → `onleave` → `finished` / `cancelled`
## Read an Encounter
```ts theme={null}
const { data: encounter } = await clinik.encounters.read('enc_xyz789');
```
## Update an Encounter
```ts theme={null}
const { data: updated } = await clinik.encounters.update('enc_xyz789', {
status: 'finished',
period: {
start: '2025-01-15T09:00:00Z',
end: '2025-01-15T09:45:00Z',
},
lengthMinutes: 45,
serviceProvider: 'Austin Family Medicine',
diagnosis: [
{ condition: 'Essential hypertension', use: 'AD', rank: 1 },
{ condition: 'Type 2 diabetes mellitus', use: 'DD', rank: 2 },
{ condition: 'Obesity', use: 'DD', rank: 3 },
],
});
```
## Search Encounters
```ts theme={null}
const { data: results } = await clinik.encounters.search({
patientId: 'pt_abc123',
status: 'finished',
dateFrom: '2025-01-01',
dateTo: '2025-03-31',
sort: '-date', // newest first
count: 20,
});
```
## Inpatient Encounters
For hospital admissions, include hospitalization details:
```ts theme={null}
const { data: admission } = await clinik.encounters.create({
status: 'in-progress',
class: 'IMP', // inpatient
patientId: 'pt_abc123',
practitionerId: 'prac_def456',
type: 'Surgical admission',
reasonCode: ['Appendicitis', 'Acute abdominal pain'],
hospitalization: {
admitSource: 'Emergency department',
origin: 'Austin General ER',
dietPreference: ['regular'],
specialArrangement: ['wheelchair'],
},
location: 'Ward 3B - Bed 12',
});
// Discharge the patient
await clinik.encounters.update(admission.id!, {
status: 'finished',
hospitalization: {
admitSource: 'Emergency department',
dischargeDisposition: 'Home',
destination: 'Patient residence',
},
});
```
## Sub-Encounters
Link related encounters using `partOfId`:
```ts theme={null}
// Pre-op consultation as part of the admission
await clinik.encounters.create({
status: 'finished',
class: 'AMB',
patientId: 'pt_abc123',
practitionerId: 'prac_anesthesia01',
type: 'Pre-operative assessment',
partOfId: admission.id!,
});
```
## Linking Resources to Encounters
Most clinical resources reference an encounter:
```ts theme={null}
// Observation during an encounter
await clinik.observations.create({
status: 'final',
code: { system: 'http://loinc.org', code: '8867-4', display: 'Heart rate' },
patientId: 'pt_abc123',
encounterId: 'enc_xyz789',
valueQuantity: { value: 72, unit: 'beats/minute' },
});
// Note from the encounter
await clinik.notes.create({
patientId: 'pt_abc123',
encounterId: 'enc_xyz789',
authorId: 'prac_def456',
title: 'Visit Summary',
content: 'Patient presents for annual wellness visit...',
type: 'progress-note',
});
```
# Enrollment Requests
Source: https://docs.clinikapi.com/guides/enrollment-requests
Request insurance enrollment for patients with coverage and provider details.
# Enrollment Requests
Enrollment Requests (FHIR `EnrollmentRequest`) initiate the process of enrolling a patient in an insurance plan. They link the candidate patient to an insurer, provider, and coverage plan.
## Submit an Enrollment Request
```ts theme={null}
const { data: enrollment } = await clinik.enrollmentRequests.create({
candidateId: 'pt_abc123',
insurerId: 'org_bluecross456',
providerId: 'Practitioner/prac_dr789',
coverageId: 'cov_gold_plan001',
});
```
## Minimal Enrollment Request
Only the candidate (patient) is required:
```ts theme={null}
const { data } = await clinik.enrollmentRequests.create({
candidateId: 'pt_newpatient456',
});
```
## Draft Enrollment
Create a draft enrollment for later submission:
```ts theme={null}
const { data } = await clinik.enrollmentRequests.create({
status: 'draft',
candidateId: 'pt_abc123',
insurerId: 'org_aetna789',
providerId: 'Organization/org_clinic001',
});
```
## Cancel an Enrollment Request
```ts theme={null}
const { data } = await clinik.enrollmentRequests.update('enr_req_abc123', {
status: 'cancelled',
});
```
## Search Enrollment Requests
```ts theme={null}
// All enrollment requests for a patient
const { data } = await clinik.enrollmentRequests.search({
candidateId: 'pt_abc123',
});
// Filter by status
const { data: active } = await clinik.enrollmentRequests.search({
status: 'active',
});
// Filter by insurer
const { data: byInsurer } = await clinik.enrollmentRequests.search({
insurerId: 'org_bluecross456',
});
```
# Enrollment Responses
Source: https://docs.clinikapi.com/guides/enrollment-responses
Track insurer responses to enrollment requests with outcomes and dispositions.
# Enrollment Responses
Enrollment Responses (FHIR `EnrollmentResponse`) capture the insurer's decision on an enrollment request. Track whether enrollment was approved, queued for processing, or encountered an error.
## Record an Enrollment Approval
```ts theme={null}
const { data: response } = await clinik.enrollmentResponses.create({
requestId: 'enr_req_abc123',
outcome: 'complete',
disposition: 'Enrollment approved. Coverage effective 2024-04-01.',
organizationId: 'org_bluecross456',
requestProviderId: 'Practitioner/prac_dr789',
});
```
## Queued for Processing
```ts theme={null}
const { data } = await clinik.enrollmentResponses.create({
requestId: 'enr_req_def456',
outcome: 'queued',
disposition: 'Enrollment request received. Processing within 5 business days.',
organizationId: 'org_aetna789',
});
```
## Record an Enrollment Denial
```ts theme={null}
const { data } = await clinik.enrollmentResponses.create({
requestId: 'enr_req_ghi789',
outcome: 'error',
disposition: 'Enrollment denied — patient does not meet eligibility criteria for selected plan.',
organizationId: 'org_cigna001',
});
```
## Update Disposition
```ts theme={null}
const { data } = await clinik.enrollmentResponses.update('enr_resp_abc123', {
disposition: 'Updated: Enrollment approved after additional documentation received.',
});
```
## Search Enrollment Responses
```ts theme={null}
// Filter by outcome
const { data } = await clinik.enrollmentResponses.search({
outcome: 'complete',
});
// Filter by status
const { data: active } = await clinik.enrollmentResponses.search({
status: 'active',
});
```
# Explanation of Benefits
Source: https://docs.clinikapi.com/guides/eobs
Track insurance adjudication results and payment details.
# Explanation of Benefits
Explanation of Benefits (FHIR `ExplanationOfBenefit`) provide a complete picture of how a claim was adjudicated — what was submitted, what was allowed, what the insurer paid, and what the patient owes. ClinikAPI simplifies the most common fields — for advanced scenarios like care team details or benefit balances, use the [FHIR passthrough](/guides/raw-fhir).
## Create an EOB
```ts theme={null}
const { data: eob } = await clinik.eobs.create({
status: 'active',
type: 'professional',
use: 'claim',
patientId: 'pt_abc123',
insurerId: 'org_ins_bluecross',
providerId: 'Practitioner/prac_dr456',
outcome: 'complete',
claimId: 'claim_xyz456',
claimResponseId: 'claimresp_abc789',
billablePeriod: {
start: '2024-03-15',
end: '2024-03-15',
},
insurance: [
{ focal: true, coverageId: 'cov_primary789' },
],
item: [
{
sequence: 1,
productOrService: '99214',
unitPrice: { value: 200.00, currency: 'USD' },
net: { value: 200.00, currency: 'USD' },
adjudication: [
{ category: 'submitted', amount: { value: 200.00, currency: 'USD' } },
{ category: 'eligible', amount: { value: 180.00, currency: 'USD' } },
{ category: 'benefit', amount: { value: 144.00, currency: 'USD' } },
{ category: 'copay', amount: { value: 36.00, currency: 'USD' } },
],
},
],
total: [
{ category: 'submitted', amount: { value: 200.00, currency: 'USD' } },
{ category: 'benefit', amount: { value: 144.00, currency: 'USD' } },
{ category: 'patient', amount: { value: 56.00, currency: 'USD' } },
],
payment: {
type: 'complete',
amount: { value: 144.00, currency: 'USD' },
date: '2024-04-01',
},
});
```
## Denied EOB
```ts theme={null}
const { data: denied } = await clinik.eobs.create({
status: 'active',
type: 'professional',
use: 'claim',
patientId: 'pt_abc123',
insurerId: 'org_ins_bluecross',
providerId: 'Practitioner/prac_dr456',
outcome: 'error',
disposition: 'Service not covered under current plan',
insurance: [
{ focal: true, coverageId: 'cov_primary789' },
],
processNote: [
{ number: 1, text: 'CPT 99215 requires prior authorization for this plan type' },
],
});
```
## Search EOBs
```ts theme={null}
// All EOBs for a patient
const { data } = await clinik.eobs.search({
patientId: 'pt_abc123',
});
// Find EOBs for a specific claim
const { data: forClaim } = await clinik.eobs.search({
claimId: 'claim_xyz456',
});
// Filter by outcome
const { data: completed } = await clinik.eobs.search({
patientId: 'pt_abc123',
outcome: 'complete',
use: 'claim',
});
```
## EOB Types
| Type | Description |
| - | - |
| `institutional` | Hospital / facility EOBs |
| `oral` | Dental EOBs |
| `pharmacy` | Pharmacy EOBs |
| `professional` | Physician / provider EOBs |
| `vision` | Vision care EOBs |
# Family History
Source: https://docs.clinikapi.com/guides/family-history
Record family member health history for genetic risk assessment and clinical decision-making.
# Family History
Family Member History (FHIR `FamilyMemberHistory`) records significant health conditions for a person related to the patient. This is critical for genetic risk assessment, hereditary condition screening, and clinical decision-making.
## Record Family History
```ts theme={null}
const { data } = await clinik.familyHistory.create({
status: 'completed',
patientId: 'pt_jane_doe',
date: '2025-01-15',
name: 'Robert Doe',
relationship: 'father',
sex: 'male',
deceasedBoolean: true,
deceasedDate: '2020-06-10',
condition: [
{
code: 'Type 2 Diabetes Mellitus',
onsetString: 'Age 45',
note: 'Managed with metformin for 15 years',
},
{
code: 'Coronary Artery Disease',
contributedToDeath: true,
onsetString: 'Age 60',
outcome: 'Fatal myocardial infarction',
},
],
note: 'Father had significant cardiovascular risk factors including smoking history',
});
```
## Multiple Family Members
Build a complete family history by creating records for each relative:
```ts theme={null}
// Mother
await clinik.familyHistory.create({
status: 'completed',
patientId: 'pt_jane_doe',
name: 'Susan Doe',
relationship: 'mother',
sex: 'female',
ageString: '72 years old',
condition: [
{ code: 'Breast Cancer', onsetString: 'Age 55', outcome: 'In remission' },
{ code: 'Osteoporosis', onsetString: 'Age 65' },
],
});
// Maternal grandmother
await clinik.familyHistory.create({
status: 'completed',
patientId: 'pt_jane_doe',
name: 'Helen Smith',
relationship: 'maternal grandmother',
sex: 'female',
deceasedBoolean: true,
deceasedDate: '2010-03-20',
condition: [
{ code: 'Breast Cancer', contributedToDeath: true, onsetString: 'Age 62' },
],
});
```
## Status Values
| Status | Description |
| - | - |
| `partial` | History is still being collected |
| `completed` | History is complete |
| `health-unknown` | Health status of the family member is unknown |
## Unknown Family History
When a patient doesn't know their family history:
```ts theme={null}
await clinik.familyHistory.create({
status: 'health-unknown',
patientId: 'pt_adopted_patient',
relationship: 'father',
note: 'Patient was adopted — biological family history unknown',
});
```
## Search Family History
```ts theme={null}
// Get all family history for a patient
const { data } = await clinik.familyHistory.search({
patientId: 'pt_jane_doe',
status: 'completed',
});
```
# Goals
Source: https://docs.clinikapi.com/guides/goals
Set and track patient care goals with measurable targets.
# Goals
Goals (FHIR `Goal`) represent intended objectives for a patient's care. They support measurable targets, achievement tracking, and lifecycle management — from initial proposal through completion.
## Create a Clinical Goal
```ts theme={null}
const { data: goal } = await clinik.goals.create({
lifecycleStatus: 'active',
description: 'Reduce HbA1c to below 7%',
patientId: 'pt_abc123',
achievementStatus: 'in-progress',
category: ['treatment'],
priority: 'high-priority',
startDate: '2024-01-01',
target: [
{
measure: 'HbA1c',
detailQuantity: { value: 7, unit: '%' },
dueDate: '2024-06-30',
},
],
expressedById: 'prac_dr456',
addressesIds: ['cond_diabetes789'],
note: 'Patient motivated, starting metformin and dietary changes',
});
```
## Behavioral Goals
```ts theme={null}
const { data: exerciseGoal } = await clinik.goals.create({
lifecycleStatus: 'active',
description: 'Walk 30 minutes daily, 5 days per week',
patientId: 'pt_abc123',
category: ['behavioral'],
priority: 'medium-priority',
startDate: '2024-02-01',
target: [
{
measure: 'Exercise frequency',
detailString: '5 days per week, 30 minutes each',
dueDate: '2024-04-01',
},
],
});
```
## Weight Management Goal
```ts theme={null}
const { data: weightGoal } = await clinik.goals.create({
lifecycleStatus: 'active',
description: 'Achieve target weight of 180 lbs',
patientId: 'pt_abc123',
category: ['dietary'],
target: [
{
measure: 'Body weight',
detailQuantity: { value: 180, unit: 'lbs' },
dueDate: '2024-12-31',
},
],
});
```
## Update Goal Progress
```ts theme={null}
await clinik.goals.update(goal.id, {
achievementStatus: 'improving',
note: 'HbA1c dropped from 9.2% to 8.1% after 3 months',
});
// Mark goal as achieved
await clinik.goals.update(goal.id, {
lifecycleStatus: 'completed',
achievementStatus: 'achieved',
statusReason: 'HbA1c measured at 6.8% — target met',
});
```
## Search Goals
```ts theme={null}
// Find all active goals for a patient
const { data } = await clinik.goals.search({
patientId: 'pt_abc123',
lifecycleStatus: 'active',
});
// Find goals by achievement status
const { data: achieved } = await clinik.goals.search({
patientId: 'pt_abc123',
achievementStatus: 'achieved',
});
// Find goals by category
const { data: dietary } = await clinik.goals.search({
patientId: 'pt_abc123',
category: 'dietary',
});
```
## Lifecycle Status Values
| Status | Description |
| - | - |
| `proposed` | Goal has been suggested |
| `planned` | Goal is planned but not yet started |
| `accepted` | Goal has been accepted by the patient |
| `active` | Goal is being actively pursued |
| `on-hold` | Goal pursuit is temporarily paused |
| `completed` | Goal has been completed |
| `cancelled` | Goal was cancelled before completion |
| `rejected` | Goal was rejected by the patient |
# Healthcare Services
Source: https://docs.clinikapi.com/guides/healthcare-services
Define and manage clinical services with availability, specialties, and referral methods.
# Healthcare Services
Healthcare services (FHIR `HealthcareService`) describe the services offered by an organization — what specialties are available, when they're available, how to refer patients, and what languages are supported.
## Create a Service
```ts theme={null}
const { data: svc } = await clinik.healthcareServices.create({
name: 'Cardiology Consultation',
providedById: 'org_sunrise_medical',
category: ['specialist'],
type: ['cardiology-consultation'],
specialty: ['Cardiology'],
appointmentRequired: true,
availableTime: [
{
daysOfWeek: ['mon', 'wed', 'fri'],
availableStartTime: '09:00:00',
availableEndTime: '17:00:00',
},
{
daysOfWeek: ['tue', 'thu'],
availableStartTime: '08:00:00',
availableEndTime: '12:00:00',
},
],
notAvailable: [
{ description: 'Holiday closure', during: { start: '2025-12-24', end: '2025-12-26' } },
],
availabilityExceptions: 'Closed on federal holidays',
referralMethod: ['phone', 'fax', 'electronic'],
communication: ['en', 'es'],
comment: 'Accepts new patients. Referral required.',
});
```
## Availability
Define when the service is available and when it's not:
```ts theme={null}
// Available times
availableTime: [
{ daysOfWeek: ['mon', 'tue', 'wed', 'thu', 'fri'], availableStartTime: '08:00:00', availableEndTime: '17:00:00' },
{ daysOfWeek: ['sat'], availableStartTime: '09:00:00', availableEndTime: '13:00:00' },
]
// Blocked periods
notAvailable: [
{ description: 'Annual conference', during: { start: '2025-03-15', end: '2025-03-18' } },
{ description: 'Facility maintenance', during: { start: '2025-06-01', end: '2025-06-02' } },
]
```
## Search Services
```ts theme={null}
// Find cardiology services
const { data } = await clinik.healthcareServices.search({
specialty: 'Cardiology',
active: true,
});
// Find services by type
const { data: labs } = await clinik.healthcareServices.search({
type: 'laboratory',
});
```
## Healthcare Services vs Practitioner Roles
| Resource | Purpose |
| - | - |
| HealthcareService | What services an organization offers |
| PractitionerRole | What role a specific practitioner plays |
A practitioner role links a practitioner to an organization and defines their role. A healthcare service defines what the organization offers regardless of who specifically provides it.
# Imaging Studies
Source: https://docs.clinikapi.com/guides/imaging-studies
Manage radiology and diagnostic imaging exams with series-level detail.
# Imaging Studies
Imaging Studies (FHIR `ImagingStudy`) represent radiology and diagnostic imaging exams such as CT scans, MRIs, X-rays, and ultrasounds. ClinikAPI simplifies series to key fields — use the [FHIR passthrough](/guides/raw-fhir) for DICOM instance-level access.
## Record a CT Scan
```ts theme={null}
const { data: study } = await clinik.imagingStudies.create({
status: 'available',
patientId: 'pt_jane123',
encounterId: 'enc_er456',
modality: ['CT'],
started: '2024-03-15T10:00:00Z',
referrerId: 'prac_drSmith',
numberOfSeries: 2,
numberOfInstances: 120,
procedureCode: ['CT chest with contrast'],
locationId: 'loc_radiology',
description: 'CT Chest — rule out pulmonary embolism',
reasonCode: ['Shortness of breath', 'Chest pain'],
series: [
{
uid: '1.2.840.113619.2.55.3.604688119.969.1364202859.234',
number: 1,
modality: 'CT',
description: 'Axial images with contrast',
numberOfInstances: 80,
bodySite: 'Chest',
},
{
uid: '1.2.840.113619.2.55.3.604688119.969.1364202859.235',
number: 2,
modality: 'CT',
description: 'Coronal reformats',
numberOfInstances: 40,
bodySite: 'Chest',
},
],
basedOn: ['ServiceRequest/sr_ctChest789'],
});
```
## MRI Study
```ts theme={null}
const { data: mri } = await clinik.imagingStudies.create({
status: 'available',
patientId: 'pt_john456',
modality: ['MR'],
started: '2024-03-16T08:30:00Z',
referrerId: 'prac_drOrtho',
interpreterIds: ['prac_drRadiologist'],
numberOfSeries: 4,
numberOfInstances: 200,
procedureCode: ['MRI knee without contrast'],
description: 'MRI Right Knee — evaluate meniscal tear',
reasonCode: ['Right knee pain', 'Locking sensation'],
series: [
{
uid: '1.2.840.113619.2.55.3.604688119.969.1364202860.100',
number: 1,
modality: 'MR',
description: 'Sagittal PD fat-sat',
numberOfInstances: 50,
bodySite: 'Right knee',
laterality: 'R',
},
],
});
```
## Simple X-Ray (No Series Detail)
```ts theme={null}
const { data: xray } = await clinik.imagingStudies.create({
status: 'available',
patientId: 'pt_jane123',
modality: ['XR'],
started: '2024-03-15T11:00:00Z',
referrerId: 'prac_drSmith',
numberOfSeries: 1,
numberOfInstances: 2,
procedureCode: ['XR chest 2 views'],
description: 'Chest X-ray PA and lateral',
});
```
## Search Imaging Studies
```ts theme={null}
// All studies for a patient
const { data } = await clinik.imagingStudies.search({
patientId: 'pt_jane123',
});
// Filter by modality
const { data: ctScans } = await clinik.imagingStudies.search({
patientId: 'pt_jane123',
modality: 'CT',
});
// Filter by date range
const { data: recent } = await clinik.imagingStudies.search({
dateFrom: '2024-03-01',
dateTo: '2024-03-31',
status: 'available',
});
```
## Common Modalities
| Code | Description |
| - | - |
| `CT` | Computed Tomography |
| `MR` | Magnetic Resonance |
| `US` | Ultrasound |
| `XR` | X-Ray (Radiography) |
| `NM` | Nuclear Medicine |
| `PT` | PET Scan |
| `MG` | Mammography |
| `RF` | Fluoroscopy |
# Immunization Evaluations
Source: https://docs.clinikapi.com/guides/immunization-evaluations
Evaluate whether immunization events meet protocol requirements for target diseases.
# Immunization Evaluations
Immunization Evaluations (FHIR `ImmunizationEvaluation`) assess whether a specific immunization event satisfies the protocol requirements for a target disease. Use these to track vaccine series compliance and identify gaps in immunization schedules.
## Evaluate a Valid Dose
```ts theme={null}
const { data: evaluation } = await clinik.immunizationEvaluations.create({
status: 'completed',
patientId: 'pt_abc123',
date: '2024-03-20',
authorityId: 'org_cdc001',
targetDisease: 'COVID-19',
immunizationEventId: 'imm_vax456',
doseStatus: 'valid',
series: 'Primary Series',
doseNumber: 2,
seriesDoses: 2,
description: 'Second dose of primary series — patient is fully vaccinated',
});
```
## Evaluate an Invalid Dose
When a dose does not meet protocol requirements:
```ts theme={null}
const { data } = await clinik.immunizationEvaluations.create({
status: 'completed',
patientId: 'pt_child456',
date: '2024-03-15',
targetDisease: 'Measles',
immunizationEventId: 'imm_mmr789',
doseStatus: 'not-valid',
doseStatusReason: ['Administered before minimum age', 'Interval too short from previous dose'],
series: 'MMR Series',
doseNumber: 1,
seriesDoses: 2,
});
```
## Pediatric Vaccine Series Tracking
```ts theme={null}
const { data } = await clinik.immunizationEvaluations.create({
status: 'completed',
patientId: 'pt_infant001',
date: '2024-02-15',
authorityId: 'org_aap001',
targetDisease: 'Hepatitis B',
immunizationEventId: 'imm_hepb_dose3',
doseStatus: 'valid',
series: 'Hepatitis B 3-dose series',
doseNumber: 3,
seriesDoses: 3,
description: 'Third dose administered at 9 months — series complete',
});
```
## Search Immunization Evaluations
```ts theme={null}
// All evaluations for a patient
const { data } = await clinik.immunizationEvaluations.search({
patientId: 'pt_abc123',
});
// Filter by target disease
const { data: covidEvals } = await clinik.immunizationEvaluations.search({
patientId: 'pt_abc123',
targetDisease: 'COVID-19',
});
// Filter by immunization event
const { data: byEvent } = await clinik.immunizationEvaluations.search({
immunizationEventId: 'imm_vax456',
});
```
# Immunization Recommendations
Source: https://docs.clinikapi.com/guides/immunization-recommendations
Generate and track patient-specific vaccine recommendations based on immunization history.
# Immunization Recommendations
Immunization Recommendations (FHIR `ImmunizationRecommendation`) provide patient-specific vaccine recommendations. They are typically generated by clinical decision support systems based on a patient's immunization history and current guidelines.
## Create Recommendations for a Child
```ts theme={null}
const { data: recs } = await clinik.immunizationRecommendations.create({
patientId: 'pt_child456',
date: '2024-06-15T10:00:00Z',
authorityId: 'org_cdc',
recommendation: [
{
vaccineCode: ['MMR'],
targetDisease: 'Measles',
forecastStatus: 'due',
series: 'Primary Series',
doseNumber: 2,
seriesDoses: 2,
dateCriterion: [
{ code: 'Earliest Date', value: '2024-07-01' },
{ code: 'Recommended Date', value: '2024-08-15' },
{ code: 'Latest Date', value: '2024-12-31' },
],
},
{
vaccineCode: ['DTaP'],
targetDisease: 'Diphtheria',
forecastStatus: 'due',
series: 'Primary Series',
doseNumber: 5,
seriesDoses: 5,
dateCriterion: [
{ code: 'Recommended Date', value: '2024-09-01' },
],
},
{
vaccineCode: ['IPV'],
targetDisease: 'Polio',
forecastStatus: 'complete',
description: 'Series complete — no further doses needed',
doseNumber: 4,
seriesDoses: 4,
},
],
});
```
## Create Recommendations for an Adult
```ts theme={null}
const { data } = await clinik.immunizationRecommendations.create({
patientId: 'pt_adult789',
date: new Date().toISOString(),
recommendation: [
{
vaccineCode: ['Tdap', 'Td'],
targetDisease: 'Tetanus',
forecastStatus: 'overdue',
forecastReason: ['Last dose was more than 10 years ago'],
description: 'Tetanus booster overdue',
doseNumber: 1,
seriesDoses: 1,
},
{
vaccineCode: ['Influenza, seasonal, injectable'],
targetDisease: 'Influenza',
forecastStatus: 'due',
description: 'Annual flu vaccine recommended',
dateCriterion: [
{ code: 'Recommended Date', value: '2024-10-01' },
],
},
{
vaccineCode: ['COVID-19 mRNA'],
targetDisease: 'COVID-19',
forecastStatus: 'due',
description: 'Updated booster recommended',
},
],
});
```
## Contraindicated Vaccine
```ts theme={null}
const { data } = await clinik.immunizationRecommendations.create({
patientId: 'pt_allergic001',
date: new Date().toISOString(),
recommendation: [{
vaccineCode: ['MMR'],
targetDisease: 'Measles',
forecastStatus: 'contraindicated',
forecastReason: ['Severe allergic reaction to previous dose'],
description: 'MMR contraindicated due to anaphylaxis history',
}],
});
```
## Search Recommendations
```ts theme={null}
// All recommendations for a patient
const { data } = await clinik.immunizationRecommendations.search({
patientId: 'pt_child456',
});
// Filter by target disease
const { data: measles } = await clinik.immunizationRecommendations.search({
targetDisease: 'Measles',
});
// Filter by vaccine code
const { data: mmr } = await clinik.immunizationRecommendations.search({
vaccineCode: 'MMR',
});
// Filter by date range
const { data: recent } = await clinik.immunizationRecommendations.search({
dateFrom: '2024-01-01',
dateTo: '2024-12-31',
});
```
# Immunizations
Source: https://docs.clinikapi.com/guides/immunizations
Record and track patient immunizations with vaccine details, reactions, and protocol tracking.
# Immunizations
Immunizations (FHIR `Immunization`) record vaccine administration events. Track vaccine details, lot numbers, dose sequences, reactions, and protocol compliance.
## Record an Immunization
```ts theme={null}
const { data: imm } = await clinik.immunizations.create({
status: 'completed',
vaccineCode: {
system: 'http://hl7.org/fhir/sid/cvx',
code: '208',
display: 'COVID-19 mRNA, LNP-S, PF, 30 mcg/0.3 mL dose',
},
patientId: 'pt_abc123',
occurrenceDateTime: '2024-03-15T10:30:00Z',
manufacturer: 'Pfizer-BioNTech',
lotNumber: 'EW0182',
expirationDate: '2024-09-30',
site: 'Left deltoid',
route: 'Intramuscular',
doseQuantity: { value: 0.3, unit: 'mL' },
performer: [
{ function: 'Ordering', actorId: 'prac_dr456' },
{ function: 'Administering', actorId: 'prac_nurse789' },
],
protocolApplied: [{
series: 'Primary Series',
doseNumber: 2,
seriesDoses: 2,
targetDisease: ['COVID-19'],
}],
note: 'Patient observed for 15 minutes, no adverse reaction',
});
```
## Simple Vaccine Code
For common vaccines, you can use a simple string:
```ts theme={null}
const { data } = await clinik.immunizations.create({
status: 'completed',
vaccineCode: 'Influenza, seasonal, injectable',
patientId: 'pt_abc123',
site: 'Right deltoid',
route: 'Intramuscular',
lotNumber: 'FL2024-A',
performer: [{ actorId: 'prac_nurse789' }],
});
```
## Record a Not-Done Immunization
When a vaccine was not administered:
```ts theme={null}
const { data } = await clinik.immunizations.create({
status: 'not-done',
vaccineCode: 'MMR',
patientId: 'pt_child456',
statusReason: 'Patient had active febrile illness',
});
```
## Track Reactions
```ts theme={null}
const { data } = await clinik.immunizations.create({
status: 'completed',
vaccineCode: 'Tdap',
patientId: 'pt_abc123',
site: 'Left deltoid',
route: 'Intramuscular',
performer: [{ actorId: 'prac_nurse789' }],
reaction: [
{ date: '2024-03-15', reported: true },
],
note: 'Mild soreness at injection site reported next day',
});
```
## Search Immunizations
```ts theme={null}
// All immunizations for a patient
const { data } = await clinik.immunizations.search({
patientId: 'pt_abc123',
});
// Filter by vaccine code
const { data: covidVax } = await clinik.immunizations.search({
patientId: 'pt_abc123',
vaccineCode: '208',
});
// Filter by date range
const { data: recent } = await clinik.immunizations.search({
patientId: 'pt_abc123',
dateFrom: '2024-01-01',
dateTo: '2024-12-31',
});
```
# Intakes
Source: https://docs.clinikapi.com/guides/intakes
Collect and manage patient intake forms as structured questionnaire responses.
# Intakes
Intakes capture patient intake forms as FHIR QuestionnaireResponse resources — structured question-answer pairs that can be queried, versioned, and linked to encounters.
## Submit an Intake Form
```ts theme={null}
const { data: intake } = await clinik.intakes.submit({
patientId: 'pt_abc123',
encounterId: 'enc_xyz789',
questionnaire: 'https://forms.clinikapi.com/new-patient-intake',
status: 'completed',
items: [
{
linkId: 'chief-complaint',
text: 'Primary reason for visit',
answer: [{ valueString: 'Persistent headaches for 2 weeks' }],
},
{
linkId: 'allergies',
text: 'Known allergies',
answer: [
{ valueString: 'Penicillin' },
{ valueString: 'Sulfa drugs' },
],
},
{
linkId: 'current-medications',
text: 'Current medications',
answer: [
{ valueString: 'Lisinopril 10mg daily' },
{ valueString: 'Metformin 500mg twice daily' },
],
},
{
linkId: 'pain-level',
text: 'Current pain level (0-10)',
answer: [{ valueInteger: 6 }],
},
{
linkId: 'temperature',
text: 'Body temperature',
answer: [{ valueQuantity: { value: 98.6, unit: '°F' } }],
},
{
linkId: 'smoking-status',
text: 'Smoking status',
answer: [{
valueCoding: {
system: 'http://snomed.info/sct',
code: '8517006',
display: 'Former smoker',
},
}],
},
],
});
```
## Based On / Part Of
Link intakes to the requests or procedures they fulfill:
```ts theme={null}
const { data } = await clinik.intakes.submit({
patientId: 'pt_abc123',
basedOn: ['sr_preop_assessment'], // ServiceRequest this fulfills
partOf: ['proc_surgery_001'], // Procedure this is part of
items: [
{ linkId: 'consent-confirmed', answer: [{ valueBoolean: true }] },
{ linkId: 'fasting-hours', answer: [{ valueInteger: 12 }] },
],
});
```
## Answer Types
| Type | Field | Example |
| - | - | - |
| Text | `valueString` | `"Persistent headaches"` |
| Yes/No | `valueBoolean` | `true` |
| Number | `valueInteger` | `6` |
| Decimal | `valueDecimal` | `98.6` |
| Date | `valueDate` | `"2024-06-15"` |
| Date-Time | `valueDateTime` | `"2025-01-15T10:00:00Z"` |
| Time | `valueTime` | `"14:30:00"` |
| Coded | `valueCoding` | `{ code: "8517006", display: "Former smoker" }` |
| Measurement | `valueQuantity` | `{ value: 165, unit: "lbs" }` |
| URI | `valueUri` | `"https://example.com/document"` |
## Nested Questions
Group related questions using nested `items` — supports unlimited depth:
```ts theme={null}
{
linkId: 'family-history',
text: 'Family Medical History',
items: [
{
linkId: 'fh-diabetes',
text: 'Family history of diabetes?',
answer: [{ valueBoolean: true }],
},
{
linkId: 'fh-heart-disease',
text: 'Family history of heart disease?',
answer: [{ valueBoolean: false }],
},
{
linkId: 'fh-details',
text: 'Details',
items: [
{
linkId: 'fh-diabetes-who',
text: 'Who has diabetes?',
answer: [{ valueString: 'Mother, maternal grandmother' }],
},
],
},
],
}
```
## Amend an Intake
```ts theme={null}
await clinik.intakes.update('intake_abc123', {
status: 'amended',
items: [
{
linkId: 'allergies',
text: 'Known allergies',
answer: [
{ valueString: 'Penicillin' },
{ valueString: 'Sulfa drugs' },
{ valueString: 'Latex' }, // newly reported
],
},
],
});
```
## Search Intakes
```ts theme={null}
const { data } = await clinik.intakes.search({
patientId: 'pt_abc123',
status: 'completed',
sort: '-date',
});
```
## Status Lifecycle
`in-progress` → `completed` → `amended` / `stopped`
# Invoices
Source: https://docs.clinikapi.com/guides/invoices
Create and manage healthcare billing invoices.
# Invoices
Invoices (FHIR `Invoice`) represent billing documents for healthcare services rendered. ClinikAPI simplifies the most common invoice fields — for advanced scenarios like complex price components or tax calculations, use the [FHIR passthrough](/guides/raw-fhir).
## Create an Invoice
```ts theme={null}
const { data: invoice } = await clinik.invoices.create({
status: 'issued',
patientId: 'pt_abc123',
type: 'professional-services',
issuerId: 'org_clinic456',
date: '2024-03-15',
lineItem: [
{
sequence: 1,
chargeItemCode: '99213',
priceComponent: [
{ type: 'base', amount: { value: 150.00, currency: 'USD' } },
],
},
{
sequence: 2,
chargeItemCode: '85025',
priceComponent: [
{ type: 'base', amount: { value: 45.00, currency: 'USD' } },
],
},
],
totalNet: { value: 195.00, currency: 'USD' },
totalGross: { value: 195.00, currency: 'USD' },
paymentTerms: 'Net 30',
});
```
## Draft Invoice
Create a draft invoice and issue it later:
```ts theme={null}
const { data: draft } = await clinik.invoices.create({
status: 'draft',
patientId: 'pt_abc123',
type: 'facility-charges',
lineItem: [
{
sequence: 1,
chargeItemCode: 'room-charge-semi-private',
priceComponent: [
{ type: 'base', amount: { value: 1200.00, currency: 'USD' } },
],
},
],
totalGross: { value: 1200.00, currency: 'USD' },
});
// Issue the invoice when ready
await clinik.invoices.update(draft.id, { status: 'issued' });
```
## Cancel an Invoice
```ts theme={null}
await clinik.invoices.update('inv_abc123', {
status: 'cancelled',
cancelledReason: 'Duplicate invoice — services already billed under INV-2024-001',
});
```
## Search Invoices
```ts theme={null}
// All invoices for a patient
const { data } = await clinik.invoices.search({
patientId: 'pt_abc123',
});
// Filter by status and date range
const { data: issued } = await clinik.invoices.search({
status: 'issued',
dateFrom: '2024-01-01',
dateTo: '2024-03-31',
});
// Filter by issuer
const { data: byClinic } = await clinik.invoices.search({
issuerId: 'org_clinic456',
status: 'balanced',
});
```
## Invoice Statuses
| Status | Description |
| - | - |
| `draft` | Invoice is being prepared |
| `issued` | Invoice has been sent to the recipient |
| `balanced` | Invoice has been fully paid |
| `cancelled` | Invoice has been cancelled |
## Complete Field Reference
| Field | Type | Required | Description |
| - | - | - | - |
| `status` | `string` | Yes | draft, issued, balanced, cancelled |
| `patientId` | `string` | No | Patient the invoice is for |
| `type` | `string` | No | Invoice type |
| `recipientId` | `string` | No | Recipient reference |
| `date` | `string` | No | Invoice date (defaults to now) |
| `issuerId` | `string` | No | Issuing Organization ID |
| `accountId` | `string` | No | Account ID |
| `participant` | `Array` | No | Participants involved |
| `lineItem` | `Array` | No | Line items with pricing |
| `totalNet` | `{ value, currency? }` | No | Total net amount |
| `totalGross` | `{ value, currency? }` | No | Total gross amount |
| `paymentTerms` | `string` | No | Payment terms |
| `cancelledReason` | `string` | No | Reason for cancellation |
| `note` | `string` | No | Additional notes |
# Labs
Source: https://docs.clinikapi.com/guides/labs
Create and manage diagnostic reports with linked observations.
# Labs
Labs (FHIR DiagnosticReport) represent diagnostic reports — lab panels, radiology reports, pathology results. They group related observations and provide clinical conclusions.
## Create a Lab Report
```ts theme={null}
const { data: lab } = await clinik.labs.create({
status: 'final',
code: {
system: 'http://loinc.org',
code: '24323-8',
display: 'Comprehensive metabolic 2000 panel',
},
patientId: 'pt_abc123',
encounterId: 'enc_xyz789',
category: 'LAB',
effectiveDateTime: '2025-01-15T10:30:00Z',
performer: 'prac_lab_tech',
resultsInterpreter: 'prac_def456',
resultIds: ['obs_glucose', 'obs_sodium', 'obs_potassium', 'obs_creatinine'],
conclusion: 'All values within normal limits. No significant abnormalities.',
conclusionCodes: [
{
system: 'http://snomed.info/sct',
code: '281900007',
display: 'No abnormality detected',
},
],
});
```
## Effective Period
For reports that span a time range (e.g. 24-hour urine collection):
```ts theme={null}
const { data } = await clinik.labs.create({
status: 'final',
code: { system: 'http://loinc.org', code: '21482-5', display: '24 hour urine protein' },
patientId: 'pt_abc123',
category: 'LAB',
effectivePeriod: {
start: '2025-01-14T08:00:00Z',
end: '2025-01-15T08:00:00Z',
},
conclusion: 'Protein within normal range.',
});
```
## Based On (ServiceRequest)
Link a report to the order that requested it:
```ts theme={null}
const { data } = await clinik.labs.create({
status: 'final',
code: { system: 'http://loinc.org', code: '24323-8', display: 'CMP' },
patientId: 'pt_abc123',
basedOn: ['sr_lab_order_001'],
// ...
});
```
## Media / Images
Attach images or media to the report:
```ts theme={null}
const { data } = await clinik.labs.create({
status: 'final',
code: 'Chest X-Ray',
patientId: 'pt_abc123',
category: 'RAD',
media: [
{ comment: 'PA view', linkId: 'media_xray_pa' },
{ comment: 'Lateral view', linkId: 'media_xray_lat' },
],
conclusion: 'No acute cardiopulmonary disease.',
});
```
## Categories
| Code | Description |
| - | - |
| `LAB` | Laboratory |
| `RAD` | Radiology |
| `PAT` | Pathology |
## Linking Observations
A lab report groups related observations. Create the observations first, then reference their IDs:
```ts theme={null}
// Create individual lab results
const { data: glucose } = await clinik.observations.create({
status: 'final',
code: { system: 'http://loinc.org', code: '2339-0', display: 'Glucose' },
patientId: 'pt_abc123',
category: 'laboratory',
valueQuantity: { value: 95, unit: 'mg/dL' },
interpretation: 'N',
referenceRange: { low: { value: 70, unit: 'mg/dL' }, high: { value: 100, unit: 'mg/dL' } },
});
// Create the report linking them
const { data: report } = await clinik.labs.create({
status: 'final',
code: { system: 'http://loinc.org', code: '24323-8', display: 'CMP' },
patientId: 'pt_abc123',
category: 'LAB',
resultIds: [glucose.id!],
conclusion: 'All values within normal limits.',
});
```
## Update a Lab Report
```ts theme={null}
await clinik.labs.update('lab_abc123', {
status: 'amended',
conclusion: 'Updated: Glucose slightly elevated on recheck.',
conclusionCodes: [
{ system: 'http://snomed.info/sct', code: '166922008', display: 'Glucose elevated' },
],
resultsInterpreter: 'prac_senior_doc',
});
```
## Read with Included Observations
```ts theme={null}
const { data } = await clinik.labs.read('lab_abc123', {
include: ['Observation'],
});
```
## Attached Documents
Attach PDF reports or images:
```ts theme={null}
const { data } = await clinik.labs.create({
status: 'final',
code: { system: 'http://loinc.org', code: '24323-8', display: 'CMP' },
patientId: 'pt_abc123',
category: 'LAB',
conclusion: 'See attached report.',
presentedForm: [
{
contentType: 'application/pdf',
url: 'https://storage.clinic.com/reports/lab-2025-001.pdf',
title: 'CMP Lab Report - Jan 2025',
},
],
});
```
## Status Lifecycle
`registered` → `partial` → `preliminary` → `final` → `amended` / `corrected` / `appended` / `cancelled`
## Search Labs
```ts theme={null}
const { data } = await clinik.labs.search({
patientId: 'pt_abc123',
status: 'final',
dateFrom: '2025-01-01',
sort: '-date',
});
```
# Locations
Source: https://docs.clinikapi.com/guides/locations
Manage physical locations — clinics, hospitals, rooms, and mobile units.
# Locations
Locations (FHIR `Location`) represent physical places where healthcare services are provided. They can model buildings, wings, rooms, beds, vehicles, or even virtual locations.
## Create a Location
```ts theme={null}
const { data: clinic } = await clinik.locations.create({
name: 'Sunrise Medical Center — Main Building',
status: 'active',
description: 'Primary care facility with 3 floors and 40 exam rooms',
mode: 'instance',
type: ['HOSP'],
phone: '555-0100',
email: 'info@sunrise-medical.com',
address: {
line: ['100 Health Blvd'],
city: 'Austin',
state: 'TX',
postalCode: '78701',
country: 'US',
},
physicalType: 'building',
position: { longitude: -97.7431, latitude: 30.2672 },
managingOrganizationId: 'org_sunrise',
hoursOfOperation: [
{ daysOfWeek: ['mon', 'tue', 'wed', 'thu', 'fri'], openingTime: '08:00:00', closingTime: '18:00:00' },
{ daysOfWeek: ['sat'], openingTime: '09:00:00', closingTime: '13:00:00' },
],
availabilityExceptions: 'Closed on federal holidays',
});
```
## Location Hierarchy
Create rooms and wings as child locations:
```ts theme={null}
const { data: wing } = await clinik.locations.create({
name: 'East Wing — Cardiology',
status: 'active',
physicalType: 'wing',
partOfId: clinic.id,
type: ['WING'],
});
const { data: room } = await clinik.locations.create({
name: 'Exam Room 101',
status: 'active',
physicalType: 'room',
partOfId: wing.id,
type: ['ROOM'],
});
```
## Location Status
| Status | Description |
| - | - |
| `active` | Open and operational |
| `suspended` | Temporarily closed (renovation, etc.) |
| `inactive` | Permanently closed |
## Location Modes
| Mode | Description |
| - | - |
| `instance` | A specific physical location |
| `kind` | A class of locations (e.g. "any pharmacy") |
## GPS Coordinates
Track precise location for mobile units or mapping:
```ts theme={null}
const { data } = await clinik.locations.create({
name: 'Mobile Health Unit — Route A',
mode: 'instance',
physicalType: 'vehicle',
position: {
longitude: -97.7431,
latitude: 30.2672,
altitude: 150,
},
});
```
## Search Locations
```ts theme={null}
const { data } = await clinik.locations.search({
name: 'Sunrise',
status: 'active',
});
```
# Measure Reports
Source: https://docs.clinikapi.com/guides/measure-reports
Submit and track quality measure results for populations and individual patients.
# Measure Reports
Measure Reports (FHIR `MeasureReport`) contain the results of evaluating a measure. They can report on individual patients, patient lists, or summary population data.
## Submit a Summary Report
```ts theme={null}
const { data: report } = await clinik.measureReports.create({
status: 'complete',
type: 'summary',
measureId: 'diabetes-hba1c-control',
period: { start: '2024-01-01', end: '2024-03-31' },
reporterId: 'org_clinic789',
group: [{
code: 'hba1c-control',
population: [
{ code: 'initial-population', count: 500 },
{ code: 'denominator', count: 480 },
{ code: 'denominator-exclusion', count: 20 },
{ code: 'numerator', count: 72 },
],
measureScore: { value: 0.15, unit: '%' },
}],
});
```
## Submit an Individual Patient Report
```ts theme={null}
const { data } = await clinik.measureReports.create({
status: 'complete',
type: 'individual',
measureId: 'diabetes-hba1c-control',
patientId: 'pt_abc123',
period: { start: '2024-01-01', end: '2024-03-31' },
date: '2024-04-01T10:00:00Z',
group: [{
code: 'hba1c-control',
population: [
{ code: 'initial-population', count: 1 },
{ code: 'numerator', count: 0 },
],
measureScore: { value: 7.2, unit: '%' },
}],
});
```
## Submit a Pending Report
```ts theme={null}
const { data } = await clinik.measureReports.create({
status: 'pending',
type: 'summary',
measureId: 'breast-cancer-screening',
period: { start: '2024-01-01', end: '2024-06-30' },
});
// Later, update the status
const { data: updated } = await clinik.measureReports.update('report_abc123', {
status: 'complete',
});
```
## Search Measure Reports
```ts theme={null}
// All reports for a measure
const { data } = await clinik.measureReports.search({
measureId: 'diabetes-hba1c-control',
});
// Reports for a specific patient
const { data: patientReports } = await clinik.measureReports.search({
patientId: 'pt_abc123',
});
// Reports in a date range
const { data: q1 } = await clinik.measureReports.search({
dateFrom: '2024-01-01',
dateTo: '2024-03-31',
});
```
# Measures
Source: https://docs.clinikapi.com/guides/measures
Define quality measures and clinical performance metrics for healthcare reporting.
# Measures
Measures (FHIR `Measure`) define quality measures, clinical guidelines, and performance metrics. They describe what to measure and how to score it — the actual results go into MeasureReports.
## Create a Quality Measure
```ts theme={null}
const { data: measure } = await clinik.measures.create({
status: 'active',
name: 'diabetes-hba1c-control',
title: 'Diabetes: HbA1c Poor Control (>9%)',
description: 'Percentage of patients aged 18-75 with diabetes whose most recent HbA1c level is greater than 9.0%',
purpose: 'Track glycemic control in diabetic patient population',
scoring: 'proportion',
type: ['outcome'],
topic: ['Diabetes', 'Quality Measure', 'CMS'],
rationale: 'Poor glycemic control leads to increased complications including retinopathy, nephropathy, and cardiovascular disease',
clinicalRecommendationStatement: 'ADA recommends HbA1c target of <7% for most adults with diabetes',
guidance: 'Use most recent HbA1c result within the measurement period',
group: [{
code: 'hba1c-control',
description: 'Patients with diabetes and HbA1c > 9%',
}],
});
```
## Create a Process Measure
```ts theme={null}
const { data } = await clinik.measures.create({
status: 'draft',
name: 'breast-cancer-screening',
title: 'Breast Cancer Screening',
description: 'Percentage of women 50-74 who had a mammogram in the past 2 years',
scoring: 'proportion',
type: ['process'],
topic: ['Preventive Care', 'Cancer Screening'],
publisher: 'Quality Department',
version: '2024.1',
});
```
## Update a Measure
```ts theme={null}
const { data } = await clinik.measures.update('measure_abc123', {
status: 'active',
version: '2024.2',
description: 'Updated description with new clinical guidelines',
});
```
## Search Measures
```ts theme={null}
// All active measures
const { data } = await clinik.measures.search({
status: 'active',
});
// Search by topic
const { data: diabetes } = await clinik.measures.search({
topic: 'Diabetes',
});
// Search by name
const { data: named } = await clinik.measures.search({
name: 'hba1c',
});
```
# Media
Source: https://docs.clinikapi.com/guides/media
Capture and manage clinical images, videos, and audio recordings.
# Media
Media (FHIR `Media`) captures clinical images, videos, and audio recordings. Track diagnostic images, wound progression photos, ultrasound recordings, dermatology images, and other clinical media attached to patient encounters.
## Capture a Clinical Image
```ts theme={null}
const { data: image } = await clinik.media.create({
status: 'completed',
type: 'image',
patientId: 'pt_abc123',
encounterId: 'enc_visit456',
operatorId: 'prac_dr789',
bodySite: 'Left knee',
createdDateTime: '2024-03-15T14:30:00Z',
height: 1920,
width: 1080,
content: {
contentType: 'image/jpeg',
url: 'https://storage.example.com/images/knee-xray-001.jpg',
title: 'Left knee X-ray — AP view',
},
note: 'Pre-operative imaging for total knee replacement evaluation',
});
```
## Record a Video
```ts theme={null}
const { data: video } = await clinik.media.create({
status: 'completed',
type: 'video',
patientId: 'pt_abc123',
encounterId: 'enc_pt_session001',
operatorId: 'prac_therapist456',
createdDateTime: '2024-03-15T10:00:00Z',
duration: 1800,
content: {
contentType: 'video/mp4',
url: 'https://storage.example.com/videos/pt-session-001.mp4',
title: 'Physical therapy session — gait analysis',
},
reasonCode: ['Post-surgical rehabilitation assessment'],
});
```
## Capture an Audio Recording
```ts theme={null}
const { data: audio } = await clinik.media.create({
status: 'completed',
type: 'audio',
patientId: 'pt_abc123',
operatorId: 'prac_dr789',
duration: 45,
content: {
contentType: 'audio/wav',
url: 'https://storage.example.com/audio/heart-auscultation-001.wav',
title: 'Heart auscultation — mitral area',
},
bodySite: 'Heart',
note: 'Grade 2/6 systolic murmur noted at mitral area',
});
```
## Wound Progression Tracking
```ts theme={null}
const { data } = await clinik.media.create({
status: 'completed',
type: 'image',
patientId: 'pt_wound_care001',
encounterId: 'enc_followup789',
operatorId: 'prac_nurse456',
bodySite: 'Right lower leg',
height: 3024,
width: 4032,
content: {
contentType: 'image/jpeg',
data: '',
title: 'Wound assessment — week 4 follow-up',
},
note: 'Wound size reduced from 4cm to 2.5cm. Granulation tissue present. Healing well.',
basedOn: ['sr_wound_care_plan001'],
});
```
## Ultrasound with Device Details
```ts theme={null}
const { data } = await clinik.media.create({
status: 'completed',
type: 'image',
modality: 'US',
view: 'Sagittal',
patientId: 'pt_prenatal001',
encounterId: 'enc_ob_visit456',
operatorId: 'prac_sonographer789',
deviceName: 'GE Voluson E10',
deviceId: 'dev_us_scanner001',
height: 768,
width: 1024,
frames: 1,
content: {
contentType: 'image/dicom',
url: 'https://pacs.example.com/studies/us-ob-001/series/001/instance/001',
title: 'Obstetric ultrasound — 20 week anatomy scan',
},
bodySite: 'Abdomen',
});
```
## Search Media
```ts theme={null}
// All media for a patient
const { data } = await clinik.media.search({
patientId: 'pt_abc123',
});
// Filter by type
const { data: images } = await clinik.media.search({
patientId: 'pt_abc123',
type: 'image',
});
// Filter by modality
const { data: ultrasounds } = await clinik.media.search({
modality: 'US',
});
// Filter by date range
const { data: recent } = await clinik.media.search({
patientId: 'pt_abc123',
dateFrom: '2024-01-01',
dateTo: '2024-12-31',
});
```
# Medication Dispenses
Source: https://docs.clinikapi.com/guides/medication-dispenses
Track pharmacy dispensing of medications to patients.
# Medication Dispenses
Medication Dispenses (FHIR `MedicationDispense`) track the supply of medications to patients — typically by a pharmacy. For medication orders, see [Prescriptions](/guides/prescriptions). For drug definitions, see [Medications](/guides/medications).
## Dispense a Medication
```ts theme={null}
const { data: dispense } = await clinik.medicationDispenses.create({
status: 'completed',
medication: {
system: 'http://www.nlm.nih.gov/research/umls/rxnorm',
code: '197361',
display: 'Lisinopril 10 MG Oral Tablet',
},
patientId: 'pt_abc123',
authorizingPrescriptionIds: ['rx_order456'],
quantity: { value: 30, unit: 'tablets' },
daysSupply: 30,
whenPrepared: '2024-03-15T10:00:00Z',
whenHandedOver: '2024-03-15T14:30:00Z',
dosageText: 'Take 1 tablet daily in the morning',
performer: [
{ function: 'dispenser', actorId: 'Practitioner/pharm_rph789' },
],
});
```
## Partial Fill
```ts theme={null}
const { data: partial } = await clinik.medicationDispenses.create({
status: 'completed',
medication: 'Amoxicillin 500mg Capsule',
patientId: 'pt_abc123',
authorizingPrescriptionIds: ['rx_order789'],
type: 'partial fill',
quantity: { value: 14, unit: 'capsules' },
daysSupply: 7,
whenHandedOver: '2024-03-15T16:00:00Z',
dosageText: 'Take 1 capsule twice daily for 7 days',
note: 'Partial fill — remaining 14 capsules available for pickup in 7 days',
});
```
## Substitution
Track when a generic is substituted for a brand-name drug:
```ts theme={null}
const { data } = await clinik.medicationDispenses.create({
status: 'completed',
medication: 'Atorvastatin 20mg Tablet',
patientId: 'pt_abc123',
authorizingPrescriptionIds: ['rx_order101'],
quantity: { value: 90, unit: 'tablets' },
daysSupply: 90,
whenHandedOver: '2024-03-15',
substitution: {
wasSubstituted: true,
type: 'generic',
reason: 'Formulary policy — generic equivalent available',
},
});
```
## Search Dispenses
```ts theme={null}
// All dispenses for a patient
const { data } = await clinik.medicationDispenses.search({
patientId: 'pt_abc123',
});
// Filter by status
const { data: completed } = await clinik.medicationDispenses.search({
patientId: 'pt_abc123',
status: 'completed',
});
// Filter by medication
const { data: lisinopril } = await clinik.medicationDispenses.search({
medication: 'lisinopril',
});
```
## Dispense Statuses
| Status | Description |
| - | - |
| `preparation` | Being prepared by the pharmacy |
| `in-progress` | Dispense is in progress |
| `on-hold` | Dispense is paused |
| `completed` | Medication has been handed over |
| `cancelled` | Dispense was cancelled |
| `stopped` | Dispense was stopped |
| `declined` | Dispense was declined |
## Medications vs Prescriptions vs Dispenses
| Resource | FHIR Type | Purpose |
| - | - | - |
| Medication | `Medication` | Drug definition (what the drug is) |
| Prescription | `MedicationRequest` | Medication order (prescribe it) |
| Medication Dispense | `MedicationDispense` | Pharmacy supply (dispense it) |
# Medication Knowledge
Source: https://docs.clinikapi.com/guides/medication-knowledge
Manage drug reference data including ingredients, costs, and packaging.
# Medication Knowledge
Medication Knowledge (FHIR `MedicationKnowledge`) provides detailed drug reference information — dosage forms, ingredients, costs, and packaging. This is a drug knowledge base, not a prescription or dispense record.
## Create a Drug Reference Entry
```ts theme={null}
const { data: mk } = await clinik.medicationKnowledge.create({
code: {
system: 'http://www.nlm.nih.gov/research/umls/rxnorm',
code: '197361',
display: 'Lisinopril 10 MG Oral Tablet',
},
status: 'active',
doseForm: 'tablet',
manufacturer: 'Teva Pharmaceuticals',
amount: { value: 10, unit: 'mg' },
synonym: ['Prinivil', 'Zestril'],
ingredient: [
{
item: {
system: 'http://www.nlm.nih.gov/research/umls/rxnorm',
code: '29046',
display: 'Lisinopril',
},
isActive: true,
strength: {
numerator: { value: 10, unit: 'mg' },
denominator: { value: 1, unit: 'tablet' },
},
},
],
intendedRoute: ['oral'],
cost: [
{ type: 'wholesale', source: 'AWP', cost: { value: 0.15, currency: 'USD' } },
{ type: 'retail', source: 'GoodRx', cost: { value: 0.85, currency: 'USD' } },
],
packaging: {
type: 'bottle',
quantity: { value: 100, unit: 'tablets' },
},
preparationInstruction: 'Store at room temperature. Protect from moisture.',
});
```
## Cost Tracking
Track multiple cost types for formulary management:
```ts theme={null}
const { data } = await clinik.medicationKnowledge.create({
code: 'Metformin 500mg Tablet',
doseForm: 'tablet',
cost: [
{ type: 'wholesale', source: 'AWP', cost: { value: 0.05, currency: 'USD' } },
{ type: 'retail', cost: { value: 0.25, currency: 'USD' } },
{ type: 'copay-tier-1', cost: { value: 5.00, currency: 'USD' } },
],
});
```
## Search Drug References
```ts theme={null}
// Search by status
const { data } = await clinik.medicationKnowledge.search({
status: 'active',
});
// Search by dose form
const { data: tablets } = await clinik.medicationKnowledge.search({
doseForm: 'tablet',
});
// Search by manufacturer
const { data: teva } = await clinik.medicationKnowledge.search({
manufacturer: 'Teva',
});
```
## Update a Drug Reference
```ts theme={null}
await clinik.medicationKnowledge.update('mk_abc123', {
status: 'inactive',
preparationInstruction: 'Discontinued — replaced by new formulation',
});
```
## Medication vs MedicationKnowledge
| Resource | FHIR Type | Purpose |
| - | - | - |
| Medication | `Medication` | Specific drug instance (batch, lot) |
| Medication Knowledge | `MedicationKnowledge` | Drug reference data (costs, ingredients, packaging) |
Use `Medication` for tracking specific drug instances in your inventory. Use `MedicationKnowledge` for building a drug formulary or reference database.
# Medication Statements
Source: https://docs.clinikapi.com/guides/medication-statements
Record patient-reported medication usage and adherence.
# Medication Statements
Medication Statements (FHIR `MedicationStatement`) record what medications a patient is taking or has taken — as reported by the patient, clinician, or other source. Unlike prescriptions, these are informational records, not orders.
## Record a Medication Statement
```ts theme={null}
const { data: stmt } = await clinik.medicationStatements.create({
status: 'active',
medication: 'Metformin 500mg Tablet',
patientId: 'pt_abc123',
category: 'community',
effectivePeriod: {
start: '2024-01-15',
},
dosageText: 'Take 1 tablet twice daily with meals',
informationSourceId: 'Patient/pt_abc123',
reasonCode: ['Type 2 diabetes management'],
note: 'Patient reports good adherence, no side effects',
});
```
## Patient-Reported Medications
During intake, record all medications a patient reports taking:
```ts theme={null}
// Over-the-counter medication
const { data: otc } = await clinik.medicationStatements.create({
status: 'active',
medication: 'Ibuprofen 200mg',
patientId: 'pt_abc123',
category: 'community',
dosageText: 'Takes 1-2 tablets as needed for headaches',
informationSourceId: 'Patient/pt_abc123',
dateAsserted: '2024-03-15',
});
// Supplement
const { data: supplement } = await clinik.medicationStatements.create({
status: 'active',
medication: 'Vitamin D3 2000 IU',
patientId: 'pt_abc123',
category: 'community',
dosageText: 'Takes 1 capsule daily',
informationSourceId: 'Patient/pt_abc123',
});
```
## Discontinued Medication
```ts theme={null}
const { data: stopped } = await clinik.medicationStatements.create({
status: 'stopped',
medication: {
system: 'http://www.nlm.nih.gov/research/umls/rxnorm',
code: '197361',
display: 'Lisinopril 10 MG Oral Tablet',
},
patientId: 'pt_abc123',
effectivePeriod: {
start: '2023-06-01',
end: '2024-02-28',
},
statusReason: ['Switched to alternative due to persistent cough'],
note: 'Replaced with Losartan 50mg',
});
```
## Link to Prescriptions
Connect a medication statement to the authorizing prescription:
```ts theme={null}
const { data } = await clinik.medicationStatements.create({
status: 'active',
medication: 'Atorvastatin 20mg Tablet',
patientId: 'pt_abc123',
basedOn: ['MedicationRequest/rx_order456'],
dosageText: 'Take 1 tablet at bedtime',
reasonCode: ['Hyperlipidemia'],
});
```
## Update a Statement
```ts theme={null}
await clinik.medicationStatements.update('ms_abc123', {
status: 'completed',
effectivePeriod: {
start: '2024-01-15',
end: '2024-06-15',
},
note: 'Course completed as prescribed',
});
```
## Search Medication Statements
```ts theme={null}
// All active medications for a patient
const { data } = await clinik.medicationStatements.search({
patientId: 'pt_abc123',
status: 'active',
});
// Filter by category
const { data: community } = await clinik.medicationStatements.search({
patientId: 'pt_abc123',
category: 'community',
});
// Search by medication
const { data: metformin } = await clinik.medicationStatements.search({
medication: 'metformin',
});
```
## Statement Statuses
| Status | Description |
| - | - |
| `active` | Patient is currently taking the medication |
| `completed` | Course of medication is finished |
| `stopped` | Medication was discontinued |
| `on-hold` | Medication is temporarily paused |
| `intended` | Patient intends to start the medication |
| `not-taken` | Patient is not taking the medication |
## Prescriptions vs Statements
| Resource | FHIR Type | Purpose |
| - | - | - |
| Prescription | `MedicationRequest` | Medication order (what was prescribed) |
| Medication Statement | `MedicationStatement` | Medication usage (what the patient is actually taking) |
A prescription is an order from a provider. A medication statement is a record of what the patient reports taking — which may include OTC drugs, supplements, or medications prescribed elsewhere.
# Medications
Source: https://docs.clinikapi.com/guides/medications
Manage medication definitions, ingredients, and batch information.
# Medications
Medications represent drug definitions — the medication itself, not a prescription. For medication orders, see [Prescriptions](/guides/prescriptions).
## Create a Medication
```ts theme={null}
// Simple — free-text name
const { data: med } = await clinik.medications.create({
code: 'Amoxicillin 500mg Capsule',
status: 'active',
form: 'capsule',
manufacturer: 'Teva Pharmaceuticals',
});
// Coded — RxNorm with full details
const { data: coded } = await clinik.medications.create({
code: {
system: 'http://www.nlm.nih.gov/research/umls/rxnorm',
code: '308182',
display: 'Amoxicillin 500 MG Oral Capsule',
},
status: 'active',
form: 'capsule',
manufacturer: 'Teva Pharmaceuticals',
amount: {
numerator: { value: 500, unit: 'mg' },
denominator: { value: 1, unit: 'capsule' },
},
ingredient: [
{
item: {
system: 'http://www.nlm.nih.gov/research/umls/rxnorm',
code: '723',
display: 'Amoxicillin',
},
isActive: true,
strength: {
numerator: { value: 500, unit: 'mg' },
denominator: { value: 1, unit: 'capsule' },
},
},
],
batch: {
lotNumber: 'LOT-2025-A001',
expirationDate: '2026-12-31',
},
});
```
## Manufacturer
Track the drug manufacturer:
```ts theme={null}
const { data } = await clinik.medications.create({
code: 'Metformin 500mg Tablet',
form: 'tablet',
manufacturer: 'Merck & Co.',
});
```
The manufacturer is returned in read responses and can be updated:
```ts theme={null}
await clinik.medications.update('med_abc123', {
manufacturer: 'Generic Pharma Inc.',
});
```
## Amount
Specify the total amount of drug in the package using a ratio:
```ts theme={null}
const { data } = await clinik.medications.create({
code: 'Insulin Glargine',
form: 'injection',
manufacturer: 'Sanofi',
amount: {
numerator: { value: 100, unit: 'units' },
denominator: { value: 1, unit: 'mL' },
},
});
```
## Coding Systems
| System | Use Case | Example |
| - | - | - |
| RxNorm | US drug codes | `197361` (Lisinopril 10mg) |
| SNOMED CT | Clinical terms | `387207008` (Ibuprofen) |
| Free text | When no code available | `"Custom compound cream"` |
## Update a Medication
```ts theme={null}
await clinik.medications.update('med_abc123', {
status: 'inactive',
manufacturer: 'Updated Pharma Corp.',
batch: { expirationDate: '2025-06-30' },
});
```
## Search Medications
```ts theme={null}
const { data } = await clinik.medications.search({
status: 'active',
count: 50,
});
for (const med of data.data) {
console.log(`${med.code} — ${med.form}`);
console.log(` Manufacturer: ${med.manufacturer}`);
if (med.batch) {
console.log(` Lot: ${med.batch.lotNumber}, Expires: ${med.batch.expirationDate}`);
}
}
```
## Medications vs Prescriptions
| Resource | FHIR Type | Purpose |
| - | - | - |
| Medication | `Medication` | Drug definition (what the drug is) |
| Prescription | `MedicationRequest` | Medication order (prescribe it to a patient) |
A prescription references a medication. You can create prescriptions with inline medication codes without creating a separate Medication resource first.
## Complete Field Reference
| Field | Type | Required | Description |
| - | - | - | - |
| `code` | `string \| CodeableConcept` | Yes | RxNorm, SNOMED CT, or free-text name |
| `status` | `string` | No | active (default), inactive |
| `form` | `string` | No | Dosage form (tablet, capsule, injection, etc.) |
| `manufacturer` | `string` | No | Manufacturer name |
| `amount` | `{ numerator, denominator }` | No | Total amount of drug in package |
| `ingredient` | `Array` | No | Active and inactive ingredients with strength |
| `batch` | `{ lotNumber?, expirationDate? }` | No | Batch/lot tracking information |
# Notes
Source: https://docs.clinikapi.com/guides/notes
Create and manage clinical notes — progress notes, discharge summaries, and more.
# Notes
Notes (FHIR DocumentReference) represent clinical documentation — progress notes, discharge summaries, consultation notes, operative notes, and other narrative records.
## Create a Note
```ts theme={null}
const { data: note } = await clinik.notes.create({
patientId: 'pt_abc123',
authorId: 'prac_def456',
encounterId: 'enc_xyz789',
type: 'progress-note',
title: 'Follow-up Visit - Hypertension Management',
content: `## Subjective
Patient reports compliance with lisinopril 10mg daily. No dizziness, cough, or swelling.
## Objective
BP: 130/84 mmHg, HR: 72 bpm
## Assessment
Essential hypertension — improving but not at goal.
## Plan
- Increase lisinopril to 20mg daily
- Recheck BP in 4 weeks`,
contentType: 'text/markdown',
docStatus: 'final',
category: 'cardiology',
date: '2025-01-15',
practiceSetting: 'cardiology',
facilityType: 'outpatient-clinic',
});
```
## Document Relationships
Link notes to other documents they replace, append to, or sign:
```ts theme={null}
// Amend a note by creating a replacement
const { data: amended } = await clinik.notes.create({
patientId: 'pt_abc123',
authorId: 'prac_def456',
type: 'progress-note',
title: 'Follow-up Visit - Amended',
content: '... corrected content ...',
docStatus: 'amended',
relatesTo: [{
code: 'replaces',
targetId: 'note_original_001',
}],
});
// Append an addendum
const { data: addendum } = await clinik.notes.create({
patientId: 'pt_abc123',
authorId: 'prac_def456',
type: 'progress-note',
title: 'Addendum - Follow-up Visit',
content: 'Patient called to report mild dizziness. Advised to take medication with food.',
relatesTo: [{
code: 'appends',
targetId: 'note_original_001',
}],
});
```
## Security Labels
Tag notes with security classifications:
```ts theme={null}
const { data } = await clinik.notes.create({
patientId: 'pt_abc123',
type: 'progress-note',
title: 'Mental Health Assessment',
content: '...',
securityLabel: [
{ system: 'http://terminology.hl7.org/CodeSystem/v3-Confidentiality', code: 'R', display: 'Restricted' },
{ code: 'mental-health', display: 'Mental Health' },
],
// ...
});
```
## Authentication and Custody
Track who authenticated and who maintains the document:
```ts theme={null}
const { data } = await clinik.notes.create({
patientId: 'pt_abc123',
authorId: 'prac_resident',
authenticatorId: 'prac_attending', // Attending physician who co-signed
custodianId: 'org_hospital', // Hospital maintaining the record
type: 'discharge-summary',
title: 'Discharge Summary',
content: '...',
// ...
});
```
## Service Context
Document the clinical context:
```ts theme={null}
const { data } = await clinik.notes.create({
patientId: 'pt_abc123',
type: 'consultation-note',
title: 'Cardiology Consultation',
content: '...',
servicePeriod: {
start: '2025-01-15T09:00:00Z',
end: '2025-01-15T09:45:00Z',
},
facilityType: 'outpatient-clinic',
practiceSetting: 'cardiology',
// ...
});
```
## Note Types
| Type | Description |
| - | - |
| `progress-note` | Standard visit documentation |
| `discharge-summary` | Hospital discharge summary |
| `consultation-note` | Specialist consultation |
| `history-and-physical` | H\&P documentation |
| `operative-note` | Surgical procedure note |
| `procedure-note` | Non-surgical procedure note |
| `referral-note` | Referral documentation |
| `transfer-summary` | Patient transfer summary |
| `other` | Other note types |
## Update a Note
```ts theme={null}
await clinik.notes.update('note_abc123', {
docStatus: 'amended',
content: '... updated content with addendum ...',
relatesTo: [{
code: 'appends',
targetId: 'note_original_001',
}],
});
```
## Search Notes
```ts theme={null}
const { data } = await clinik.notes.search({
patientId: 'pt_abc123',
type: 'progress-note',
authorId: 'prac_def456',
sort: '-date',
});
```
# Nutrition Orders
Source: https://docs.clinikapi.com/guides/nutrition-orders
Create and manage dietary orders — oral diets, supplements, and enteral formulas.
# Nutrition Orders
Nutrition orders (FHIR `NutritionOrder`) represent dietary prescriptions for patients. They cover oral diets with specific nutrient modifications, nutritional supplements, and enteral (tube feeding) formulas.
## Create a Nutrition Order
```ts theme={null}
const { data: order } = await clinik.nutritionOrders.create({
status: 'active',
intent: 'order',
patientId: 'pt_abc123',
ordererId: 'prac_def456',
oralDiet: {
type: ['diabetic', 'low-sodium'],
instruction: 'No added salt. Limit carbohydrates to 45g per meal.',
nutrient: [
{ modifier: 'Sodium', amount: { value: 2000, unit: 'mg' } },
{ modifier: 'Carbohydrate', amount: { value: 135, unit: 'g' } },
],
},
excludeFoodModifier: ['shellfish', 'peanuts'],
note: 'Patient has a history of diabetic ketoacidosis',
});
```
## Common Use Cases
### Oral Diet with Allergies
```ts theme={null}
const { data } = await clinik.nutritionOrders.create({
status: 'active',
intent: 'order',
patientId: 'pt_abc123',
ordererId: 'prac_def456',
allergyIntoleranceIds: ['allergy_gluten', 'allergy_dairy'],
oralDiet: {
type: ['gluten-free', 'dairy-free'],
instruction: 'Strict gluten-free and dairy-free diet',
},
foodPreferenceModifier: ['vegetarian'],
});
```
### Nutritional Supplement
```ts theme={null}
const { data } = await clinik.nutritionOrders.create({
status: 'active',
intent: 'order',
patientId: 'pt_abc123',
supplement: [
{
type: 'High-protein oral supplement',
productName: 'Ensure High Protein',
quantity: { value: 1, unit: 'bottle' },
instruction: 'One bottle with each meal, three times daily',
},
],
note: 'Patient is malnourished — BMI 17.5',
});
```
### Enteral Formula (Tube Feeding)
```ts theme={null}
const { data } = await clinik.nutritionOrders.create({
status: 'active',
intent: 'order',
patientId: 'pt_abc123',
encounterId: 'enc_icu789',
enteralFormula: {
baseFormulaType: 'Standard polymeric formula',
baseFormulaProductName: 'Jevity 1.5 Cal',
additiveType: 'Fiber',
routeOfAdministration: 'Nasogastric tube',
administrationInstruction: 'Continuous infusion at 50mL/hr, advance by 25mL/hr every 8 hours to goal of 75mL/hr',
},
});
```
## Status Lifecycle
`draft` → `active` → `on-hold` → `completed` / `revoked`
## Search Nutrition Orders
```ts theme={null}
const { data } = await clinik.nutritionOrders.search({
patientId: 'pt_abc123',
status: 'active',
});
```
# Observations
Source: https://docs.clinikapi.com/guides/observations
Record vitals, lab values, and clinical measurements.
# Observations
Observations capture clinical measurements — vital signs, lab results, social history, and exam findings.
## Create a Vital Sign
```ts theme={null}
// Heart rate
const { data: heartRate } = await clinik.observations.create({
status: 'final',
code: { system: 'http://loinc.org', code: '8867-4', display: 'Heart rate' },
patientId: 'pt_abc123',
encounterId: 'enc_xyz789',
category: 'vital-signs',
effectiveDateTime: '2025-01-15T09:15:00Z',
valueQuantity: { value: 72, unit: 'beats/minute', system: 'http://unitsofmeasure.org', code: '/min' },
interpretation: 'N', // Normal
});
```
## Blood Pressure (Multi-Component)
Blood pressure uses the `component` field for systolic and diastolic values:
```ts theme={null}
const { data: bp } = await clinik.observations.create({
status: 'final',
code: { system: 'http://loinc.org', code: '85354-9', display: 'Blood pressure panel' },
patientId: 'pt_abc123',
category: 'vital-signs',
effectiveDateTime: '2025-01-15T09:15:00Z',
component: [
{
code: { system: 'http://loinc.org', code: '8480-6', display: 'Systolic blood pressure' },
valueQuantity: { value: 120, unit: 'mmHg' },
},
{
code: { system: 'http://loinc.org', code: '8462-4', display: 'Diastolic blood pressure' },
valueQuantity: { value: 80, unit: 'mmHg' },
},
],
});
```
## Lab Result
```ts theme={null}
const { data: glucose } = await clinik.observations.create({
status: 'final',
code: { system: 'http://loinc.org', code: '2339-0', display: 'Glucose [Mass/volume] in Blood' },
patientId: 'pt_abc123',
category: 'laboratory',
effectiveDateTime: '2025-01-15T10:00:00Z',
valueQuantity: { value: 95, unit: 'mg/dL' },
interpretation: 'N',
referenceRange: {
low: { value: 70, unit: 'mg/dL' },
high: { value: 100, unit: 'mg/dL' },
text: '70-100 mg/dL',
},
});
```
## Categories
| Category | Description | Examples |
| - | - | - |
| `vital-signs` | Vital sign measurements | Heart rate, BP, temperature, SpO2 |
| `laboratory` | Lab test results | Glucose, CBC, metabolic panel |
| `social-history` | Social/behavioral data | Smoking status, alcohol use |
| `exam` | Physical exam findings | Lung sounds, reflexes |
## Interpretation Codes
| Code | Meaning |
| - | - |
| `N` | Normal |
| `H` | High |
| `L` | Low |
| `A` | Abnormal |
| `HH` | Critically high |
| `LL` | Critically low |
## Search Observations
```ts theme={null}
const { data: vitals } = await clinik.observations.search({
patientId: 'pt_abc123',
status: 'final',
dateFrom: '2025-01-01',
sort: '-date',
count: 50,
});
```
# Organizations
Source: https://docs.clinikapi.com/guides/organizations
Manage healthcare organizations, departments, and provider groups.
# Organizations
Organizations (FHIR `Organization`) represent healthcare providers, hospital departments, insurance companies, and other entities involved in care delivery. They form the organizational hierarchy that practitioners and services belong to.
## Create an Organization
```ts theme={null}
const { data: org } = await clinik.organizations.create({
name: 'Sunrise Medical Center',
type: ['prov'],
phone: '555-0100',
email: 'admin@sunrise-medical.com',
address: {
line: ['100 Health Blvd'],
city: 'Austin',
state: 'TX',
postalCode: '78701',
country: 'US',
},
contact: [
{
purpose: 'billing',
firstName: 'Sarah',
lastName: 'Johnson',
email: 'billing@sunrise-medical.com',
phone: '555-0101',
},
{
purpose: 'admin',
firstName: 'Mike',
lastName: 'Chen',
email: 'admin@sunrise-medical.com',
},
],
});
```
## Organization Hierarchy
Create departments as child organizations:
```ts theme={null}
const { data: dept } = await clinik.organizations.create({
name: 'Cardiology Department',
type: ['dept'],
partOfId: org.id,
phone: '555-0110',
});
```
## Organization Types
| Type | Description |
| - | - |
| `prov` | Healthcare provider |
| `dept` | Hospital department |
| `team` | Care team |
| `govt` | Government |
| `ins` | Insurance company |
| `pay` | Payer |
| `edu` | Educational institution |
| `bus` | Non-healthcare business |
## Search Organizations
```ts theme={null}
const { data } = await clinik.organizations.search({
name: 'Sunrise',
type: 'prov',
active: true,
});
```
# Patients
Source: https://docs.clinikapi.com/guides/patients
Create, read, update, search, and delete patient records.
# Patients
Patients are the core resource in ClinikAPI. Every clinical resource (encounters, observations, prescriptions, etc.) references a patient.
## Create a Patient
```ts theme={null}
const { data: patient } = await clinik.patients.create({
firstName: 'Jane',
lastName: 'Doe',
email: 'jane@example.com',
phone: '+1-555-0100',
gender: 'female',
birthDate: '1990-03-15',
maritalStatus: 'married',
address: {
line: ['123 Main St', 'Apt 4B'],
city: 'Austin',
state: 'TX',
postalCode: '78701',
country: 'US',
},
languages: [
{ language: 'en', preferred: true },
{ language: 'es' },
],
contact: [
{
relationship: 'spouse',
firstName: 'John',
lastName: 'Doe',
phone: '+1-555-0101',
email: 'john@example.com',
},
],
generalPractitionerId: 'prac_abc123',
photo: {
url: 'https://cdn.example.com/patients/jane.jpg',
contentType: 'image/jpeg',
},
});
```
## Read a Patient with Related Resources
The `include` option uses FHIR `_revinclude` to fetch related resources in a single call:
```ts theme={null}
const { data } = await clinik.patients.read(patient.id!, {
include: ['Encounter', 'Observation', 'MedicationRequest', 'Appointment'],
});
// Destructured response
console.log(data.patient); // Patient resource
console.log(data.encounters); // Encounter[]
console.log(data.observations); // Observation[]
console.log(data.prescriptions); // MedicationRequest[]
console.log(data.appointments); // Appointment[]
```
The full `PatientReadResponse` includes:
| Field | Type | Description |
| - | - | - |
| `patient` | `Patient` | The patient resource |
| `encounters` | `Encounter[]` | All encounters for this patient |
| `observations` | `Observation[]` | Vitals, lab values, etc. |
| `medications` | `Medication[]` | Medication records |
| `appointments` | `Appointment[]` | Scheduled appointments |
| `intakes` | `QuestionnaireResponse[]` | Intake forms |
| `consents` | `Consent[]` | Signed consents |
| `labs` | `DiagnosticReport[]` | Lab reports |
| `prescriptions` | `MedicationRequest[]` | Prescriptions |
| `notes` | `DocumentReference[]` | Clinical notes |
| `assessments` | `ClinicalImpression[]` | Clinical assessments |
| `documents` | `Composition[]` | Structured documents |
## Update a Patient
Updates use JSON Patch under the hood — only send the fields you want to change:
```ts theme={null}
const { data: updated } = await clinik.patients.update(patient.id!, {
phone: '+1-555-0200',
address: {
line: ['456 Oak Ave'],
city: 'Dallas',
state: 'TX',
postalCode: '75201',
},
});
```
## Search Patients
```ts theme={null}
const { data: results } = await clinik.patients.search({
name: 'Doe',
gender: 'female',
count: 20,
});
for (const patient of results.data) {
console.log(patient.name?.[0]?.family); // "Doe"
}
// Pagination
if (results.hasMore) {
const { data: nextPage } = await clinik.patients.search({
name: 'Doe',
cursor: results.cursor,
});
}
```
### Search Parameters
| Parameter | Type | Description |
| - | - | - |
| `name` | `string` | Search by name (partial match) |
| `email` | `string` | Exact email match |
| `phone` | `string` | Exact phone match |
| `birthDate` | `string` | Date of birth (YYYY-MM-DD) |
| `gender` | `string` | male, female, other, unknown |
| `active` | `boolean` | Filter by active status |
| `count` | `number` | Results per page (default: 20, max: 100) |
| `cursor` | `string` | Pagination cursor |
## Delete a Patient
```ts theme={null}
await clinik.patients.delete(patient.id!);
```
Deleting a patient does not cascade to related resources. Delete dependent resources first if needed.
# Payment Notices
Source: https://docs.clinikapi.com/guides/payment-notices
Notify recipients about payment events and status changes.
# Payment Notices
Payment Notices (FHIR `PaymentNotice`) communicate payment status information between payers and providers. They link to a `PaymentReconciliation` and notify the recipient organization about the payment event.
## Send a Payment Notice
```ts theme={null}
const { data: notice } = await clinik.paymentNotices.create({
status: 'active',
paymentId: 'pmtrec_settlement789',
recipientId: 'org_sunriseMedical',
amount: { value: 1250.00, currency: 'USD' },
paymentDate: '2024-03-15',
paymentStatus: 'paid',
providerId: 'Organization/org_blueShield',
});
```
## Payment Notice with Request/Response References
Link the notice to the original claim and its adjudication:
```ts theme={null}
const { data: notice } = await clinik.paymentNotices.create({
status: 'active',
paymentId: 'pmtrec_q1settlement',
recipientId: 'org_cardiology',
amount: { value: 3500.00, currency: 'USD' },
paymentDate: '2024-03-31',
paymentStatus: 'cleared',
requestId: 'Claim/clm_knee123',
responseId: 'ClaimResponse/clmresp_knee123',
});
```
## Search Payment Notices
```ts theme={null}
// All notices for a provider
const { data } = await clinik.paymentNotices.search({
providerId: 'Organization/org_blueShield',
});
// Filter by date range
const { data: recent } = await clinik.paymentNotices.search({
dateFrom: '2024-01-01',
dateTo: '2024-03-31',
status: 'active',
});
```
## Payment Status Values
| Status | Description |
| - | - |
| `paid` | Payment has been made |
| `cleared` | Payment has cleared |
# Payment Reconciliations
Source: https://docs.clinikapi.com/guides/payment-reconciliations
Track payment settlements with line-item detail and processing notes.
# Payment Reconciliations
Payment Reconciliations (FHIR `PaymentReconciliation`) provide detailed payment settlement information from payers to providers. They include line-item breakdowns showing how individual claims were settled.
## Record a Payment Settlement
```ts theme={null}
const { data: reconciliation } = await clinik.paymentReconciliations.create({
status: 'active',
paymentDate: '2024-03-15',
paymentAmount: { value: 4750.00, currency: 'USD' },
paymentIssuerId: 'org_blueShield',
outcome: 'complete',
disposition: 'Monthly settlement — March 2024',
period: { start: '2024-03-01', end: '2024-03-31' },
detail: [
{
type: 'payment',
date: '2024-03-15',
amount: { value: 2500.00, currency: 'USD' },
payeeId: 'Practitioner/prac_drSmith',
requestId: 'Claim/clm_visit001',
},
{
type: 'payment',
date: '2024-03-15',
amount: { value: 1800.00, currency: 'USD' },
payeeId: 'Practitioner/prac_drJones',
requestId: 'Claim/clm_visit002',
},
{
type: 'adjustment',
date: '2024-03-15',
amount: { value: 450.00, currency: 'USD' },
},
],
processNote: [
{ type: 'display', text: 'All claims for March settled. Adjustment for overpayment on CLM-2024-002.' },
],
});
```
## Partial Payment
```ts theme={null}
const { data: partial } = await clinik.paymentReconciliations.create({
status: 'active',
paymentDate: '2024-03-20',
paymentAmount: { value: 800.00, currency: 'USD' },
paymentIssuerId: 'org_aetna',
outcome: 'partial',
disposition: 'Partial payment — pending additional documentation',
detail: [
{
type: 'payment',
amount: { value: 800.00, currency: 'USD' },
requestId: 'Claim/clm_surgery456',
},
],
processNote: [
{ text: 'Remaining $2,200 pending operative report submission' },
],
});
```
## Search Payment Reconciliations
```ts theme={null}
// All reconciliations by outcome
const { data } = await clinik.paymentReconciliations.search({
outcome: 'complete',
});
// Filter by date range
const { data: q1 } = await clinik.paymentReconciliations.search({
dateFrom: '2024-01-01',
dateTo: '2024-03-31',
status: 'active',
});
```
## Outcome Values
| Outcome | Description |
| - | - |
| `queued` | Payment is queued for processing |
| `complete` | Payment fully processed |
| `error` | Error during processing |
| `partial` | Partial payment issued |
# Persons
Source: https://docs.clinikapi.com/guides/persons
Manage person records that link across patients, practitioners, and related persons.
# Persons
Persons (FHIR `Person`) represent a common demographic record that may be linked to multiple patient, practitioner, or related person records. They are useful for identity management and record linkage across the system.
## Create a Person
```ts theme={null}
const { data: person } = await clinik.persons.create({
firstName: 'Maria',
lastName: 'Garcia',
phone: '555-0142',
email: 'maria.garcia@example.com',
gender: 'female',
birthDate: '1985-07-22',
address: {
line: ['456 Oak Avenue'],
city: 'San Antonio',
state: 'TX',
postalCode: '78205',
},
managingOrganizationId: 'org_sunrise',
});
```
## Link to Other Records
A person can be linked to patient, practitioner, or related person records with varying levels of assurance:
```ts theme={null}
const { data } = await clinik.persons.create({
firstName: 'James',
lastName: 'Wilson',
email: 'james.wilson@example.com',
link: [
{ targetId: 'Patient/pt_james_wilson', assurance: 'level4' },
{ targetId: 'Practitioner/dr_wilson', assurance: 'level3' },
],
});
```
## Assurance Levels
| Level | Description |
| - | - |
| `level1` | No matching criteria met |
| `level2` | Some criteria met |
| `level3` | High confidence match |
| `level4` | Verified — this is the same person |
## Update a Person
```ts theme={null}
await clinik.persons.update(person.id, {
phone: '555-0199',
link: [
{ targetId: 'Patient/pt_maria_garcia', assurance: 'level4' },
],
});
```
## Search Persons
```ts theme={null}
const { data } = await clinik.persons.search({
name: 'Garcia',
active: true,
});
```
## Person vs Patient
| Resource | Purpose |
| - | - |
| Person | Identity record — links across systems |
| Patient | Clinical record — encounters, observations, medications |
Use Person when you need to track a single individual across multiple roles or systems. Use Patient for clinical care data.
# Plan Definitions
Source: https://docs.clinikapi.com/guides/plan-definitions
Define clinical protocols, order sets, and workflow templates for standardized care delivery.
# Plan Definitions
Plan definitions (FHIR `PlanDefinition`) describe reusable clinical protocols, order sets, and workflow templates. They define goals and a sequence of actions that should be taken as part of a care pathway.
## Create a Plan Definition
```ts theme={null}
const { data: plan } = await clinik.planDefinitions.create({
status: 'active',
name: 'diabetes-management-protocol',
title: 'Type 2 Diabetes Management Protocol',
type: 'clinical-protocol',
description: 'Standard protocol for managing Type 2 Diabetes in primary care',
goal: [
{ description: 'HbA1c below 7%', priority: 'high-priority', category: 'physiologic' },
{ description: 'Blood pressure below 130/80', priority: 'high-priority' },
{ description: 'LDL cholesterol below 100 mg/dL', priority: 'medium-priority' },
],
action: [
{ title: 'Initial Assessment', description: 'Complete metabolic panel and HbA1c', priority: 'routine', code: 'initial-assessment' },
{ title: 'Quarterly Follow-up', description: 'HbA1c check every 3 months', priority: 'routine' },
{ title: 'Annual Eye Exam', description: 'Dilated eye exam referral', priority: 'routine', type: 'referral' },
{ title: 'Annual Foot Exam', description: 'Comprehensive foot examination', priority: 'routine' },
],
topic: ['diabetes', 'chronic-disease-management'],
});
```
## Common Use Cases
### Order Set
```ts theme={null}
const { data } = await clinik.planDefinitions.create({
status: 'active',
name: 'pre-op-cardiac-order-set',
title: 'Pre-Operative Cardiac Assessment Order Set',
type: 'order-set',
description: 'Standard pre-operative cardiac workup',
action: [
{ title: 'ECG', code: 'ecg', priority: 'urgent' },
{ title: 'Chest X-Ray', code: 'chest-xray', priority: 'routine' },
{ title: 'CBC', code: 'cbc', priority: 'routine' },
{ title: 'BMP', code: 'bmp', priority: 'routine' },
{ title: 'Coagulation Panel', code: 'coag-panel', priority: 'routine' },
],
});
```
### Workflow Definition
```ts theme={null}
const { data } = await clinik.planDefinitions.create({
status: 'active',
name: 'patient-intake-workflow',
title: 'New Patient Intake Workflow',
type: 'workflow-definition',
action: [
{ title: 'Registration', description: 'Complete patient demographics', type: 'create' },
{ title: 'Insurance Verification', description: 'Verify coverage eligibility', type: 'create' },
{ title: 'Health History', description: 'Complete intake questionnaire', type: 'create' },
{ title: 'Vitals', description: 'Record initial vital signs', type: 'create' },
{ title: 'Provider Assignment', description: 'Assign to available provider', type: 'create' },
],
});
```
## Search Plan Definitions
```ts theme={null}
const { data } = await clinik.planDefinitions.search({
status: 'active',
type: 'clinical-protocol',
title: 'diabetes',
});
```
## Advanced Features
For advanced PlanDefinition features like `dynamicValue`, `expression`, `library`, or `relatedArtifact`, use the [FHIR Passthrough](/sdk/fhir-passthrough):
```ts theme={null}
const { data } = await clinik.fhir.request('POST', '/PlanDefinition', {
resourceType: 'PlanDefinition',
status: 'active',
// ... full FHIR R4 PlanDefinition
});
```
# Practitioner Roles
Source: https://docs.clinikapi.com/guides/practitioner-roles
Define where and when practitioners practice — roles, availability, and specialties.
# Practitioner Roles
PractitionerRole defines the role a practitioner plays at a specific organization or location. A single practitioner can have multiple roles — cardiologist at one hospital, consultant at another clinic.
## Create a Practitioner Role
```ts theme={null}
const { data: role } = await clinik.practitionerRoles.create({
practitionerId: 'prac_abc123',
organizationName: 'Austin Heart Clinic',
role: 'doctor',
specialty: ['Cardiology', 'Interventional Cardiology'],
locationName: 'Main Campus - Building A',
phone: '+1-555-0100',
email: 'dr.chen@austinheart.com',
period: { start: '2024-01-01' },
availableTime: [
{
daysOfWeek: ['mon', 'tue', 'wed', 'thu', 'fri'],
availableStartTime: '08:00:00',
availableEndTime: '17:00:00',
},
],
notAvailable: [
{ description: 'Annual leave', during: { start: '2025-08-01', end: '2025-08-15' } },
],
availabilityExceptions: 'Closed on public holidays',
});
```
## Multiple Availability Schedules
A practitioner can have different hours on different days:
```ts theme={null}
await clinik.practitionerRoles.create({
practitionerId: 'prac_abc123',
organizationName: "St. David's Medical Center",
role: 'consultant',
specialty: ['Cardiology'],
availableTime: [
{
daysOfWeek: ['tue', 'thu'],
availableStartTime: '13:00:00',
availableEndTime: '17:00:00',
},
{
daysOfWeek: ['sat'],
availableStartTime: '09:00:00',
availableEndTime: '12:00:00',
},
],
});
```
## Unavailability Periods
Mark periods when the practitioner is not available:
```ts theme={null}
await clinik.practitionerRoles.update('role_xyz789', {
notAvailable: [
{ description: 'Medical conference', during: { start: '2025-06-10', end: '2025-06-14' } },
{ description: 'Personal leave', during: { start: '2025-07-01', end: '2025-07-05' } },
],
availabilityExceptions: 'May be available for emergencies during leave periods',
});
```
## Update Availability
```ts theme={null}
await clinik.practitionerRoles.update('role_xyz789', {
availableDays: ['mon', 'wed', 'fri'],
availableStartTime: '09:00',
availableEndTime: '16:00',
});
```
## Deactivate a Role
```ts theme={null}
await clinik.practitionerRoles.update('role_xyz789', {
active: false,
});
```
## Search Roles
```ts theme={null}
const { data } = await clinik.practitionerRoles.search({
count: 50,
});
```
## Practitioner vs PractitionerRole
| Resource | Purpose |
| - | - |
| Practitioner | The person (name, NPI, qualifications) |
| PractitionerRole | Where/when they practice (org, schedule, specialty in context) |
A practitioner is created once. Roles are created for each organization/location they work at.
# Practitioners
Source: https://docs.clinikapi.com/guides/practitioners
Manage clinicians, physicians, and healthcare providers.
# Practitioners
Practitioners represent healthcare providers — physicians, nurses, therapists, and other clinicians. They are referenced by encounters, prescriptions, notes, and other clinical resources.
## Create a Practitioner
```ts theme={null}
const { data: doc } = await clinik.practitioners.create({
firstName: 'Sarah',
lastName: 'Chen',
prefix: ['Dr.'],
suffix: ['MD', 'FACC'],
email: 'dr.chen@austinheart.com',
phone: '+1-555-0100',
gender: 'female',
npi: '1234567890',
specialty: 'Cardiology',
qualifications: [
{
name: 'Doctor of Medicine',
issuer: 'Johns Hopkins University',
period: { start: '2010-05-15' },
},
{
name: 'Board Certified - Cardiovascular Disease',
issuer: 'American Board of Internal Medicine',
identifier: 'ABIM-12345',
period: { start: '2015-06-01', end: '2025-06-01' },
},
],
languages: ['en', 'zh'],
address: {
line: ['100 Medical Center Blvd'],
city: 'Austin',
state: 'TX',
postalCode: '78701',
},
photo: {
url: 'https://cdn.austinheart.com/staff/dr-chen.jpg',
contentType: 'image/jpeg',
},
});
```
## Practitioner Roles
A practitioner can have multiple roles at different organizations. Use `clinik.practitionerRoles` to define where and when they practice:
```ts theme={null}
// Dr. Chen is a cardiologist at Austin Heart Clinic
await clinik.practitionerRoles.create({
practitionerId: doc.id!,
organizationName: 'Austin Heart Clinic',
role: 'doctor',
specialty: ['Cardiology', 'Interventional Cardiology'],
locationName: 'Main Campus',
period: { start: '2024-01-01' },
availableTime: [
{
daysOfWeek: ['mon', 'tue', 'wed', 'thu', 'fri'],
availableStartTime: '08:00:00',
availableEndTime: '17:00:00',
},
],
notAvailable: [
{ description: 'Annual conference', during: { start: '2025-10-01', end: '2025-10-05' } },
],
});
// She also consults at St. David's Hospital on Thursdays
await clinik.practitionerRoles.create({
practitionerId: doc.id!,
organizationName: "St. David's Medical Center",
role: 'consultant',
specialty: ['Cardiology'],
locationName: 'Cardiology Wing',
availableTime: [
{
daysOfWeek: ['thu'],
availableStartTime: '13:00:00',
availableEndTime: '17:00:00',
},
],
});
```
## Referencing Practitioners
Most clinical resources reference practitioners:
```ts theme={null}
// Encounter with a practitioner
await clinik.encounters.create({
status: 'in-progress',
class: 'AMB',
patientId: 'pt_abc123',
practitionerId: doc.id!,
type: 'Cardiology follow-up',
});
// Prescription by a practitioner
await clinik.prescriptions.create({
patientId: 'pt_abc123',
prescriberId: doc.id!,
medication: 'Lisinopril 10mg',
intent: 'order',
});
// Clinical note by a practitioner
await clinik.notes.create({
patientId: 'pt_abc123',
authorId: doc.id!,
title: 'Cardiology Consultation',
content: 'Patient presents with well-controlled hypertension...',
type: 'consultation-note',
});
```
## Search Practitioners
```ts theme={null}
// Find cardiologists
const { data } = await clinik.practitioners.search({
specialty: 'Cardiology',
active: true,
});
// Search by NPI
const { data: byNpi } = await clinik.practitioners.search({
npi: '1234567890',
});
```
## Deactivate a Practitioner
```ts theme={null}
await clinik.practitioners.update(doc.id!, {
active: false,
});
```
# Prescriptions
Source: https://docs.clinikapi.com/guides/prescriptions
Create and manage medication orders with dosage instructions.
# Prescriptions
Prescriptions (FHIR `MedicationRequest`) represent medication orders written by practitioners.
## Create a Prescription
```ts theme={null}
const { data: rx } = await clinik.prescriptions.create({
patientId: 'pt_abc123',
prescriberId: 'prac_def456',
encounterId: 'enc_xyz789',
medication: {
system: 'http://www.nlm.nih.gov/research/umls/rxnorm',
code: '197361',
display: 'Lisinopril 10 MG Oral Tablet',
},
intent: 'order',
status: 'active',
priority: 'routine',
category: 'outpatient',
authoredOn: '2026-04-29T10:00:00Z',
dosageText: 'Take 1 tablet by mouth once daily',
dosage: {
dose: { value: 10, unit: 'mg' },
frequency: 1,
period: 1,
periodUnit: 'd',
route: 'oral',
},
refills: 3,
quantity: { value: 30, unit: 'tablets' },
supplyDays: 30,
substitutionAllowed: true,
reason: 'Essential hypertension',
note: 'Monitor blood pressure weekly',
courseOfTherapy: 'continuous',
});
```
## New Fields
### Status Reason
Explain why a prescription is on-hold, cancelled, or stopped:
```ts theme={null}
await clinik.prescriptions.update('rx_abc123', {
status: 'on-hold',
statusReason: 'Patient reported dizziness — holding pending follow-up',
});
```
### Category
Classify the medication usage context:
```ts theme={null}
const { data } = await clinik.prescriptions.create({
patientId: 'pt_abc123',
prescriberId: 'prac_def456',
medication: 'Metformin 500mg',
category: 'discharge', // inpatient, outpatient, community, discharge
// ...
});
```
### Do Not Perform
Create a "do not administer" order:
```ts theme={null}
const { data } = await clinik.prescriptions.create({
patientId: 'pt_abc123',
prescriberId: 'prac_def456',
medication: 'Aspirin',
doNotPerform: true,
reason: 'Patient has aspirin allergy',
// ...
});
```
### Performer
Specify who should administer the medication:
```ts theme={null}
const { data } = await clinik.prescriptions.create({
patientId: 'pt_abc123',
prescriberId: 'prac_def456',
medication: 'Insulin Glargine 100 units/mL',
performerId: 'prac_nurse789',
// ...
});
```
### Course of Therapy
Indicate the overall pattern of medication administration:
```ts theme={null}
const { data } = await clinik.prescriptions.create({
patientId: 'pt_abc123',
prescriberId: 'prac_def456',
medication: 'Prednisone 10mg',
courseOfTherapy: 'acute', // continuous, acute, seasonal
// ...
});
```
### Prior Prescription
Link to a prescription being replaced:
```ts theme={null}
const { data } = await clinik.prescriptions.create({
patientId: 'pt_abc123',
prescriberId: 'prac_def456',
medication: 'Lisinopril 20 MG Oral Tablet',
priorPrescriptionId: 'rx_old456',
reason: 'Dose increase — blood pressure not controlled at 10mg',
// ...
});
```
## Dosage Options
You can provide dosage as free text, structured data, or both:
```ts theme={null}
// Free text only
{ dosageText: 'Take 1 tablet twice daily with food' }
// Structured only
{
dosage: {
dose: { value: 500, unit: 'mg' },
frequency: 2,
period: 1,
periodUnit: 'd',
route: 'oral',
}
}
// Both (recommended — structured for computation, text for display)
{
dosageText: 'Take 500mg twice daily with food',
dosage: {
dose: { value: 500, unit: 'mg' },
frequency: 2,
period: 1,
periodUnit: 'd',
route: 'oral',
}
}
```
### Period Units
| Unit | Meaning |
| - | - |
| `h` | Hours |
| `d` | Days |
| `wk` | Weeks |
| `mo` | Months |
## Update a Prescription
```ts theme={null}
// Put a prescription on hold
const { data: updated } = await clinik.prescriptions.update('rx_abc123', {
status: 'on-hold',
statusReason: 'Patient reported dizziness — holding pending follow-up',
});
// Change priority
await clinik.prescriptions.update('rx_abc123', {
priority: 'urgent',
performerId: 'prac_nurse789',
});
// Cancel a prescription
await clinik.prescriptions.update('rx_abc123', {
status: 'cancelled',
statusReason: 'Replaced with alternative medication',
});
```
## Search Prescriptions
```ts theme={null}
const { data: results } = await clinik.prescriptions.search({
patientId: 'pt_abc123',
status: 'active',
prescriberId: 'prac_def456',
});
for (const rx of results.data) {
console.log(`${rx.medication} — ${rx.dosageText}`);
console.log(` Category: ${rx.category}, Course: ${rx.courseOfTherapy}`);
}
```
## Status Lifecycle
`draft` → `active` → `on-hold` → `completed` / `cancelled` / `stopped`
Use `statusReason` to document why a prescription changed status.
## Complete Field Reference
| Field | Type | Description |
| - | - | - |
| `patientId` | `string` | Patient reference (required) |
| `prescriberId` | `string` | Prescribing practitioner (required) |
| `medication` | `string \| CodeableConcept` | Medication code or name (required) |
| `intent` | `string` | proposal, plan, order, original-order |
| `status` | `string` | active, on-hold, cancelled, completed, draft |
| `statusReason` | `string` | Reason for current status |
| `priority` | `string` | routine, urgent, asap, stat |
| `category` | `string` | inpatient, outpatient, community, discharge |
| `doNotPerform` | `boolean` | True if prohibiting the medication |
| `authoredOn` | `string` | When authored (ISO 8601, defaults to now) |
| `performerId` | `string` | Intended performer of administration |
| `courseOfTherapy` | `string` | continuous, acute, seasonal |
| `priorPrescriptionId` | `string` | Reference to replaced prescription |
| `dosageText` | `string` | Human-readable dosage instructions |
| `dosage` | `object` | Structured dosage (dose, frequency, period, route) |
| `refills` | `number` | Number of refills (0-99) |
| `quantity` | `{ value, unit }` | Quantity to dispense |
| `supplyDays` | `number` | Expected supply duration in days |
| `substitutionAllowed` | `boolean` | Allow generic substitution |
| `reason` | `string` | Clinical reason for the prescription |
| `note` | `string` | Additional notes for the pharmacist |
# Raw FHIR Passthrough
Source: https://docs.clinikapi.com/guides/raw-fhir
Send raw FHIR R4 requests when the simplified API doesn't cover your use case.
# Raw FHIR Passthrough
The simplified SDK covers the most common use cases, but sometimes you need to send raw FHIR R4 requests — custom search parameters, FHIR operations, or resource types we haven't simplified yet.
The FHIR passthrough routes requests directly to the ClinikAPI FHIR gateway with your tenant context automatically applied.
## SDK Usage
```ts theme={null}
// Create a raw FHIR resource
const { data } = await clinik.fhir.request('POST', '/Patient', {
resourceType: 'Patient',
name: [{ family: 'Smith', given: ['John'] }],
gender: 'male',
birthDate: '1990-01-15',
});
// Search with custom FHIR parameters
const { data: bundle } = await clinik.fhir.request(
'GET',
'/Observation?code=8867-4&date=ge2024-01-01&_sort=-date&_count=50'
);
// Read a specific resource
const { data: patient } = await clinik.fhir.request('GET', '/Patient/pt_abc123');
// Delete a resource
await clinik.fhir.request('DELETE', '/Observation/obs_xyz789');
```
## REST API
```bash theme={null}
# Create
curl -X POST https://api.clinikapi.com/v1/fhir/Patient \
-H "x-api-key: clk_live_abc123" \
-H "Content-Type: application/fhir+json" \
-d '{"resourceType":"Patient","name":[{"family":"Smith"}]}'
# Search
curl "https://api.clinikapi.com/v1/fhir/Observation?code=8867-4&_count=10" \
-H "x-api-key: clk_live_abc123"
# Read
curl https://api.clinikapi.com/v1/fhir/Patient/pt_abc123 \
-H "x-api-key: clk_live_abc123"
```
## Tenant Isolation
Even in passthrough mode, tenant isolation is enforced:
* **Creates**: your tenant tag is automatically injected into `meta.tag`
* **Searches**: a `_tag` filter is automatically appended
* **Reads/Updates/Deletes**: ownership is verified
You cannot bypass tenant isolation through the FHIR passthrough.
## FHIR CapabilityStatement
The `/v1/metadata` endpoint returns a FHIR R4 CapabilityStatement (no auth required):
```bash theme={null}
curl https://api.clinikapi.com/v1/metadata
```
This describes all supported resource types, search parameters, and operations.
## When to Use Passthrough
| Use Case | Recommended Approach |
| - | - |
| Standard CRUD operations | Use the simplified SDK methods |
| Custom FHIR search parameters | Use `clinik.fhir.request('GET', ...)` |
| FHIR operations (`$everything`, `$validate`) | Use `clinik.fhir.request('POST', ...)` |
| Resource types not in the SDK | Use `clinik.fhir.request(...)` |
| Complex FHIR queries | Use `clinik.fhir.request('GET', ...)` |
The passthrough returns raw FHIR R4 resources — not the simplified format used by the SDK methods.
You'll need to work with FHIR resource structures directly.
# Risk Assessments
Source: https://docs.clinikapi.com/guides/risk-assessments
Record and manage clinical risk evaluations — cardiovascular risk, fall risk, cancer screening, and more.
# Risk Assessments
Risk assessments (FHIR `RiskAssessment`) capture the results of clinical risk evaluations. They record the method used, the predictions made, and any recommended mitigation actions.
## Create a Risk Assessment
```ts theme={null}
const { data: risk } = await clinik.riskAssessments.create({
status: 'final',
patientId: 'pt_abc123',
performerId: 'prac_def456',
method: 'Framingham Risk Score',
code: 'cardiovascular-risk',
conditionId: 'cond_hypertension',
prediction: [
{
outcome: 'Myocardial infarction',
probabilityDecimal: 0.12,
qualitativeRisk: 'moderate',
rationale: '10-year ASCVD risk based on age, cholesterol, blood pressure, smoking status',
},
],
mitigation: 'Start statin therapy. Lifestyle modifications recommended.',
reasonCode: ['Hypertension', 'Hyperlipidemia'],
});
```
## Common Use Cases
### Cardiovascular Risk Score
```ts theme={null}
const { data } = await clinik.riskAssessments.create({
status: 'final',
patientId: 'pt_abc123',
performerId: 'prac_cardiologist',
method: 'ASCVD Pooled Cohort Equations',
code: '10-year-ascvd-risk',
prediction: [
{
outcome: 'Atherosclerotic cardiovascular disease event',
probabilityDecimal: 0.15,
qualitativeRisk: 'high',
rationale: 'Age 62, male, total cholesterol 240, HDL 38, systolic BP 148, on BP meds, non-diabetic, smoker',
},
],
mitigation: 'High-intensity statin therapy. Smoking cessation counseling. Blood pressure optimization.',
});
```
### Fall Risk Assessment
```ts theme={null}
const { data } = await clinik.riskAssessments.create({
status: 'final',
patientId: 'pt_elderly',
performerId: 'prac_nurse',
method: 'Morse Fall Scale',
code: 'fall-risk',
prediction: [
{
outcome: 'Fall',
qualitativeRisk: 'high',
rationale: 'Score 55: history of falling, secondary diagnosis, ambulatory aid, IV therapy, impaired gait',
},
],
mitigation: 'Fall precautions: bed alarm, non-slip footwear, call light within reach, hourly rounding',
});
```
### Cancer Screening Risk
```ts theme={null}
const { data } = await clinik.riskAssessments.create({
status: 'final',
patientId: 'pt_abc123',
performerId: 'prac_oncologist',
method: 'Gail Model',
code: 'breast-cancer-risk',
prediction: [
{
outcome: 'Invasive breast cancer',
probabilityDecimal: 0.023,
qualitativeRisk: 'moderate',
relativeRisk: 1.8,
rationale: '5-year risk based on age, family history, reproductive history, prior biopsies',
},
],
mitigation: 'Annual mammography. Consider MRI screening. Discuss chemoprevention options.',
reasonCode: ['Family history of breast cancer', 'Prior atypical ductal hyperplasia'],
});
```
## Update Predictions
```ts theme={null}
const { data } = await clinik.riskAssessments.update(risk.id, {
status: 'amended',
prediction: [
{
outcome: 'Myocardial infarction',
probabilityDecimal: 0.08,
qualitativeRisk: 'moderate',
rationale: 'Revised after 6 months of statin therapy and lifestyle changes',
},
],
mitigation: 'Continue current statin therapy. Reassess in 6 months.',
});
```
## Search Risk Assessments
```ts theme={null}
const { data } = await clinik.riskAssessments.search({
patientId: 'pt_abc123',
status: 'final',
method: 'Framingham',
});
```
# Schedules
Source: https://docs.clinikapi.com/guides/schedules
Manage practitioner and location schedules for appointment booking.
# Schedules
Schedules (FHIR `Schedule`) define a container for time slots that may be available for booking appointments. They connect practitioners, locations, or services to their availability windows.
## Create a Schedule
```ts theme={null}
const { data: schedule } = await clinik.schedules.create({
active: true,
serviceCategory: ['General Practice'],
serviceType: ['Consultation', 'Follow-up'],
specialty: ['Family Medicine'],
actorIds: ['Practitioner/dr_smith', 'Location/room_101'],
planningHorizon: {
start: '2025-03-01T00:00:00Z',
end: '2025-06-30T23:59:59Z',
},
comment: 'Dr. Smith Monday-Friday schedule for Q2 2025',
});
```
## Schedule + Slots Workflow
Schedules are containers — the actual bookable time windows are defined as Slots:
```ts theme={null}
// 1. Create a schedule for a practitioner
const { data: schedule } = await clinik.schedules.create({
actorIds: ['Practitioner/dr_jones'],
serviceType: ['Cardiology Consultation'],
specialty: ['Cardiology'],
planningHorizon: {
start: '2025-04-01T00:00:00Z',
end: '2025-04-30T23:59:59Z',
},
});
// 2. Create slots on that schedule
for (let day = 1; day <= 30; day++) {
const date = `2025-04-${String(day).padStart(2, '0')}`;
for (let hour = 9; hour < 17; hour++) {
await clinik.slots.create({
scheduleId: schedule.id,
status: 'free',
start: `${date}T${String(hour).padStart(2, '0')}:00:00Z`,
end: `${date}T${String(hour).padStart(2, '0')}:30:00Z`,
});
}
}
// 3. When a patient books, create an appointment and mark the slot busy
```
## Multi-Actor Schedules
A schedule can reference multiple actors (e.g., a practitioner and a room):
```ts theme={null}
const { data } = await clinik.schedules.create({
actorIds: [
'Practitioner/dr_patel',
'Location/ultrasound_room_2',
],
serviceType: ['Obstetric Ultrasound'],
specialty: ['Obstetrics'],
planningHorizon: {
start: '2025-05-01T00:00:00Z',
end: '2025-05-31T23:59:59Z',
},
});
```
## Deactivate a Schedule
```ts theme={null}
await clinik.schedules.update(schedule.id, {
active: false,
comment: 'Dr. Smith on leave — schedule paused',
});
```
## Search Schedules
```ts theme={null}
const { data } = await clinik.schedules.search({
specialty: 'Cardiology',
active: true,
});
```
# Service Requests
Source: https://docs.clinikapi.com/guides/service-requests
Create and manage clinical orders — lab orders, imaging requests, referrals, and procedures.
# Service Requests
Service requests (FHIR `ServiceRequest`) represent orders for clinical services — lab orders, imaging requests, referrals, procedure orders, and other clinical activities that need to be fulfilled.
## Create a Service Request
```ts theme={null}
const { data: order } = await clinik.serviceRequests.create({
status: 'active',
intent: 'order',
patientId: 'pt_abc123',
encounterId: 'enc_xyz789',
code: {
system: 'http://loinc.org',
code: '24323-8',
display: 'Comprehensive Metabolic Panel',
},
category: ['laboratory'],
priority: 'urgent',
requesterId: 'prac_def456',
occurrenceDateTime: '2025-02-01T08:00:00Z',
reasonCode: ['Pre-operative assessment'],
note: 'Fasting required — draw before 10am',
patientInstruction: 'Do not eat or drink after midnight',
});
```
## Common Use Cases
### Lab Order
```ts theme={null}
const { data } = await clinik.serviceRequests.create({
status: 'active',
intent: 'order',
patientId: 'pt_abc123',
code: { system: 'http://loinc.org', code: '24331-1', display: 'Lipid Panel' },
category: ['laboratory'],
priority: 'routine',
requesterId: 'prac_def456',
});
```
### Imaging Request
```ts theme={null}
const { data } = await clinik.serviceRequests.create({
status: 'active',
intent: 'order',
patientId: 'pt_abc123',
code: 'MRI Brain without contrast',
category: ['imaging'],
priority: 'urgent',
requesterId: 'prac_def456',
reasonCode: ['Persistent headaches', 'Rule out intracranial pathology'],
bodySite: ['Brain'],
});
```
### Referral
```ts theme={null}
const { data } = await clinik.serviceRequests.create({
status: 'active',
intent: 'order',
patientId: 'pt_abc123',
code: 'Cardiology consultation',
category: ['referral'],
priority: 'routine',
requesterId: 'prac_pcp',
performerType: 'Cardiologist',
reasonCode: ['Uncontrolled hypertension despite dual therapy'],
patientInstruction: 'Bring your home blood pressure log to the appointment',
});
```
### Do Not Perform
```ts theme={null}
const { data } = await clinik.serviceRequests.create({
status: 'active',
intent: 'order',
patientId: 'pt_abc123',
code: 'Aspirin administration',
doNotPerform: true,
reasonCode: ['Aspirin allergy'],
});
```
## Status Lifecycle
`draft` → `active` → `on-hold` → `completed` / `revoked`
## Linking to Tasks
Service requests are often fulfilled by tasks:
```ts theme={null}
// Create the order
const { data: order } = await clinik.serviceRequests.create({
status: 'active', intent: 'order',
patientId: 'pt_abc123',
code: 'CBC',
category: ['laboratory'],
});
// Create a task to fulfill it
const { data: task } = await clinik.tasks.create({
status: 'requested', intent: 'order',
patientId: 'pt_abc123',
basedOn: [`ServiceRequest/${order.id}`],
code: 'lab-draw',
description: 'Draw blood for CBC',
});
```
## Search Service Requests
```ts theme={null}
const { data } = await clinik.serviceRequests.search({
patientId: 'pt_abc123',
status: 'active',
category: 'laboratory',
priority: 'urgent',
sort: '-date',
});
```
# Slots
Source: https://docs.clinikapi.com/guides/slots
Manage scheduling slots — define available time periods for booking appointments.
# Slots
Slots (FHIR `Slot`) represent available time periods on a practitioner's or location's schedule. They define when appointments can be booked and are the building blocks of a scheduling system.
## Create Available Slots
```ts theme={null}
// Generate morning slots for a practitioner
const slots = [];
for (let hour = 9; hour < 12; hour++) {
const { data } = await clinik.slots.create({
scheduleId: 'sched_dr_smith_mon',
status: 'free',
start: `2025-02-03T${String(hour).padStart(2, '0')}:00:00Z`,
end: `2025-02-03T${String(hour).padStart(2, '0')}:30:00Z`,
serviceType: 'General consultation',
specialty: 'Family Medicine',
appointmentType: 'routine',
});
slots.push(data);
}
```
## Slot Status Values
| Status | Description |
| - | - |
| `free` | Available for booking |
| `busy` | Already booked |
| `busy-unavailable` | Blocked (lunch, meeting, etc.) |
| `busy-tentative` | Tentatively held |
## Book a Slot
When an appointment is booked, update the slot status:
```ts theme={null}
// Mark slot as busy when appointment is confirmed
await clinik.slots.update('slot_abc123', {
status: 'busy',
});
```
## Block Time
Block out time for non-appointment activities:
```ts theme={null}
const { data } = await clinik.slots.create({
scheduleId: 'sched_dr_smith_mon',
status: 'busy-unavailable',
start: '2025-02-03T12:00:00Z',
end: '2025-02-03T13:00:00Z',
comment: 'Lunch break',
});
```
## Overbooked Slots
Flag slots that have been double-booked:
```ts theme={null}
await clinik.slots.update('slot_abc123', {
status: 'busy',
overbooked: true,
comment: 'Double-booked — urgent add-on',
});
```
## Search Available Slots
```ts theme={null}
// Find free slots for a schedule
const { data } = await clinik.slots.search({
scheduleId: 'sched_dr_smith_mon',
status: 'free',
dateFrom: '2025-02-03',
dateTo: '2025-02-07',
});
// Find slots by specialty
const { data: cardio } = await clinik.slots.search({
specialty: 'Cardiology',
status: 'free',
dateFrom: '2025-02-01',
});
```
## Scheduling Workflow
1. Create a `Schedule` for a practitioner/location (via FHIR passthrough)
2. Create `Slot` resources defining available time periods
3. When a patient books, create an `Appointment` and update the slot to `busy`
4. If cancelled, update the slot back to `free`
## Slots vs Appointments
| Resource | Purpose |
| - | - |
| Slot | Defines available time windows |
| Appointment | Represents a booked visit |
| AppointmentResponse | Participant's reply to an appointment |
Slots are the supply side of scheduling. Appointments are the demand side.
# Specimens
Source: https://docs.clinikapi.com/guides/specimens
Track biological samples from collection through laboratory testing.
# Specimens
Specimens (FHIR `Specimen`) represent biological samples collected from patients for laboratory analysis. ClinikAPI simplifies collection details and skips the processing array — use the [FHIR passthrough](/guides/raw-fhir) for advanced specimen processing workflows.
## Collect a Blood Sample
```ts theme={null}
const { data: specimen } = await clinik.specimens.create({
status: 'available',
type: 'blood',
patientId: 'pt_jane123',
collection: {
collectorId: 'Practitioner/prac_nurse456',
collectedDateTime: '2024-03-15T09:30:00Z',
quantity: { value: 10, unit: 'mL' },
method: 'venipuncture',
bodySite: 'left antecubital fossa',
},
container: [
{
type: 'EDTA tube',
description: 'Purple top tube',
capacity: { value: 10, unit: 'mL' },
specimenQuantity: { value: 8, unit: 'mL' },
},
],
condition: ['room-temperature'],
requestIds: ['sr_cbc789'],
});
```
## Tissue Biopsy
```ts theme={null}
const { data: biopsy } = await clinik.specimens.create({
type: 'tissue',
patientId: 'pt_john456',
collection: {
collectorId: 'Practitioner/prac_surgeon789',
collectedDateTime: '2024-03-15T14:00:00Z',
method: 'excisional biopsy',
bodySite: 'right breast',
},
container: [
{
type: 'formalin container',
description: '10% neutral buffered formalin',
},
],
note: 'Specimen labeled with patient name and DOB. Sent to pathology.',
requestIds: ['sr_pathology001'],
});
```
## Derived Specimen (Child from Parent)
```ts theme={null}
const { data: derived } = await clinik.specimens.create({
type: 'serum',
patientId: 'pt_jane123',
parentIds: [specimen.id],
receivedTime: '2024-03-15T10:00:00Z',
container: [
{ type: 'serum separator tube', capacity: { value: 5, unit: 'mL' } },
],
});
```
## Search Specimens
```ts theme={null}
// All specimens for a patient
const { data } = await clinik.specimens.search({
patientId: 'pt_jane123',
});
// Filter by type and status
const { data: blood } = await clinik.specimens.search({
patientId: 'pt_jane123',
type: 'blood',
status: 'available',
});
// Filter by collection date
const { data: recent } = await clinik.specimens.search({
dateFrom: '2024-03-01',
dateTo: '2024-03-31',
});
```
## Specimen Types
| Type | Description |
| - | - |
| `blood` | Whole blood sample |
| `serum` | Blood serum |
| `plasma` | Blood plasma |
| `urine` | Urine sample |
| `tissue` | Tissue biopsy |
| `saliva` | Saliva sample |
| `csf` | Cerebrospinal fluid |
| `stool` | Stool sample |
# Tasks
Source: https://docs.clinikapi.com/guides/tasks
Track clinical workflow items — lab orders, referrals, care coordination, and follow-ups.
# Tasks
Tasks (FHIR `Task`) represent actionable clinical workflow items that need to be tracked through a lifecycle. They're used for lab orders, referral follow-ups, care coordination, medication administration tracking, and any other clinical activity that needs assignment and status tracking.
## Create a Task
```ts theme={null}
const { data: task } = await clinik.tasks.create({
status: 'requested',
intent: 'order',
priority: 'urgent',
code: 'lab-order',
description: 'Order CBC and CMP for pre-operative assessment',
patientId: 'pt_abc123',
encounterId: 'enc_xyz789',
requesterId: 'prac_surgeon',
ownerId: 'prac_lab_tech',
executionPeriod: {
start: '2025-02-01T08:00:00Z',
end: '2025-02-01T17:00:00Z',
},
input: [
{ type: 'lab-panel', valueString: 'CBC' },
{ type: 'lab-panel', valueString: 'CMP' },
{ type: 'fasting-required', valueBoolean: true },
],
note: 'Patient is NPO after midnight. Draw labs before 10am.',
});
```
## Task Lifecycle
```
draft → requested → received → accepted → in-progress → completed
↘ on-hold → in-progress
↘ rejected
↘ cancelled
↘ failed
```
| Status | Description |
| - | - |
| `draft` | Task is being prepared |
| `requested` | Task has been requested |
| `received` | Owner has received the task |
| `accepted` | Owner has accepted the task |
| `rejected` | Owner has rejected the task |
| `ready` | Task is ready to be performed |
| `cancelled` | Task was cancelled |
| `in-progress` | Task is being worked on |
| `on-hold` | Task is paused |
| `failed` | Task could not be completed |
| `completed` | Task is done |
## Update Task Status
```ts theme={null}
// Accept a task
await clinik.tasks.update('task_abc123', {
status: 'accepted',
businessStatus: 'Assigned to lab technician',
});
// Mark as in-progress
await clinik.tasks.update('task_abc123', {
status: 'in-progress',
businessStatus: 'Specimen collected',
});
// Complete with output
await clinik.tasks.update('task_abc123', {
status: 'completed',
businessStatus: 'Results available',
output: [
{ type: 'lab-report', valueReference: 'DiagnosticReport/lab_cbc_001' },
{ type: 'lab-report', valueReference: 'DiagnosticReport/lab_cmp_001' },
],
});
```
## Task Inputs and Outputs
Tasks can carry structured data as inputs (what's needed) and outputs (what was produced):
```ts theme={null}
// Input: what the task needs
input: [
{ type: 'medication', valueString: 'Amoxicillin 500mg' },
{ type: 'dose-count', valueInteger: 21 },
{ type: 'start-date', valueDate: '2025-02-01' },
]
// Output: what the task produced
output: [
{ type: 'prescription-id', valueReference: 'MedicationRequest/rx_001' },
{ type: 'dispensed', valueBoolean: true },
]
```
## Task Restrictions
Constrain how and when a task should be fulfilled:
```ts theme={null}
restriction: {
repetitions: 3, // Can be repeated up to 3 times
period: { start: '2025-02-01', end: '2025-02-28' },
recipientIds: ['Patient/pt_abc123'],
}
```
## Parent Tasks
Break complex workflows into sub-tasks:
```ts theme={null}
// Parent task
const { data: parent } = await clinik.tasks.create({
status: 'requested',
intent: 'order',
code: 'pre-op-workup',
description: 'Complete pre-operative workup',
patientId: 'pt_abc123',
});
// Sub-task
const { data: sub } = await clinik.tasks.create({
status: 'requested',
intent: 'order',
code: 'lab-order',
description: 'Pre-op labs',
patientId: 'pt_abc123',
partOf: [parent.id!],
});
```
## Search Tasks
```ts theme={null}
// Tasks assigned to a specific owner
const { data } = await clinik.tasks.search({
ownerId: 'prac_lab_tech',
status: 'requested',
priority: 'urgent',
});
// All tasks for a patient
const { data: patientTasks } = await clinik.tasks.search({
patientId: 'pt_abc123',
sort: '-date',
});
```
# Vision Prescriptions
Source: https://docs.clinikapi.com/guides/vision-prescriptions
Create and manage optical prescriptions for eyeglasses and contact lenses.
# Vision Prescriptions
Vision prescriptions (FHIR `VisionPrescription`) represent optical prescriptions written by optometrists or ophthalmologists. They include detailed lens specifications for each eye — sphere, cylinder, axis, prism, and contact lens parameters.
## Create a Vision Prescription
```ts theme={null}
const { data: rx } = await clinik.visionPrescriptions.create({
status: 'active',
patientId: 'pt_abc123',
dateWritten: '2025-03-15',
prescriberId: 'prac_optometrist',
lensSpecification: [
{
product: 'lens',
eye: 'right',
sphere: -2.25,
cylinder: -0.75,
axis: 180,
add: 1.75,
prism: [{ amount: 0.5, base: 'down' }],
},
{
product: 'lens',
eye: 'left',
sphere: -2.00,
cylinder: -1.25,
axis: 175,
add: 1.75,
},
],
});
```
## Common Use Cases
### Eyeglasses Prescription
```ts theme={null}
const { data } = await clinik.visionPrescriptions.create({
status: 'active',
patientId: 'pt_abc123',
dateWritten: '2025-03-15',
prescriberId: 'prac_optometrist',
lensSpecification: [
{
product: 'lens',
eye: 'right',
sphere: -3.50,
cylinder: -1.00,
axis: 90,
add: 2.00,
},
{
product: 'lens',
eye: 'left',
sphere: -3.25,
cylinder: -0.75,
axis: 85,
add: 2.00,
},
],
});
```
### Contact Lens Prescription
```ts theme={null}
const { data } = await clinik.visionPrescriptions.create({
status: 'active',
patientId: 'pt_abc123',
dateWritten: '2025-03-15',
prescriberId: 'prac_optometrist',
lensSpecification: [
{
product: 'contact',
eye: 'right',
power: -2.50,
backCurve: 8.6,
diameter: 14.2,
brand: 'Acuvue Oasys',
color: 'clear',
note: 'Daily wear, replace every 2 weeks',
},
{
product: 'contact',
eye: 'left',
power: -2.25,
backCurve: 8.6,
diameter: 14.2,
brand: 'Acuvue Oasys',
color: 'clear',
},
],
});
```
### Prism Correction
```ts theme={null}
const { data } = await clinik.visionPrescriptions.create({
status: 'active',
patientId: 'pt_abc123',
dateWritten: '2025-03-15',
prescriberId: 'prac_optometrist',
lensSpecification: [
{
product: 'lens',
eye: 'right',
sphere: -1.50,
prism: [
{ amount: 2.0, base: 'in' },
{ amount: 0.5, base: 'up' },
],
},
{
product: 'lens',
eye: 'left',
sphere: -1.75,
prism: [
{ amount: 2.0, base: 'out' },
{ amount: 0.5, base: 'down' },
],
},
],
});
```
## Search Vision Prescriptions
```ts theme={null}
const { data } = await clinik.visionPrescriptions.search({
patientId: 'pt_abc123',
status: 'active',
prescriberId: 'prac_optometrist',
});
```
# Webhooks
Source: https://docs.clinikapi.com/guides/webhooks
Get real-time notifications when resources are created, updated, or deleted.
# Webhooks
Webhooks notify your application in real-time when resources change. Every webhook payload is HMAC-SHA256 signed for security.
This page is the reference — payload, headers, settings. For how to build
against it, see [Webhooks in Practice](/guides/webhooks-in-practice): the
handler shape, worked scenarios, and the four mistakes that only surface in
production.
## Setting Up Webhooks
1. Go to **Webhooks** in the [Developer Dashboard](https://dashboard.clinikapi.com)
2. Click **Create Webhook**
3. Enter your endpoint URL (must be HTTPS)
4. Select which events to subscribe to
5. Save — you'll receive a webhook secret for signature verification
### Endpoint requirements
The endpoint must be reachable on the public internet over `https://`. URLs
that resolve to a non-routable address are rejected — loopback, link-local
(including cloud metadata addresses), private and carrier-grade-NAT ranges,
and internal names such as `*.internal` or `*.local`. Credentials embedded in
the URL (`https://user:pass@…`) are rejected too; use the signing secret to
authenticate us instead.
This is enforced again at delivery time, not only when you save the webhook,
so an endpoint whose DNS later points somewhere internal stops receiving
deliveries rather than turning us into a proxy for it.
**Redirects are not followed.** A `3xx` response counts as a failed delivery
and is retried. Register the final URL.
## Event Format
Events follow the pattern `{resource}.{action}`:
```
patient.created
encounter.updated
prescription.deleted
```
## Payload Structure
```json theme={null}
{
"id": "evt_lx8f3a7x2_k9m2n4",
"event": "patient.created",
"timestamp": "2025-01-15T09:15:00.000Z",
"data": {
"resourceType": "patient",
"resourceId": "pt_abc123",
"action": "created",
"tenantId": "org_def456",
"environment": "live"
}
}
```
`data.environment` is `live` or `test`, depending on which key produced the
event. **Check it.** Webhooks are registered per organisation, not per
environment, so one endpoint receives sandbox and production events alike —
and `resourceId` only exists in the datastore its own environment writes to, so
fetching a test resource with a live key returns 404. Branch on it before you
let an event drive real work: sandbox testing should not send a patient a real
appointment reminder.
`data.tenantId` identifies the tenant partition that produced the event: the sub-organization ID when the triggering API key belongs to a sub-org, otherwise your organization ID. Use it to route events per customer behind a single endpoint.
## Environment Filtering
A webhook receives **both** environments by default, because registrations are
per organisation rather than per key. When adding an endpoint you can pin it:
| Setting | Receives |
| - | - |
| Both (default) | every event, live and test |
| Live keys only | only events produced by `clk_live_*` keys |
| Test keys only | only events produced by `clk_test_*` keys |
Pin your production receiver to **live**. Otherwise sandbox testing drives real
work — the same `patient.created` that fires a genuine appointment reminder —
and `resourceId` will point at a record that exists only in the sandbox
datastore, so fetching it with a live key returns 404.
Existing webhooks are unpinned and keep receiving both, so nothing changes
until you choose otherwise.
## Sub-Organization Filtering
Webhooks are registered at the organization level, and by default an endpoint receives events from **all** of your traffic — organization keys and every sub-organization. When adding an endpoint you can optionally pin it to a single sub-organization: a pinned endpoint only receives events produced by that sub-org's API keys. Either way, `data.tenantId` always carries the originating tenant.
## Headers
| Header | Description |
| - | - |
| `X-Clinik-Signature` | HMAC-SHA256 hex signature of the raw body |
| `X-Clinik-Signature-V2` | `t=,v1=` — signature over `.`. Prefer this |
| `X-Clinik-Timestamp` | Unix timestamp (seconds) when the webhook was sent |
| `X-Clinik-Event` | Event type (e.g. `patient.created`) |
| `X-Clinik-Delivery-Id` | Unique delivery ID for deduplication |
## Verifying Signatures
Always verify the signature before processing a webhook. Verify against the
**raw request body** — re-serializing parsed JSON changes the bytes and the
signature will not match.
Prefer `X-Clinik-Signature-V2`: it covers the timestamp as well as the body, so
you can reject a stale replay. `X-Clinik-Signature` covers the body alone and
remains supported for existing integrations, but on its own it cannot tell a
fresh delivery from a replayed one.
```ts theme={null}
import crypto from 'crypto';
const TOLERANCE_SECONDS = 300; // reject anything older than 5 minutes
function verifyWebhook(rawBody: string, header: string, secret: string): boolean {
// header looks like: t=1700000000,v1=
const parts = Object.fromEntries(
header.split(',').map((kv) => kv.split('=', 2) as [string, string]),
);
const timestamp = Number(parts.t);
const received = parts.v1 ?? '';
if (!Number.isFinite(timestamp) || !received) return false;
// Freshness — this is the part the timestamp buys you.
if (Math.abs(Math.floor(Date.now() / 1000) - timestamp) > TOLERANCE_SECONDS) return false;
const expected = crypto
.createHmac('sha256', secret)
.update(`${timestamp}.${rawBody}`)
.digest('hex');
// timingSafeEqual THROWS when the two buffers differ in length, and the
// signature is attacker-controlled — compare lengths first, or a malformed
// header crashes your handler instead of returning 401.
const a = Buffer.from(received, 'utf8');
const b = Buffer.from(expected, 'utf8');
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
// In your webhook handler — note express.raw(), not express.json()
app.post('/webhooks/clinikapi', express.raw({ type: 'application/json' }), (req, res) => {
const header = req.headers['x-clinik-signature-v2'] as string;
const rawBody = req.body.toString('utf8');
const isValid = header && verifyWebhook(rawBody, header, process.env.CLINIK_WEBHOOK_SECRET!);
if (!isValid) {
return res.status(401).send('Invalid signature');
}
const event = JSON.parse(rawBody);
switch (event.event) {
case 'patient.created':
// Handle new patient
break;
case 'appointment.updated':
// Handle appointment change
break;
}
res.status(200).send('OK');
});
```
## Event Subscription
You can subscribe to:
| Pattern | Description |
| - | - |
| `*` | All events |
| `patient.*` | All patient events (created, updated, deleted) |
| `patient.created` | Only patient creation |
### Available Events
All 62 resource types support `.created`, `.updated`, and `.deleted` events:
**Clinical:** `patient`, `encounter`, `observation`, `condition`, `allergy`, `assessment`, `care-plan`, `care-team`, `goal`, `risk-assessment`, `family-member-history`
**Medications:** `medication`, `prescription`, `medication-dispense`, `medication-statement`, `medication-knowledge`, `immunization`, `immunization-evaluation`, `immunization-recommendation`, `nutrition-order`
**Scheduling:** `appointment`, `appointment-response`, `schedule`, `slot`
**Documentation:** `note`, `document`, `consent`, `intake`, `media`
**Diagnostics:** `lab`, `specimen`, `imaging-study`
**Administrative:** `practitioner`, `practitioner-role`, `organization`, `location`, `healthcare-service`, `person`
**Workflow:** `task`, `service-request`, `device-request`, `activity-definition`, `plan-definition`
**Devices:** `device`, `device-use-statement`
**Billing and Insurance:** `account`, `charge-item`, `claim`, `claim-response`, `coverage`, `eligibility-request`, `eligibility-response`, `explanation-of-benefit`, `invoice`, `payment-notice`, `payment-reconciliation`, `enrollment-request`, `enrollment-response`, `vision-prescription`
**Quality and Audit:** `measure`, `measure-report`, `audit-event`
## Retry Policy
Failed deliveries are retried with exponential backoff:
| Attempt | Delay |
| - | - |
| 1 | 30 seconds |
| 2 | 2 minutes |
| 3 | 8 minutes |
| 4 | 32 minutes |
| 5 | 2 hours |
After 5 failed attempts, the delivery is marked as failed. You can view delivery logs in the Dashboard under **Analytics > Webhook Logs**.
Retries are **per endpoint**. If you have several webhooks subscribed to the
same event and one of them fails, only that one is retried — the endpoints that
already received the event are not sent it again.
A delivery refused because the destination is not routable is **not** retried:
the address will not become valid on its own. Fix the URL and the next event
delivers normally.
## Best Practices
* Always return `200` quickly — process events asynchronously
* Verify `X-Clinik-Signature-V2` on every request, against the raw body
* Reject deliveries whose timestamp is outside your tolerance window
* Deduplicate on `X-Clinik-Delivery-Id` — delivery is at-least-once, so the
same event can legitimately arrive twice
* Use specific event subscriptions instead of `*` when possible
# Webhooks in Practice
Source: https://docs.clinikapi.com/guides/webhooks-in-practice
Build a real integration on webhooks — the handler shape, the four things that bite, and worked scenarios.
# Webhooks in Practice
[The webhooks reference](/guides/webhooks) covers the payload, the headers and
the settings. This page is about actually building on them: what a correct
handler looks like, why each part of it exists, and the mistakes that only show
up in production.
## The mental model: a doorbell, not a delivery
A webhook tells you *that* something changed and gives you its id. It does not
carry the record:
```json theme={null}
{
"id": "evt_msaygdno_y4n1ox",
"event": "appointment.created",
"timestamp": "2026-08-02T09:15:00.000Z",
"data": {
"resourceType": "appointment",
"resourceId": "b79ea396-6161-4f8b-9004-5ba29d9f3744",
"action": "created",
"tenantId": "6ed948b8-7fe0-48e4-9521-0606cdab7cd4",
"environment": "live"
}
}
```
No patient name, no phone number, no appointment time. That is deliberate. A
webhook body travels to an endpoint we do not control and cannot audit, so it
carries an identifier rather than PHI: an intercepted delivery leaks a UUID,
not a patient. You fetch the record yourself, with your own key, over an
authenticated connection that *is* logged.
So every handler has the same shape:
**verify → deduplicate → check environment → fetch → act.**
## A complete handler
```ts theme={null}
import crypto from 'crypto';
const TOLERANCE_SECONDS = 300;
export async function POST(req: Request) {
// 1. VERIFY — against the RAW body. Re-serializing parsed JSON changes the
// bytes and the signature will never match.
const raw = await req.text();
if (!verify(raw, req.headers.get('x-clinik-signature-v2'), process.env.CLINIK_WEBHOOK_SECRET!)) {
return new Response('invalid signature', { status: 401 });
}
const { id, event, data } = JSON.parse(raw);
// 2. DEDUPLICATE — delivery is at-least-once, so this event can legitimately
// arrive more than once. Without this, a retry sends a second reminder.
if (await seen(id)) return new Response('ok');
await remember(id);
// 3. ENVIRONMENT — one endpoint receives sandbox and production events alike.
// Skip anything that is not real before it can trigger real work.
if (data.environment !== 'live') return new Response('ok');
// 4. FETCH — the payload has ids, not data.
if (event === 'appointment.created') {
const { data: appt } = await clinik.appointments.read(data.resourceId);
const { data: patient } = await clinik.patients.read(appt.patientId);
// 5. ACT — but queue it. Slow handlers get retried.
await queue.publish('reminder', { to: patient.phone, at: appt.start });
}
return new Response('ok');
}
function verify(rawBody: string, header: string | null, secret: string): boolean {
if (!header) return false;
const parts = Object.fromEntries(header.split(',').map((kv) => kv.split('=', 2)));
const timestamp = Number(parts.t);
const received = parts.v1 ?? '';
if (!Number.isFinite(timestamp) || !received) return false;
if (Math.abs(Math.floor(Date.now() / 1000) - timestamp) > TOLERANCE_SECONDS) return false;
const expected = crypto.createHmac('sha256', secret)
.update(`${timestamp}.${rawBody}`).digest('hex');
// timingSafeEqual THROWS on a length mismatch, and the signature is
// attacker-controlled — compare lengths first or a junk header crashes you.
const a = Buffer.from(received, 'utf8');
const b = Buffer.from(expected, 'utf8');
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
```
## The four things that bite
`JSON.parse` then `JSON.stringify` reorders keys and changes whitespace, so the
bytes you hash are not the bytes we signed. In Express this means
`express.raw({ type: 'application/json' })`, not `express.json()`. Symptom:
every signature fails, and it looks like the secret is wrong.
Delivery is **at-least-once**. A handler that times out *after* doing its work
still gets retried, because we never saw the 200. Deduplicate on
`X-Clinik-Delivery-Id` (also the payload's `id`) before acting. Skipping this is
how one booking becomes three text messages.
Webhooks are registered per organisation, not per key, so an endpoint receives
test and live events alike. Every integration test you run fires the same
`appointment.created` as a real booking. Check `data.environment`, and pin your
production endpoint to **live** when you register it so sandbox traffic never
reaches it at all.
There is a second reason to care: `resourceId` only exists in the datastore its
own environment writes to. Fetching a test resource with a live key returns
`404`.
Failed deliveries retry on a 30s → 2min → 8min → 32min → 2h backoff. A handler
that spends 20 seconds generating a PDF invites duplicates and eventually gets
marked failed. Return `200` as soon as the event is verified and durable, then
process asynchronously.
## Worked scenarios
### Appointment reminders
Subscribe to `appointment.created` and `appointment.updated`. On create,
schedule a reminder 24 hours out; on update, reschedule it; on
`appointment.deleted`, cancel it. Because the reminder is keyed to the
appointment id, the update path is idempotent by construction.
This is the case that most clearly beats polling — not for latency, but because
you would otherwise diff every clinic's appointment list on a timer, forever.
### Critical result escalation
Subscribe to `lab.created`, fetch the report, and page the on-call clinician
when a value is out of range.
Here latency genuinely matters. A critical potassium result sitting in a
one-minute polling gap is a patient-safety issue, not a performance one — and
the gap is unbounded if your poller is mid-restart.
```ts theme={null}
if (event === 'lab.created') {
const { data: report } = await clinik.labs.read(data.resourceId);
if (isCritical(report)) await page(onCallFor(report.patientId), report);
}
```
### One platform, many clinics
If you resell to multiple practices, give each one a **sub-organization**. You
then have two options, and the right one depends on your architecture:
* **One endpoint, route on `data.tenantId`.** It carries the sub-org id, not
your parent organization id, so it is a clean routing key.
* **One endpoint per clinic, pinned to that sub-org.** Their events never reach
another clinic's infrastructure — useful when each customer has their own
deployment, or when you want the isolation to be structural rather than a
line of code.
### Keeping a billing system in sync
Subscribe to `charge-item.created` and `invoice.updated` and push into your
accounting system. Nobody re-keys anything, and the FHIR record stays the
source of truth.
## Before you go live
* Register the **final** URL. Redirects are not followed — a `301` to a
trailing slash makes every delivery a failure.
* The endpoint must be publicly reachable over HTTPS. Loopback, private ranges
and internal hostnames are rejected at registration *and* at delivery.
* Subscribe to the specific events you handle rather than `*`. It is cheaper
for both of us, and it makes the delivery log readable when something breaks.
* Watch **Analytics → Webhook Logs** in the dashboard after your first
deployment. Every attempt is recorded with its status and response, and a
refused delivery tells you exactly why.
# Introduction
Source: https://docs.clinikapi.com/introduction
Healthcare infrastructure for developers. Build clinical apps without FHIR complexity.
# Welcome to ClinikAPI
ClinikAPI is a managed healthcare infrastructure platform that lets you build clinical applications through a simple REST API and SDK — without dealing with FHIR R4 complexity, HIPAA compliance infrastructure, or cloud provisioning.
## What ClinikAPI Does
You send simplified JSON. We handle the rest:
* **FHIR R4 transformation** — your payloads are automatically converted to strict FHIR R4 resources
* **Tenant isolation** — every resource is tagged and filtered by your organization
* **Secure storage** — data lives in an encrypted, HIPAA-compliant FHIR R4 data store
* **Compliance** — BAA-ready infrastructure with audit logging on every request
```ts theme={null}
import { Clinik } from '@clinikapi/sdk';
const clinik = new Clinik(process.env.CLINIKAPI_SECRET_KEY);
// Create a patient — ClinikAPI handles FHIR transformation + storage
const { data: patient } = await clinik.patients.create({
firstName: 'Jane',
lastName: 'Doe',
email: 'jane@example.com',
gender: 'female',
birthDate: '1990-03-15',
});
console.log(patient.id); // "pt_abc123"
```
## Base URL
All API endpoints are served from:
```
https://api.clinikapi.com/v1
```
* Resource endpoints: `https://api.clinikapi.com/v1/patients`, `/v1/encounters`, and so on for every resource below
* `GET /v1/metadata` — the FHIR CapabilityStatement (public, no key required)
* `GET https://api.clinikapi.com/health` — service liveness (outside `/v1`, no key required)
The `@clinikapi/sdk` client targets this base URL by default — no configuration needed.
## 62 FHIR R4 Resources
Full CRUD + search + pagination out of the box, organized by FHIR domain:
### Individuals
| Resource | FHIR Type | SDK Namespace |
| - | - | - |
| Patients | Patient | `clinik.patients` |
| Practitioners | Practitioner | `clinik.practitioners` |
| Practitioner Roles | PractitionerRole | `clinik.practitionerRoles` |
| Persons | Person | `clinik.persons` |
| Family History | FamilyMemberHistory | `clinik.familyHistory` |
### Entities
| Resource | FHIR Type | SDK Namespace |
| - | - | - |
| Organizations | Organization | `clinik.organizations` |
| Locations | Location | `clinik.locations` |
| Healthcare Services | HealthcareService | `clinik.healthcareServices` |
| Devices | Device | `clinik.devices` |
### Clinical — Summary
| Resource | FHIR Type | SDK Namespace |
| - | - | - |
| Conditions | Condition | `clinik.conditions` |
| Allergies | AllergyIntolerance | `clinik.allergies` |
| Assessments | ClinicalImpression | `clinik.assessments` |
| Family History | FamilyMemberHistory | `clinik.familyHistory` |
### Clinical — Diagnostics
| Resource | FHIR Type | SDK Namespace |
| - | - | - |
| Observations | Observation | `clinik.observations` |
| Labs | DiagnosticReport | `clinik.labs` |
| Specimens | Specimen | `clinik.specimens` |
| Imaging Studies | ImagingStudy | `clinik.imagingStudies` |
| Media | Media | `clinik.media` |
| Risk Assessments | RiskAssessment | `clinik.riskAssessments` |
### Clinical — Medications
| Resource | FHIR Type | SDK Namespace |
| - | - | - |
| Medications | Medication | `clinik.medications` |
| Prescriptions | MedicationRequest | `clinik.prescriptions` |
| Medication Dispenses | MedicationDispense | `clinik.medicationDispenses` |
| Medication Statements | MedicationStatement | `clinik.medicationStatements` |
| Medication Knowledge | MedicationKnowledge | `clinik.medicationKnowledge` |
| Immunizations | Immunization | `clinik.immunizations` |
| Immunization Evaluations | ImmunizationEvaluation | `clinik.immunizationEvaluations` |
| Immunization Recommendations | ImmunizationRecommendation | `clinik.immunizationRecommendations` |
| Nutrition Orders | NutritionOrder | `clinik.nutritionOrders` |
| Vision Prescriptions | VisionPrescription | `clinik.visionPrescriptions` |
### Clinical — Care Provision
| Resource | FHIR Type | SDK Namespace |
| - | - | - |
| Encounters | Encounter | `clinik.encounters` |
| Care Plans | CarePlan | `clinik.carePlans` |
| Care Teams | CareTeam | `clinik.careTeams` |
| Goals | Goal | `clinik.goals` |
| Service Requests | ServiceRequest | `clinik.serviceRequests` |
| Device Requests | DeviceRequest | `clinik.deviceRequests` |
| Device Use Statements | DeviceUseStatement | `clinik.deviceUseStatements` |
| Consents | Consent | `clinik.consents` |
### Clinical — Documents and Forms
| Resource | FHIR Type | SDK Namespace |
| - | - | - |
| Notes | DocumentReference | `clinik.notes` |
| Documents | Composition | `clinik.documents` |
| Intakes | QuestionnaireResponse | `clinik.intakes` |
### Scheduling
| Resource | FHIR Type | SDK Namespace |
| - | - | - |
| Appointments | Appointment | `clinik.appointments` |
| Appointment Responses | AppointmentResponse | `clinik.appointmentResponses` |
| Schedules | Schedule | `clinik.schedules` |
| Slots | Slot | `clinik.slots` |
### Workflow
| Resource | FHIR Type | SDK Namespace |
| - | - | - |
| Tasks | Task | `clinik.tasks` |
| Activity Definitions | ActivityDefinition | `clinik.activityDefinitions` |
| Plan Definitions | PlanDefinition | `clinik.planDefinitions` |
### Financial — Billing
| Resource | FHIR Type | SDK Namespace |
| - | - | - |
| Accounts | Account | `clinik.accounts` |
| Charge Items | ChargeItem | `clinik.chargeItems` |
| Invoices | Invoice | `clinik.invoices` |
### Financial — Claims and Reimbursement
| Resource | FHIR Type | SDK Namespace |
| - | - | - |
| Claims | Claim | `clinik.claims` |
| Claim Responses | ClaimResponse | `clinik.claimResponses` |
| Explanation of Benefits | ExplanationOfBenefit | `clinik.eobs` |
| Payment Notices | PaymentNotice | `clinik.paymentNotices` |
| Payment Reconciliations | PaymentReconciliation | `clinik.paymentReconciliations` |
### Financial — Insurance
| Resource | FHIR Type | SDK Namespace |
| - | - | - |
| Coverages | Coverage | `clinik.coverages` |
| Eligibility Requests | CoverageEligibilityRequest | `clinik.eligibilityRequests` |
| Eligibility Responses | CoverageEligibilityResponse | `clinik.eligibilityResponses` |
| Enrollment Requests | EnrollmentRequest | `clinik.enrollmentRequests` |
| Enrollment Responses | EnrollmentResponse | `clinik.enrollmentResponses` |
### Quality and Audit
| Resource | FHIR Type | SDK Namespace |
| - | - | - |
| Measures | Measure | `clinik.measures` |
| Measure Reports | MeasureReport | `clinik.measureReports` |
| Audit Events | AuditEvent | `clinik.auditEvents` |
## Architecture
ClinikAPI is a **data API** — you bring your own auth (Clerk, Auth0, Firebase, etc.).
```
Your App → Your Backend → ClinikAPI SDK → ClinikAPI REST API → FHIR R4 Data Store
```
* The SDK runs **server-side only** with a secret API key
* React widgets use a **proxy pattern** — they talk to your backend, not directly to ClinikAPI
* Test keys route to a shared test datastore; live keys route to production
## Next Steps
Get your first patient created in under 5 minutes.
Learn how API keys and tenant isolation work.
Full TypeScript SDK documentation.
Drop-in clinical UI widgets for your frontend.
# Business Associate Agreement
Source: https://docs.clinikapi.com/legal/baa
HIPAA Business Associate Agreement for ClinikAPI customers.
# Business Associate Agreement
ClinikAPI provides a HIPAA Business Associate Agreement (BAA) for all paid plans (Starter and above).
## What is a BAA?
A BAA is a legally binding contract required by HIPAA when a covered entity (your organization) shares Protected Health Information (PHI) with a business associate (ClinikAPI). It defines:
* How PHI may be used and disclosed
* Safeguards required to protect PHI
* Breach notification procedures
* Termination and data return obligations
## Requesting a BAA
BAAs are available on all paid plans:
| Plan | BAA Available |
| - | - |
| Sandbox (free) | No |
| Starter (\$49/mo) | Yes |
| Pro (\$499/mo) | Yes |
| Team (\$1,999/mo) | Yes |
| Enterprise (custom) | Yes (custom terms) |
To request a BAA:
1. Upgrade to a paid plan in the [Dashboard](https://dashboard.clinikapi.com)
2. Navigate to **Settings > Compliance**
3. Review and sign the BAA electronically
Enterprise customers receive a customized BAA with additional terms.
## Technical Safeguards
ClinikAPI implements the following safeguards as documented in the BAA:
* **Encryption at rest**: AES-256 with cloud-managed KMS keys
* **Encryption in transit**: TLS 1.2+ on all API endpoints
* **Access controls**: API key authentication with tenant isolation
* **Audit logging**: Every API request logged with FHIR resource context
* **Data isolation**: Tenant-tagged resources with enforced `_tag` filtering
* **Breach notification**: Within 60 days of discovery per HIPAA requirements
## Contact
For BAA questions or custom enterprise agreements, contact [compliance@clinikapi.com](mailto:compliance@clinikapi.com).
# Privacy Policy
Source: https://docs.clinikapi.com/legal/privacy
ClinikAPI privacy policy.
# Privacy Policy
*Last updated: April 2025*
## Overview
ClinikAPI ("we", "us", "our") operates the ClinikAPI healthcare infrastructure platform. This privacy policy explains how we collect, use, and protect information when you use our services.
## Information We Collect
### Account Information
* Name, email address, organization name
* Billing information (processed by Stripe — we do not store card numbers)
### Usage Data
* API request logs (endpoint, timestamp, response code, request ID)
* Dashboard usage analytics (via PostHog)
* Error logs for debugging
### Clinical Data (PHI)
* Clinical data is stored in our HIPAA-compliant cloud infrastructure on behalf of our customers
* We act as a Business Associate under HIPAA
* We do not access, use, or disclose PHI except as necessary to provide the service
* PHI is encrypted at rest (AES-256) and in transit (TLS 1.2+)
## How We Use Information
* To provide and maintain the ClinikAPI service
* To process billing and subscriptions
* To send service-related communications
* To monitor and improve service reliability
* To comply with legal obligations
## Data Retention
* Account data: retained while your account is active, deleted within 30 days of account closure
* API request logs: retained for 90 days
* Clinical data (PHI): retained until you delete it or close your account; deleted within 30 days of account closure per BAA terms
## Data Security
* All data encrypted at rest and in transit
* API key authentication with tenant isolation
* Audit logging on every request
* Regular security assessments
* SOC 2 Type II compliance (in progress)
## Your Rights
* Access your data via the API or Dashboard
* Export your data via bulk export
* Delete your data via the API or by contacting support
* Close your account at any time
## Contact
For privacy questions: [privacy@clinikapi.com](mailto:privacy@clinikapi.com)
# Terms of Service
Source: https://docs.clinikapi.com/legal/terms
ClinikAPI terms of service.
# Terms of Service
*Last updated: April 2025*
## 1. Acceptance
By accessing or using ClinikAPI ("Service"), you agree to these Terms of Service. If you are using the Service on behalf of an organization, you represent that you have authority to bind that organization.
## 2. Service Description
ClinikAPI provides a managed healthcare infrastructure platform including:
* REST API for clinical data storage and retrieval (FHIR R4 — 62 resource types)
* TypeScript SDK for server-side integration (`@clinikapi/sdk`)
* React component library for client-side UI (`@clinikapi/react`)
* Developer dashboard for API key management, analytics, billing, and webhooks
* FHIR R4 transformation engine with tenant isolation
## 3. Account Responsibilities
* You are responsible for maintaining the security of your API keys
* You must not share API keys or expose them in client-side code
* You are responsible for all activity under your account
* You must comply with all applicable laws including HIPAA when handling PHI
## 4. Acceptable Use
You agree not to:
* Use the Service for any unlawful purpose
* Attempt to access other tenants' data
* Reverse engineer or decompile the Service
* Exceed rate limits through automated means
* Store non-clinical data in FHIR datastores
* Resell the Service without written permission
## 5. Pricing and Billing
* Plans and pricing are listed at [clinikapi.com](https://clinikapi.com)
* Paid plans are billed monthly or annually via Stripe
* Overages are billed at \$0.003 per request beyond your plan limit
* Refunds are handled on a case-by-case basis
## 6. Data Ownership
* You retain all rights to your data
* We do not claim ownership of any clinical data stored through the Service
* We act as a Business Associate under HIPAA for PHI
## 7. Service Level
* We target 99.9% API uptime
* Scheduled maintenance windows are communicated in advance
* Status updates are available at [status.clinikapi.com](https://status.clinikapi.com)
## 8. Limitation of Liability
ClinikAPI's liability is limited to the amount you paid for the Service in the 12 months preceding the claim. We are not liable for indirect, incidental, or consequential damages.
## 9. Termination
* You may close your account at any time
* We may suspend accounts for Terms violations with notice
* Upon termination, your data is deleted within 30 days per our data retention policy
## 10. Changes
We may update these Terms with 30 days notice. Continued use after changes constitutes acceptance.
## Contact
For questions: [legal@clinikapi.com](mailto:legal@clinikapi.com)
# Quickstart
Source: https://docs.clinikapi.com/quickstart
Create your first patient in under 5 minutes.
# Quickstart
Get up and running with ClinikAPI in three steps. The API lives at `https://api.clinikapi.com/v1` — the SDK targets it by default, so there is nothing to configure.
## 1. Get Your API Key
Sign up at [dashboard.clinikapi.com](https://dashboard.clinikapi.com) and create an organization. You'll get two keys:
* `clk_test_*` — routes to the shared test datastore (safe to experiment with)
* `clk_live_*` — routes to production (available on paid plans)
## 2. Install the SDK
```bash theme={null}
npm install @clinikapi/sdk
```
The SDK is **server-side only**. Never import it in client-side code — your API key would be exposed.
For frontend UI, use `@clinikapi/react` with the proxy pattern.
## 3. Create a Patient
```ts theme={null}
import { Clinik } from '@clinikapi/sdk';
const clinik = new Clinik(process.env.CLINIKAPI_SECRET_KEY!);
async function main() {
// Create a patient
const { data: patient, meta } = await clinik.patients.create({
firstName: 'Jane',
lastName: 'Doe',
email: 'jane.doe@example.com',
gender: 'female',
birthDate: '1990-03-15',
address: {
line: ['123 Main St'],
city: 'Austin',
state: 'TX',
postalCode: '78701',
country: 'US',
},
});
console.log('Patient ID:', patient.id);
console.log('Request ID:', meta.requestId);
console.log('Rate limit remaining:', meta.rateLimitRemaining);
// Read the patient back with related resources
const { data: full } = await clinik.patients.read(patient.id!, {
include: ['Encounter', 'Observation'],
});
console.log('Encounters:', full.encounters.length);
console.log('Observations:', full.observations.length);
// Search patients
const { data: results } = await clinik.patients.search({
name: 'Doe',
count: 10,
});
console.log('Found:', results.data.length, 'patients');
}
main();
```
**Search is eventually consistent.** A freshly created resource can take a few
seconds (typically \~10s) to appear in `search` results, while `read(id)` works
immediately. Always use the `id` returned by `create` for read-after-write —
never poll search to confirm a write. See
[Data Consistency](/data-consistency) for the patterns.
## Response Format
Every SDK method returns `ApiResponse`:
```ts theme={null}
interface ApiResponse {
data: T; // The resource or result
meta: {
requestId: string; // For support tickets
timestamp: string; // ISO 8601
status: number; // HTTP status
rateLimitTotal?: number; // Requests allowed per window
rateLimitRemaining?: number; // Requests left
rateLimitReset?: number; // Seconds until reset
};
}
```
## Using Test vs Live Keys
| Key Prefix | Environment | Datastore |
| - | - | - |
| `clk_test_*` | Sandbox | Shared test datastore |
| `clk_live_*` | Production | Shared prod (Free/Pro) or dedicated (Enterprise) |
Test keys are available on all plans including Sandbox. Use them for development and testing — data is isolated from production.
## Next Steps
* [Authentication](/authentication) — how API keys and tenant isolation work
* [Patients Guide](/guides/patients) — deep dive into patient operations
* [Webhooks](/guides/webhooks) — get notified on resource changes
* [Error Handling](/sdk/error-handling) — handle errors gracefully
# Accounts
Source: https://docs.clinikapi.com/sdk/accounts
SDK reference for billing account operations.
# clinik.accounts
Accounts track billing and financial information — patient accounts, insurance coverage, guarantors, and service periods.
## create
```ts theme={null}
const { data, meta } = await clinik.accounts.create(request): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `status` | `string` | Yes | active, inactive, on-hold |
| `type` | `string` | No | Account type (patient, expense, depreciation) |
| `name` | `string` | No | Human-readable label |
| `patientId` | `string` | No | Patient the account is for |
| `servicePeriod` | `{ start?, end? }` | No | Transaction window |
| `coverage` | `Array<{ coverageId, priority? }>` | No | Insurance coverage |
| `ownerId` | `string` | No | Organization managing the account |
| `description` | `string` | No | Explanation of purpose |
| `guarantor` | `Array<{ partyId, onHold?, period? }>` | No | Responsible parties |
| `partOfId` | `string` | No | Parent account ID |
## Example
```ts theme={null}
const { data } = await clinik.accounts.create({
status: 'active',
type: 'patient',
name: 'Jane Doe - Primary Account',
patientId: 'pt_abc123',
servicePeriod: { start: '2025-01-01', end: '2025-12-31' },
coverage: [{ coverageId: 'cov_insurance_001', priority: 1 }],
ownerId: 'org_sunrise_medical',
});
```
## read / update / delete / search
Same pattern as other resources. Search supports `patientId`, `status`, `type`, `ownerId` filters.
# Activity Definitions
Source: https://docs.clinikapi.com/sdk/activity-definitions
SDK reference for activity definition operations.
# clinik.activityDefinitions
Activity definitions (FHIR `ActivityDefinition`) describe clinical activities that can be performed — templates for orders, referrals, procedures, and other clinical actions.
## create
```ts theme={null}
const { data, meta } = await clinik.activityDefinitions.create(request): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `status` | `string` | Yes | draft, active, retired |
| `name` | `string` | No | Computer-friendly name |
| `title` | `string` | No | Human-friendly title |
| `description` | `string` | No | Description of the activity |
| `purpose` | `string` | No | Why this definition exists |
| `usage` | `string` | No | Clinical usage notes |
| `kind` | `string` | No | Resource kind (Appointment, MedicationRequest, ServiceRequest, Task) |
| `code` | `string \| CodeableConcept` | No | Activity code |
| `intent` | `string` | No | proposal, plan, directive, order |
| `priority` | `string` | No | routine, urgent, asap, stat |
| `doNotPerform` | `boolean` | No | True if should NOT be performed |
| `timingDateTime` | `string` | No | When the activity should occur |
| `timingPeriod` | `{ start?, end? }` | No | Time window for the activity |
| `locationId` | `string` | No | Location ID |
| `participant` | `Array<{ type, role? }>` | No | Participants |
| `quantity` | `{ value, unit? }` | No | Quantity |
| `bodySite` | `string[]` | No | Body sites |
| `publisher` | `string` | No | Publisher name |
| `date` | `string` | No | Publication date |
| `version` | `string` | No | Business version |
| `url` | `string` | No | Canonical URL |
| `experimental` | `boolean` | No | For testing only |
| `topic` | `string[]` | No | Topic categories |
## Example
```ts theme={null}
const { data } = await clinik.activityDefinitions.create({
status: 'active',
name: 'blood-glucose-check',
title: 'Blood Glucose Check',
kind: 'ServiceRequest',
code: { system: 'http://loinc.org', code: '2339-0', display: 'Glucose [Mass/volume] in Blood' },
intent: 'order',
priority: 'routine',
description: 'Routine blood glucose monitoring for diabetic patients',
participant: [{ type: 'practitioner', role: 'Lab Technician' }],
});
```
## read / update / delete / search
Same pattern as other resources. Search supports `status`, `name`, `title`, `kind`, `code` filters.
For advanced ActivityDefinition features like dynamicValue, expression, library, or relatedArtifact, use the [FHIR Passthrough](/sdk/fhir-passthrough).
# Allergies
Source: https://docs.clinikapi.com/sdk/allergies
SDK reference for allergy and intolerance operations.
# clinik.allergies
Allergies represent a patient's known allergies and adverse reactions to substances, mapped to the FHIR `AllergyIntolerance` resource.
## create
```ts theme={null}
const { data, meta } = await clinik.allergies.create(request): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `patientId` | `string` | Yes | Patient ID |
| `clinicalStatus` | `string` | No | active, inactive, resolved |
| `verificationStatus` | `string` | No | unconfirmed, confirmed, refuted |
| `type` | `string` | No | allergy or intolerance |
| `category` | `string[]` | No | food, medication, environment, biologic |
| `criticality` | `string` | No | low, high, unable-to-assess |
| `code` | `string \| CodeableConcept` | No | What the allergy is to |
| `encounterId` | `string` | No | Encounter context |
| `onsetDateTime` | `string` | No | When the allergy started |
| `onsetString` | `string` | No | Onset description |
| `recordedDate` | `string` | No | When recorded |
| `recorderId` | `string` | No | Practitioner who recorded |
| `asserterId` | `string` | No | Who asserted the allergy |
| `lastOccurrence` | `string` | No | Last occurrence date |
| `note` | `string` | No | Additional notes |
| `reaction` | `Array` | No | Adverse reactions |
### Reaction Fields
| Field | Type | Required | Description |
| - | - | - | - |
| `substance` | `string` | No | Specific substance |
| `manifestation` | `string[]` | Yes | Clinical symptoms |
| `description` | `string` | No | Reaction description |
| `onset` | `string` | No | When the reaction occurred |
| `severity` | `string` | No | mild, moderate, severe |
| `exposureRoute` | `string` | No | How the allergen was encountered |
| `note` | `string` | No | Additional notes |
## Example
```ts theme={null}
const { data } = await clinik.allergies.create({
patientId: 'pt_abc123',
clinicalStatus: 'active',
verificationStatus: 'confirmed',
type: 'allergy',
category: ['medication'],
criticality: 'high',
code: 'Penicillin',
reaction: [{
manifestation: ['Hives', 'Angioedema'],
severity: 'severe',
}],
});
```
## read / update / delete / search
Same pattern as other resources. Search supports `patientId`, `clinicalStatus`, `type`, `category`, `criticality`, `code` filters.
# Appointment Responses
Source: https://docs.clinikapi.com/sdk/appointment-responses
SDK reference for appointment response operations.
# clinik.appointmentResponses
Appointment responses represent a participant's reply to an appointment — accepting, declining, tentatively accepting, or requesting a new time.
## create
```ts theme={null}
const { data, meta } = await clinik.appointmentResponses.create(request): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `appointmentId` | `string` | Yes | The appointment this response relates to |
| `participantStatus` | `string` | Yes | accepted, declined, tentative, needs-action |
| `actorId` | `string` | No | The participant (Patient/Practitioner reference) |
| `participantType` | `string` | No | Role of participant |
| `start` | `string` | No | Proposed new start time |
| `end` | `string` | No | Proposed new end time |
| `comment` | `string` | No | Additional comments |
## Example
```ts theme={null}
// Accept an appointment
const { data } = await clinik.appointmentResponses.create({
appointmentId: 'appt_abc123',
participantStatus: 'accepted',
actorId: 'Practitioner/prac_def456',
comment: 'Confirmed — see you then.',
});
// Propose a new time
const { data: counter } = await clinik.appointmentResponses.create({
appointmentId: 'appt_abc123',
participantStatus: 'tentative',
actorId: 'Patient/pt_xyz789',
start: '2025-02-03T10:00:00Z',
end: '2025-02-03T10:30:00Z',
comment: 'Can we move to Monday morning instead?',
});
```
## read / update / delete / search
Same pattern as other resources. Search supports `appointmentId`, `actorId`, `participantStatus` filters.
# Appointments
Source: https://docs.clinikapi.com/sdk/appointments
SDK reference for appointment operations.
# clinik.appointments
## create
```ts theme={null}
const { data, meta } = await clinik.appointments.create(request: AppointmentCreateRequest): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `status` | `string` | Yes | proposed, pending, booked, arrived, fulfilled, cancelled, noshow, checked-in, waitlist |
| `patientId` | `string` | Yes | Patient reference |
| `practitionerId` | `string` | No | Practitioner reference |
| `start` | `string` | No | Start time (ISO 8601) |
| `end` | `string` | No | End time (ISO 8601) |
| `minutesDuration` | `number` | No | Duration in minutes |
| `appointmentType` | `string` | No | routine, walkin, urgent, followup |
| `serviceType` | `string` | No | Service being booked |
| `serviceCategory` | `string` | No | Service category |
| `specialty` | `string` | No | Required specialty |
| `reasonCode` | `string` | No | Reason for appointment |
| `priority` | `number` | No | 0 (routine) to 9 (urgent) |
| `description` | `string` | No | Subject line |
| `comment` | `string` | No | Additional comments |
| `patientInstruction` | `string` | No | Instructions for patient |
| `cancelationReason` | `string` | No | Reason for cancellation |
| `basedOnId` | `string` | No | ServiceRequest this appointment assesses |
| `requestedPeriod` | `Array<{ start?, end? }>` | No | Preferred time windows |
| `created` | `string` | No | When initially created (defaults to now) |
## read / update / delete / search
Same pattern as other resources. See [Encounters](/sdk/encounters) for the shared interface.
# Assessments
Source: https://docs.clinikapi.com/sdk/assessments
SDK reference for clinical assessment (ClinicalImpression) operations.
# clinik.assessments
## create
```ts theme={null}
const { data, meta } = await clinik.assessments.create(request: AssessmentCreateRequest): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `status` | `string` | Yes | in-progress, completed |
| `statusReason` | `string` | No | Reason for current status |
| `patientId` | `string` | Yes | Patient reference |
| `encounterId` | `string` | No | Encounter reference |
| `practitionerId` | `string` | No | Assessor reference |
| `code` | `string` | No | Kind of assessment (initial-assessment, follow-up, discharge) |
| `description` | `string` | No | Description of the assessment |
| `summary` | `string` | Yes | Clinical summary |
| `findings` | `AssessmentFinding[]` | No | Clinical findings with optional basis |
| `note` | `string` | No | Additional notes |
| `effectiveDateTime` | `string` | No | When assessment was made |
| `date` | `string` | No | When documented (defaults to now) |
| `previousAssessmentId` | `string` | No | Reference to previous assessment |
| `problemIds` | `string[]` | No | Condition/AllergyIntolerance IDs being assessed |
| `investigations` | `AssessmentInvestigation[]` | No | Sets of investigations |
| `protocol` | `string[]` | No | Clinical protocol URIs followed |
| `prognosis` | `Array<{ code?, text }>` | No | Prognosis codes |
| `supportingInfoIds` | `string[]` | No | Supporting information references |
### Finding Structure
```ts theme={null}
findings: [
{ code: 'I10', text: 'Essential hypertension', basis: 'Blood pressure readings' },
{ text: 'No signs of end-organ damage' },
]
```
### Investigation Structure
```ts theme={null}
investigations: [
{ name: 'Initial labs', itemIds: ['obs_glucose', 'obs_creatinine'] },
{ name: 'Imaging', itemIds: ['dr_chest_xray'] },
]
```
## Example
```ts theme={null}
const { data: assessment } = await clinik.assessments.create({
status: 'completed',
code: 'initial-assessment',
patientId: 'pt_abc123',
encounterId: 'enc_xyz789',
practitionerId: 'prac_def456',
summary: 'Patient presents with well-controlled hypertension.',
findings: [
{ code: 'I10', text: 'Essential hypertension — well controlled', basis: 'BP 128/82' },
{ text: 'No signs of end-organ damage' },
],
investigations: [
{ name: 'Lab panel', itemIds: ['obs_cmp_001', 'obs_cbc_001'] },
],
problemIds: ['cond_hypertension_001'],
prognosis: [{ text: 'Good — well controlled with current regimen' }],
note: 'Follow up in 3 months.',
});
```
## search
| Parameter | Type | Description |
| - | - | - |
| `patientId` | `string` | Filter by patient |
| `practitionerId` | `string` | Filter by assessor |
| `status` | `string` | Filter by status |
| `encounterId` | `string` | Filter by encounter |
## read / update / delete
Same pattern as other resources.
# Audit Events
Source: https://docs.clinikapi.com/sdk/audit-events
SDK reference for audit event operations.
# clinik.auditEvents
Audit Events (FHIR `AuditEvent`) record security-relevant events in your system. Audit events are **immutable** — they can be created and read, but not updated.
## create
```ts theme={null}
const { data, meta } = await clinik.auditEvents.create(request): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `type` | `string` | Yes | Event type code (e.g. "rest", "login", "export") |
| `subtype` | `string[]` | No | Event subtypes |
| `action` | `string` | No | Action code: C, R, U, D, E |
| `recorded` | `string` | Yes | ISO 8601 timestamp |
| `outcome` | `string` | No | 0=success, 4=minor, 8=serious, 12=major failure |
| `outcomeDesc` | `string` | No | Outcome description |
| `purposeOfEvent` | `string[]` | No | Purpose of the event |
| `agent` | `Array` | Yes | Who was involved |
| `agent[].who` | `string` | Yes | Agent identifier |
| `agent[].name` | `string` | No | Agent display name |
| `agent[].requestor` | `boolean` | Yes | Whether this agent initiated the event |
| `agent[].role` | `string` | No | Agent role |
| `agent[].networkAddress` | `string` | No | Network address |
| `source` | `object` | Yes | Event source |
| `source.observer` | `string` | Yes | Source observer |
| `source.site` | `string` | No | Source site |
| `source.type` | `string` | No | Source type |
| `entity` | `Array` | No | Entities involved |
| `entity[].what` | `string` | No | Entity reference |
| `entity[].type` | `string` | No | Entity type |
| `entity[].role` | `string` | No | Entity role |
| `entity[].name` | `string` | No | Entity name |
| `entity[].description` | `string` | No | Entity description |
## Example
```ts theme={null}
const { data } = await clinik.auditEvents.create({
type: 'rest',
action: 'R',
recorded: new Date().toISOString(),
outcome: '0',
agent: [{
who: 'prac_dr456',
name: 'Dr. Smith',
requestor: true,
role: 'Practitioner',
networkAddress: '192.168.1.100',
}],
source: {
observer: 'ClinikAPI',
site: 'Cloud',
type: 'Application Server',
},
entity: [{
what: 'Patient/pt_abc123',
type: '1',
role: '1',
name: 'Patient Record',
}],
});
```
## read / delete / search
Audit events support `read`, `delete`, and `search` — but **not** `update`. Search supports `action`, `outcome`, `agent`, `dateFrom`, `dateTo` filters.
# Care Plans
Source: https://docs.clinikapi.com/sdk/care-plans
SDK reference for care plan operations.
# clinik.carePlans
Care plans (FHIR `CarePlan`) represent planned healthcare activities for a patient, including goals, activities, and care team coordination.
## create
```ts theme={null}
const { data, meta } = await clinik.carePlans.create(request): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `status` | `string` | Yes | draft, active, on-hold, revoked, completed |
| `intent` | `string` | Yes | proposal, plan, order, option |
| `patientId` | `string` | Yes | Patient ID |
| `encounterId` | `string` | No | Encounter context |
| `title` | `string` | No | Human-readable title |
| `description` | `string` | No | Description of the care plan |
| `category` | `string[]` | No | Category tags |
| `period` | `{ start?, end? }` | No | Time period covered |
| `created` | `string` | No | When created (defaults to now) |
| `authorId` | `string` | No | Author Practitioner ID |
| `contributorIds` | `string[]` | No | Contributor Practitioner IDs |
| `careTeamIds` | `string[]` | No | CareTeam IDs |
| `addressesIds` | `string[]` | No | Condition IDs this plan addresses |
| `goalIds` | `string[]` | No | Goal IDs |
| `note` | `string` | No | Additional notes |
| `activity` | `Array` | No | Planned activities |
| `basedOn` | `string[]` | No | CarePlan IDs this is based on |
| `replaces` | `string[]` | No | CarePlan IDs this replaces |
| `partOf` | `string[]` | No | CarePlan IDs this is part of |
### Activity Object
| Field | Type | Required | Description |
| - | - | - | - |
| `description` | `string` | Yes | Activity description |
| `status` | `string` | Yes | not-started, scheduled, in-progress, completed, cancelled |
| `code` | `string` | No | Activity code |
| `scheduledString` | `string` | No | Scheduled timing as text |
| `performerId` | `string` | No | Performer Practitioner ID |
| `referenceId` | `string` | No | Reference to another resource |
## Example
```ts theme={null}
const { data } = await clinik.carePlans.create({
status: 'active',
intent: 'plan',
patientId: 'pt_abc123',
title: 'Diabetes Management Plan',
description: 'Comprehensive care plan for Type 2 diabetes management',
category: ['diabetes-management'],
authorId: 'prac_dr456',
activity: [
{
description: 'HbA1c test every 3 months',
status: 'scheduled',
code: 'lab-test',
scheduledString: 'Every 3 months',
},
{
description: 'Dietary consultation',
status: 'not-started',
performerId: 'prac_dietitian789',
},
],
goalIds: ['goal_target_a1c'],
note: 'Patient motivated to improve glycemic control',
});
```
## read / update / delete / search
Same pattern as other resources. Search supports `patientId`, `status`, `category`, `authorId` filters.
# Care Teams
Source: https://docs.clinikapi.com/sdk/care-teams
SDK reference for care team operations.
# clinik.careTeams
Care Teams represent groups of practitioners collaborating on patient care, mapped to the FHIR `CareTeam` resource.
## create
```ts theme={null}
const { data, meta } = await clinik.careTeams.create(request): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `name` | `string` | Yes | Team name |
| `status` | `string` | No | proposed, active, suspended, inactive |
| `category` | `string[]` | No | Team categories |
| `patientId` | `string` | No | Patient this team is for |
| `encounterId` | `string` | No | Encounter context |
| `period` | `{ start?, end? }` | No | Active period |
| `participant` | `Array` | No | Team members |
| `reasonCode` | `string[]` | No | Reason codes |
| `managingOrganizationIds` | `string[]` | No | Managing organizations |
| `phone` | `string` | No | Team phone |
| `email` | `string` | No | Team email |
| `note` | `string` | No | Additional notes |
### Participant Fields
| Field | Type | Required | Description |
| - | - | - | - |
| `role` | `string` | No | Participant role |
| `memberId` | `string` | Yes | Member reference |
| `onBehalfOfId` | `string` | No | Organization represented |
| `period` | `{ start?, end? }` | No | Participation period |
## Example
```ts theme={null}
const { data } = await clinik.careTeams.create({
name: 'Diabetes Management Team',
status: 'active',
patientId: 'pt_abc123',
participant: [
{ role: 'Primary Care Physician', memberId: 'Practitioner/pract_dr456' },
{ role: 'Endocrinologist', memberId: 'Practitioner/pract_dr789' },
],
});
```
## read / update / delete / search
Same pattern as other resources. Search supports `patientId`, `status`, `category` filters.
# Charge Items
Source: https://docs.clinikapi.com/sdk/charge-items
SDK reference for charge item and billing operations.
# clinik.chargeItems
Charge Items represent billable services and charges, mapped to the FHIR `ChargeItem` resource.
## create
```ts theme={null}
const { data, meta } = await clinik.chargeItems.create(request): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `status` | `string` | Yes | planned, billable, not-billable, aborted, billed |
| `code` | `string \| CodeableConcept` | Yes | Billing code (CPT, HCPCS, etc.) |
| `patientId` | `string` | Yes | Patient ID |
| `encounterId` | `string` | No | Encounter context |
| `occurrenceDateTime` | `string` | No | When the charge occurred |
| `occurrencePeriod` | `{ start?, end? }` | No | Charge time range |
| `performer` | `Array` | No | Performers |
| `performingOrganizationId` | `string` | No | Performing organization |
| `requestingOrganizationId` | `string` | No | Requesting organization |
| `quantity` | `{ value, unit? }` | No | Quantity |
| `bodySite` | `string[]` | No | Body sites |
| `priceOverride` | `{ value, currency? }` | No | Price override |
| `overrideReason` | `string` | No | Reason for price override |
| `enteredDate` | `string` | No | When the charge was entered |
| `reason` | `string[]` | No | Reason codes |
| `accountIds` | `string[]` | No | Account IDs to charge |
| `note` | `string` | No | Additional notes |
### Performer Fields
| Field | Type | Required | Description |
| - | - | - | - |
| `function` | `string` | No | Performer function/role |
| `actorId` | `string` | Yes | Performer reference |
## Example
```ts theme={null}
const { data } = await clinik.chargeItems.create({
status: 'billable',
code: {
system: 'http://www.ama-assn.org/go/cpt',
code: '99213',
display: 'Office visit, established patient',
},
patientId: 'pt_abc123',
encounterId: 'enc_visit456',
priceOverride: { value: 150.00, currency: 'USD' },
});
```
## read / update / delete / search
Same pattern as other resources. Search supports `patientId`, `status`, `code`, `dateFrom`, `dateTo` filters.
# Claim Responses
Source: https://docs.clinikapi.com/sdk/claim-responses
SDK reference for claim response operations.
# clinik.claimResponses
Claim responses (FHIR `ClaimResponse`) represent adjudication results from insurers in response to submitted claims. ClinikAPI exposes the most commonly used fields — use the [FHIR passthrough](/sdk/fhir-passthrough) for advanced adjudication scenarios.
## create
```ts theme={null}
const { data, meta } = await clinik.claimResponses.create(request): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `status` | `string` | Yes | active, cancelled, draft |
| `type` | `string` | Yes | Claim type |
| `use` | `string` | Yes | claim, preauthorization, predetermination |
| `patientId` | `string` | Yes | Patient ID |
| `created` | `string` | No | When created (defaults to now) |
| `insurerId` | `string` | Yes | Insurer Organization ID |
| `requestId` | `string` | No | Claim ID this responds to |
| `outcome` | `string` | Yes | queued, complete, error, partial |
| `disposition` | `string` | No | Disposition message |
| `preAuthRef` | `string` | No | Pre-authorization reference |
| `payeeType` | `string` | No | Payee type |
| `item` | `Array` | No | Adjudicated line items |
| `total` | `Array` | No | Totals by category |
| `payment` | `object` | No | Payment details |
| `processNote` | `Array` | No | Processing notes |
| `note` | `string` | No | Additional notes |
### Item Object
| Field | Type | Required | Description |
| - | - | - | - |
| `itemSequence` | `number` | Yes | Corresponding claim item sequence |
| `adjudication` | `Array` | Yes | Adjudication details |
### Adjudication Object
| Field | Type | Required | Description |
| - | - | - | - |
| `category` | `string` | Yes | Category (e.g. submitted, eligible, benefit, copay) |
| `amount` | `{ value, currency? }` | No | Amount |
## Example
```ts theme={null}
const { data } = await clinik.claimResponses.create({
status: 'active',
type: 'professional',
use: 'claim',
patientId: 'pt_abc123',
insurerId: 'org_ins789',
requestId: 'claim_xyz456',
outcome: 'complete',
disposition: 'Claim processed successfully',
item: [
{
itemSequence: 1,
adjudication: [
{ category: 'submitted', amount: { value: 150.00, currency: 'USD' } },
{ category: 'eligible', amount: { value: 135.00, currency: 'USD' } },
{ category: 'benefit', amount: { value: 108.00, currency: 'USD' } },
{ category: 'copay', amount: { value: 27.00, currency: 'USD' } },
],
},
],
total: [
{ category: 'submitted', amount: { value: 195.00, currency: 'USD' } },
{ category: 'benefit', amount: { value: 156.00, currency: 'USD' } },
],
payment: {
type: 'complete',
amount: { value: 156.00, currency: 'USD' },
date: '2024-04-01',
},
});
```
## read / update / delete / search
Same pattern as other resources. Update supports `status` and `disposition`. Search supports `patientId`, `status`, `use`, `outcome`, `requestId` filters.
# Claims
Source: https://docs.clinikapi.com/sdk/claims
SDK reference for claim operations.
# clinik.claims
Claims (FHIR `Claim`) represent healthcare billing requests submitted to insurers for reimbursement. ClinikAPI exposes the most commonly used fields — use the [FHIR passthrough](/sdk/fhir-passthrough) for advanced claim scenarios.
## create
```ts theme={null}
const { data, meta } = await clinik.claims.create(request): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `status` | `string` | Yes | active, cancelled, draft |
| `type` | `string` | Yes | institutional, oral, pharmacy, professional, vision |
| `use` | `string` | Yes | claim, preauthorization, predetermination |
| `patientId` | `string` | Yes | Patient ID |
| `created` | `string` | No | When created (defaults to now) |
| `providerId` | `string` | Yes | Provider (Practitioner/Organization ID) |
| `insurerId` | `string` | No | Insurer Organization ID |
| `priority` | `string` | Yes | normal, immediate, deferred, stat |
| `billablePeriod` | `{ start?, end? }` | No | Billable period |
| `diagnosis` | `Array` | No | Diagnoses |
| `procedure` | `Array` | No | Procedures |
| `insurance` | `Array` | Yes | Insurance coverage (min 1) |
| `item` | `Array` | No | Line items |
| `total` | `{ value, currency? }` | No | Total claim amount |
| `note` | `string` | No | Additional notes |
### Insurance Object
| Field | Type | Required | Description |
| - | - | - | - |
| `sequence` | `number` | Yes | Sequence number |
| `focal` | `boolean` | Yes | Whether this is the focal coverage |
| `coverageId` | `string` | Yes | Coverage resource ID |
### Item Object
| Field | Type | Required | Description |
| - | - | - | - |
| `sequence` | `number` | Yes | Sequence number |
| `productOrService` | `string` | Yes | Product or service code |
| `quantity` | `{ value, unit? }` | No | Quantity |
| `unitPrice` | `{ value, currency? }` | No | Unit price |
| `net` | `{ value, currency? }` | No | Net amount |
## Example
```ts theme={null}
const { data } = await clinik.claims.create({
status: 'active',
type: 'professional',
use: 'claim',
patientId: 'pt_abc123',
providerId: 'Practitioner/prac_dr456',
priority: 'normal',
insurance: [{ sequence: 1, focal: true, coverageId: 'cov_ins789' }],
diagnosis: [
{ sequence: 1, code: 'E11.9' },
{ sequence: 2, code: 'I10' },
],
item: [
{
sequence: 1,
productOrService: '99213',
unitPrice: { value: 150.00, currency: 'USD' },
net: { value: 150.00, currency: 'USD' },
},
{
sequence: 2,
productOrService: '85025',
unitPrice: { value: 45.00, currency: 'USD' },
net: { value: 45.00, currency: 'USD' },
},
],
total: { value: 195.00, currency: 'USD' },
});
```
## read / update / delete / search
Same pattern as other resources. Update supports `status` only. Search supports `patientId`, `status`, `use`, `providerId`, `dateFrom`, `dateTo` filters.
# Client
Source: https://docs.clinikapi.com/sdk/client
The Clinik client class and its configuration.
# Clinik Client
The `Clinik` class is the entry point for all SDK operations. It manages authentication, retries, rate limit metadata, and request serialization.
## Constructor
```ts theme={null}
import { Clinik } from '@clinikapi/sdk';
const clinik = new Clinik(apiKey: string, options?: ClinikOptions);
```
### Parameters
| Parameter | Type | Required | Description |
| - | - | - | - |
| `apiKey` | `string` | Yes | Your secret API key (`clk_live_*` or `clk_test_*`) |
| `options` | `ClinikOptions` | No | Configuration options |
### ClinikOptions
| Field | Type | Default | Description |
| - | - | - | - |
| `baseUrl` | `string` | `https://api.clinikapi.com` | API base URL |
| `timeout` | `number` | `30000` | Request timeout (ms) |
| `retries` | `number` | `2` | Max retries on 5xx/429 |
## Resource Namespaces
The client exposes 62 resource namespaces, organized by FHIR domain:
```ts theme={null}
// ── Individuals ──────────────────────────────────────────
clinik.patients // Patient
clinik.practitioners // Practitioner
clinik.practitionerRoles // PractitionerRole
clinik.persons // Person
clinik.familyHistory // FamilyMemberHistory
// ── Entities ─────────────────────────────────────────────
clinik.organizations // Organization
clinik.locations // Location
clinik.healthcareServices // HealthcareService
clinik.devices // Device
// ── Clinical — Summary ───────────────────────────────────
clinik.conditions // Condition
clinik.allergies // AllergyIntolerance
clinik.assessments // ClinicalImpression
// ── Clinical — Diagnostics ───────────────────────────────
clinik.observations // Observation
clinik.labs // DiagnosticReport
clinik.specimens // Specimen
clinik.imagingStudies // ImagingStudy
clinik.media // Media
clinik.riskAssessments // RiskAssessment
// ── Clinical — Medications ───────────────────────────────
clinik.medications // Medication
clinik.prescriptions // MedicationRequest
clinik.medicationDispenses // MedicationDispense
clinik.medicationStatements // MedicationStatement
clinik.medicationKnowledge // MedicationKnowledge
clinik.immunizations // Immunization
clinik.immunizationEvaluations // ImmunizationEvaluation
clinik.immunizationRecommendations // ImmunizationRecommendation
clinik.nutritionOrders // NutritionOrder
clinik.visionPrescriptions // VisionPrescription
// ── Clinical — Care Provision ────────────────────────────
clinik.encounters // Encounter
clinik.carePlans // CarePlan
clinik.careTeams // CareTeam
clinik.goals // Goal
clinik.serviceRequests // ServiceRequest
clinik.deviceRequests // DeviceRequest
clinik.deviceUseStatements // DeviceUseStatement
clinik.consents // Consent
// ── Clinical — Documents and Forms ───────────────────────
clinik.notes // DocumentReference
clinik.documents // Composition
clinik.intakes // QuestionnaireResponse
// ── Scheduling ───────────────────────────────────────────
clinik.appointments // Appointment
clinik.appointmentResponses // AppointmentResponse
clinik.schedules // Schedule
clinik.slots // Slot
// ── Workflow ─────────────────────────────────────────────
clinik.tasks // Task
clinik.activityDefinitions // ActivityDefinition
clinik.planDefinitions // PlanDefinition
// ── Financial — Billing ──────────────────────────────────
clinik.accounts // Account
clinik.chargeItems // ChargeItem
clinik.invoices // Invoice
// ── Financial — Claims and Reimbursement ─────────────────
clinik.claims // Claim
clinik.claimResponses // ClaimResponse
clinik.eobs // ExplanationOfBenefit
clinik.paymentNotices // PaymentNotice
clinik.paymentReconciliations // PaymentReconciliation
// ── Financial — Insurance ────────────────────────────────
clinik.coverages // Coverage
clinik.eligibilityRequests // CoverageEligibilityRequest
clinik.eligibilityResponses // CoverageEligibilityResponse
clinik.enrollmentRequests // EnrollmentRequest
clinik.enrollmentResponses // EnrollmentResponse
// ── Quality and Audit ────────────────────────────────────
clinik.measures // Measure
clinik.measureReports // MeasureReport
clinik.auditEvents // AuditEvent
```
Each namespace provides:
| Method | Description |
| - | - |
| `create(data)` | Create a new resource |
| `read(id, options?)` | Read a resource by ID |
| `update(id, data)` | Update a resource (JSON Patch) |
| `delete(id)` | Delete a resource |
| `search(params?)` | Search with pagination |
## FHIR Escape Hatch
For raw FHIR R4 requests:
```ts theme={null}
clinik.fhir.request(method: string, path: string, body?: unknown)
```
See [FHIR Passthrough](/sdk/fhir-passthrough) for details.
## Response Type
Every method returns `ApiResponse`:
```ts theme={null}
interface ApiResponse {
data: T;
meta: ResponseMeta;
}
interface ResponseMeta {
requestId: string;
timestamp: string;
status: number;
rateLimitTotal?: number;
rateLimitRemaining?: number;
rateLimitReset?: number;
}
```
## Security Features
The SDK includes built-in security protections:
* **Browser detection** — warns if used in a browser environment
* **HTTPS enforcement** — warns if `baseUrl` is not HTTPS
* **Path traversal protection** — resource IDs are validated against `[a-zA-Z0-9\-_.]`
* **FHIR include injection prevention** — `_include` values are validated
* **Body size limits** — requests over 1MB are rejected before sending
* **PHI sanitization** — error messages never contain patient data
* **Jittered retries** — prevents thundering herd on failures
# Conditions
Source: https://docs.clinikapi.com/sdk/conditions
SDK reference for condition and diagnosis operations.
# clinik.conditions
Conditions represent clinical diagnoses, problems, and health concerns, mapped to the FHIR `Condition` resource.
## create
```ts theme={null}
const { data, meta } = await clinik.conditions.create(request): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `patientId` | `string` | Yes | Patient ID |
| `clinicalStatus` | `string` | No | active, recurrence, relapse, inactive, remission, resolved |
| `verificationStatus` | `string` | No | unconfirmed, provisional, differential, confirmed, refuted |
| `category` | `string[]` | No | problem-list-item, encounter-diagnosis |
| `severity` | `string` | No | mild, moderate, severe |
| `code` | `string \| CodeableConcept` | No | ICD-10, SNOMED, or free text |
| `bodySite` | `string[]` | No | Body sites affected |
| `encounterId` | `string` | No | Encounter context |
| `onsetDateTime` | `string` | No | When the condition started |
| `onsetString` | `string` | No | Onset description |
| `abatementDateTime` | `string` | No | When the condition resolved |
| `abatementString` | `string` | No | Abatement description |
| `recordedDate` | `string` | No | When recorded |
| `recorderId` | `string` | No | Practitioner who recorded |
| `asserterId` | `string` | No | Who asserted the condition |
| `stage` | `Array` | No | Staging information |
| `evidence` | `Array` | No | Supporting evidence |
| `note` | `string` | No | Additional notes |
### Stage Fields
| Field | Type | Required | Description |
| - | - | - | - |
| `summary` | `string` | No | Stage summary (e.g. "Stage II") |
| `type` | `string` | No | Stage type (clinical, pathological) |
### Evidence Fields
| Field | Type | Required | Description |
| - | - | - | - |
| `code` | `string[]` | No | Evidence codes |
| `detailIds` | `string[]` | No | Reference IDs to supporting evidence |
## Example
```ts theme={null}
const { data } = await clinik.conditions.create({
patientId: 'pt_abc123',
clinicalStatus: 'active',
verificationStatus: 'confirmed',
category: ['encounter-diagnosis'],
code: {
system: 'http://hl7.org/fhir/sid/icd-10-cm',
code: 'E11.9',
display: 'Type 2 diabetes mellitus',
},
onsetDateTime: '2023-08-15',
});
```
## read / update / delete / search
Same pattern as other resources. Search supports `patientId`, `clinicalStatus`, `verificationStatus`, `category`, `severity`, `code` filters.
# Consents
Source: https://docs.clinikapi.com/sdk/consents
SDK reference for consent operations.
# clinik.consents
Consents represent patient agreements to privacy policies, treatment plans, research participation, and other healthcare directives.
## sign
```ts theme={null}
const { data, meta } = await clinik.consents.sign(request: ConsentSignRequest): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `patientId` | `string` | Yes | Patient reference |
| `status` | `string` | No | draft, proposed, active, rejected, inactive |
| `scope` | `string` | Yes | patient-privacy, research, treatment, adr |
| `category` | `string \| string[]` | Yes | Consent category (e.g. "hipaa-notice") |
| `dateTime` | `string` | No | When consent was given |
| `performerId` | `string` | No | Who is agreeing (practitioner, patient) |
| `organizationId` | `string` | No | Custodian organization |
| `policyUri` | `string` | No | Policy URI (shorthand for single policy) |
| `policies` | `Array<{ authority?, uri? }>` | No | Multiple policies with authority |
| `policyRule` | `string` | No | Regulation that this consents to |
| `sourceAttachment` | `object` | No | Source document (attachment) |
| `sourceReferenceId` | `string` | No | Source document reference ID |
| `verification` | `Array<{ verified, verifiedWith?, verificationDate? }>` | No | Verification details (multiple) |
| `provision` | `ConsentProvisionInput` | No | Provision rules with nested exceptions |
### Provision Structure
```ts theme={null}
provision: {
type: 'permit' | 'deny',
period: { start?, end? },
actor: [{ role: string, reference: string }],
action: [{ system?, code, display? }],
securityLabel: [{ system?, code, display? }],
purpose: [{ system?, code, display? }],
class: [{ system?, code, display? }],
code: [{ system?, code, display? }],
dataPeriod: { start?, end? },
data: [{ meaning: 'instance' | 'related' | 'dependents' | 'authoredby', reference: string }],
provision: [/* nested exception rules */],
}
```
## read / update / delete / search
Same pattern as other resources. Search supports `patientId`, `status`, `dateFrom`, `dateTo` filters.
### Consent Scopes
| Scope | Description |
| - | - |
| `patient-privacy` | Privacy and data sharing (HIPAA notices) |
| `research` | Research participation |
| `treatment` | Treatment consent |
| `adr` | Advance directive |
# Coverages
Source: https://docs.clinikapi.com/sdk/coverages
SDK reference for coverage operations.
# clinik.coverages
Coverages (FHIR `Coverage`) represent a patient's insurance plan details. ClinikAPI exposes the most commonly used fields — use the [FHIR passthrough](/sdk/fhir-passthrough) for advanced coverage scenarios.
## create
```ts theme={null}
const { data, meta } = await clinik.coverages.create(request): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `status` | `string` | Yes | active, cancelled, draft |
| `patientId` | `string` | Yes | Patient (beneficiary) ID |
| `type` | `string` | No | medical, dental, vision, pharmacy |
| `subscriberId` | `string` | No | Subscriber ID on insurance card |
| `subscriberRef` | `string` | No | Subscriber reference (Patient/RelatedPerson) |
| `policyHolderRef` | `string` | No | Policy holder reference |
| `relationship` | `string` | No | self, spouse, child, other |
| `period` | `{ start?, end? }` | No | Coverage period |
| `payorIds` | `string[]` | Yes | Payor Organization IDs |
| `class` | `Array` | No | Coverage classes (group, plan, etc.) |
| `order` | `number` | No | Relative order of coverage |
| `network` | `string` | No | Insurance plan network |
| `dependent` | `string` | No | Dependent number |
| `subrogation` | `boolean` | No | Subrogation flag |
### Class Object
| Field | Type | Required | Description |
| - | - | - | - |
| `type` | `string` | Yes | Class type (group, plan, subplan, etc.) |
| `value` | `string` | Yes | Class value |
| `name` | `string` | No | Human-readable name |
## Example
```ts theme={null}
const { data } = await clinik.coverages.create({
status: 'active',
patientId: 'pt_abc123',
type: 'medical',
subscriberId: 'SUB-98765',
subscriberRef: 'Patient/pt_abc123',
relationship: 'self',
payorIds: ['org_ins_bluecross'],
period: { start: '2024-01-01', end: '2024-12-31' },
class: [
{ type: 'group', value: 'GRP-100', name: 'Employer Group Plan' },
{ type: 'plan', value: 'PLN-GOLD', name: 'Gold PPO' },
],
network: 'PPO Network',
});
```
## read / update / delete / search
Same pattern as other resources. Update supports `status`, `period`, `network`. Search supports `patientId`, `status`, `type`, `payorId` filters.
# Device Requests
Source: https://docs.clinikapi.com/sdk/device-requests
SDK reference for device request operations.
# clinik.deviceRequests
Device requests represent orders or proposals for a device to be used on a patient.
## create
```ts theme={null}
const { data, meta } = await clinik.deviceRequests.create(request): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `intent` | `string` | Yes | proposal, plan, directive, order, etc. |
| `code` | `string \| object` | Yes | Device being requested |
| `patientId` | `string` | Yes | Patient ID |
| `status` | `string` | No | draft, active, on-hold, revoked, completed |
| `encounterId` | `string` | No | Encounter during which request was made |
| `priority` | `string` | No | routine, urgent, asap, stat |
| `occurrenceDateTime` | `string` | No | When device should be used |
| `occurrencePeriod` | `object` | No | Period when device should be used |
| `authoredOn` | `string` | No | When request was authored (defaults to now) |
| `requesterId` | `string` | No | Practitioner who made the request |
| `performerId` | `string` | No | Who should fulfill the request |
| `performerType` | `string` | No | Type of performer |
| `reasonCode` | `string[]` | No | Reason codes |
| `note` | `string` | No | Additional notes |
| `basedOn` | `string[]` | No | Based-on resource IDs |
## Example
```ts theme={null}
const { data } = await clinik.deviceRequests.create({
intent: 'order',
code: 'Continuous Glucose Monitor',
patientId: 'pt_abc123',
status: 'active',
priority: 'routine',
requesterId: 'prac_dr456',
reasonCode: ['Type 2 Diabetes monitoring'],
note: 'Patient to use CGM for 14-day glucose monitoring cycle',
});
```
## read / update / delete / search
Same pattern as other resources. Update supports `status`, `priority`, `note`. Search supports `patientId`, `status`, `intent`, `code` filters.
# Device Use Statements
Source: https://docs.clinikapi.com/sdk/device-use-statements
SDK reference for device use statement operations.
# clinik.deviceUseStatements
Device use statements record when and how a device was used on a patient.
## create
```ts theme={null}
const { data, meta } = await clinik.deviceUseStatements.create(request): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `status` | `string` | Yes | active, completed, on-hold, intended, stopped, not-done |
| `patientId` | `string` | Yes | Patient ID |
| `deviceId` | `string` | Yes | Device reference |
| `timingDateTime` | `string` | No | When the device was used (point in time) |
| `timingPeriod` | `object` | No | When the device was used (period) |
| `recordedOn` | `string` | No | When the statement was recorded |
| `sourceId` | `string` | No | Who made the statement |
| `reasonCode` | `string[]` | No | Reason codes for device use |
| `bodySite` | `string` | No | Body site where device was used |
| `note` | `string` | No | Additional notes |
| `basedOn` | `string[]` | No | ServiceRequest IDs |
## Example
```ts theme={null}
const { data } = await clinik.deviceUseStatements.create({
status: 'active',
patientId: 'pt_abc123',
deviceId: 'dev_pacemaker789',
timingPeriod: { start: '2024-01-15' },
bodySite: 'Left chest wall',
reasonCode: ['Bradycardia management'],
note: 'Dual-chamber pacemaker implanted, functioning normally',
});
```
## read / update / delete / search
Same pattern as other resources. Update supports `status`, `note`. Search supports `patientId`, `status`, `deviceId` filters.
# Devices
Source: https://docs.clinikapi.com/sdk/devices
SDK reference for device operations.
# clinik.devices
Devices represent medical devices, equipment, and implantable hardware tracked in the system.
## create
```ts theme={null}
const { data, meta } = await clinik.devices.create(request): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `deviceName` | `string` | Yes | User-friendly device name |
| `status` | `string` | No | active, inactive |
| `manufacturer` | `string` | No | Manufacturer name |
| `modelNumber` | `string` | No | Model number |
| `serialNumber` | `string` | No | Serial number |
| `lotNumber` | `string` | No | Lot number |
| `manufactureDate` | `string` | No | Date of manufacture |
| `expirationDate` | `string` | No | Expiration date |
| `type` | `string` | No | Device type/kind |
| `patientId` | `string` | No | Patient this device is affixed to |
| `ownerId` | `string` | No | Organization responsible |
| `locationId` | `string` | No | Where the device is found |
| `url` | `string` | No | Network address |
| `note` | `string` | No | Additional notes |
| `parentId` | `string` | No | Parent device ID |
| `udiCarrier` | `Array` | No | UDI carrier info (deviceIdentifier, carrierHRF) |
| `safety` | `string[]` | No | Safety codes |
## Example
```ts theme={null}
const { data } = await clinik.devices.create({
deviceName: 'Medtronic Pacemaker Model X200',
status: 'active',
manufacturer: 'Medtronic',
modelNumber: 'X200',
serialNumber: 'SN-2024-78432',
type: 'cardiac-pacemaker',
patientId: 'pt_abc123',
udiCarrier: [{ deviceIdentifier: '08717648200274', carrierHRF: '(01)08717648200274' }],
});
```
## read / update / delete / search
Same pattern as other resources. Update supports `status`, `note`, `locationId`, `patientId`. Search supports `patientId`, `status`, `type`, `manufacturer`, `modelNumber` filters.
# Documents
Source: https://docs.clinikapi.com/sdk/documents
SDK reference for structured document (Composition) operations.
# clinik.documents
Compositions are structured clinical documents with sections — discharge summaries, referral letters, care plans, etc.
## create
```ts theme={null}
const { data, meta } = await clinik.documents.create(request: DocumentCreateRequest): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `status` | `string` | Yes | preliminary, final, amended |
| `type` | `string` | Yes | Document type (e.g. "discharge-summary") |
| `category` | `string[]` | No | Document categories for classification |
| `patientId` | `string` | Yes | Patient reference |
| `encounterId` | `string` | No | Encounter reference |
| `practitionerId` | `string` | Yes | Author reference |
| `title` | `string` | Yes | Document title |
| `date` | `string` | No | Document date |
| `sections` | `DocumentSection[]` | Yes | Document sections (recursive) |
| `confidentiality` | `'N' \| 'R' \| 'V'` | No | Normal, Restricted, Very Restricted |
| `attester` | `DocumentAttester[]` | No | Who attested to accuracy |
| `custodianId` | `string` | No | Organization maintaining the document |
| `relatesTo` | `DocumentRelatesTo[]` | No | Relationships to other compositions |
| `event` | `DocumentEvent[]` | No | Clinical services being documented |
### Section Structure (recursive)
```ts theme={null}
{
title: string;
code?: string;
text: string;
resourceIds?: string[];
authorId?: string; // Per-section author
mode?: 'working' | 'snapshot' | 'changes';
sections?: DocumentSection[]; // Nested sub-sections
}
```
### Attester Structure
```ts theme={null}
{
mode: 'personal' | 'professional' | 'legal' | 'official';
time?: string;
partyId?: string; // Practitioner ID
}
```
## search / read / update / delete
Same pattern as other resources.
# Eligibility Requests
Source: https://docs.clinikapi.com/sdk/eligibility-requests
SDK reference for eligibility request operations.
# clinik.eligibilityRequests
Eligibility Requests (FHIR `CoverageEligibilityRequest`) are used to check insurance eligibility and benefits. ClinikAPI exposes the most commonly used fields — use the [FHIR passthrough](/sdk/fhir-passthrough) for advanced eligibility scenarios.
## create
```ts theme={null}
const { data, meta } = await clinik.eligibilityRequests.create(request): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `status` | `string` | Yes | active, cancelled, draft |
| `purpose` | `string[]` | Yes | auth-requirements, benefits, discovery, validation |
| `patientId` | `string` | Yes | Patient ID |
| `created` | `string` | No | When created (defaults to now) |
| `insurerId` | `string` | Yes | Insurer Organization ID |
| `providerId` | `string` | No | Provider (Practitioner/Organization ID) |
| `servicedDate` | `string` | No | Service date (point in time) |
| `servicedPeriod` | `{ start?, end? }` | No | Service period |
| `insurance` | `Array` | No | Insurance coverages to check |
| `item` | `Array` | No | Items to check eligibility for |
### Insurance Object
| Field | Type | Required | Description |
| - | - | - | - |
| `focal` | `boolean` | No | Whether this is the focal coverage |
| `coverageId` | `string` | Yes | Coverage resource ID |
### Item Object
| Field | Type | Required | Description |
| - | - | - | - |
| `category` | `string` | No | Benefit category |
| `productOrService` | `string` | No | Product or service code |
## Example
```ts theme={null}
const { data } = await clinik.eligibilityRequests.create({
status: 'active',
purpose: ['benefits'],
patientId: 'pt_abc123',
insurerId: 'org_ins_bluecross',
providerId: 'Practitioner/prac_dr456',
servicedDate: '2024-06-15',
insurance: [
{ focal: true, coverageId: 'cov_primary789' },
],
});
```
## read / update / delete / search
Same pattern as other resources. Update supports `status` only. Search supports `patientId`, `status`, `dateFrom`, `dateTo` filters.
# Eligibility Responses
Source: https://docs.clinikapi.com/sdk/eligibility-responses
SDK reference for eligibility response operations.
# clinik.eligibilityResponses
Eligibility Responses (FHIR `CoverageEligibilityResponse`) contain the results of an eligibility check. ClinikAPI exposes the most commonly used fields — use the [FHIR passthrough](/sdk/fhir-passthrough) for advanced eligibility scenarios.
## create
```ts theme={null}
const { data, meta } = await clinik.eligibilityResponses.create(request): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `status` | `string` | Yes | active, cancelled, draft |
| `purpose` | `string[]` | Yes | Purpose codes |
| `patientId` | `string` | Yes | Patient ID |
| `created` | `string` | No | When created (defaults to now) |
| `requestId` | `string` | Yes | CoverageEligibilityRequest this responds to |
| `outcome` | `string` | Yes | queued, complete, error, partial |
| `insurerId` | `string` | Yes | Insurer Organization ID |
| `disposition` | `string` | No | Disposition message |
| `insurance` | `Array` | No | Insurance details |
| `preAuthRef` | `string` | No | Pre-authorization reference |
| `error` | `Array` | No | Processing errors |
### Insurance Object
| Field | Type | Required | Description |
| - | - | - | - |
| `coverageId` | `string` | Yes | Coverage resource ID |
| `inforce` | `boolean` | No | Whether coverage is in force |
| `benefitPeriod` | `{ start?, end? }` | No | Benefit period |
### Error Object
| Field | Type | Required | Description |
| - | - | - | - |
| `code` | `string` | Yes | Error code |
## Example
```ts theme={null}
const { data } = await clinik.eligibilityResponses.create({
status: 'active',
purpose: ['benefits'],
patientId: 'pt_abc123',
insurerId: 'org_ins_bluecross',
requestId: 'eligreq_xyz456',
outcome: 'complete',
disposition: 'Coverage is active with standard benefits',
insurance: [
{
coverageId: 'cov_primary789',
inforce: true,
benefitPeriod: { start: '2024-01-01', end: '2024-12-31' },
},
],
});
```
## read / update / delete / search
Same pattern as other resources. Update supports `status`, `disposition`. Search supports `patientId`, `status`, `outcome`, `requestId` filters.
# Encounters
Source: https://docs.clinikapi.com/sdk/encounters
SDK reference for encounter operations.
# clinik.encounters
## create
```ts theme={null}
const { data, meta } = await clinik.encounters.create(request: EncounterCreateRequest): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `status` | `string` | Yes | planned, arrived, triaged, in-progress, onleave, finished, cancelled |
| `class` | `string` | Yes | AMB, IMP, EMER, HH, VR |
| `patientId` | `string` | Yes | Patient reference |
| `practitionerId` | `string` | No | Primary practitioner reference |
| `participants` | `Array<{ practitionerId, role? }>` | No | Additional participants |
| `type` | `string` | No | Encounter type |
| `serviceType` | `string` | No | Service type |
| `priority` | `string` | No | Priority |
| `reasonCode` | `string` | No | Reason for encounter |
| `period` | `{ start?, end? }` | No | Time period |
| `lengthMinutes` | `number` | No | Duration in minutes |
| `location` | `string` | No | Location name |
| `serviceProvider` | `string` | No | Organization name |
| `diagnosis` | `Array<{ condition, use?, rank? }>` | No | Diagnoses |
| `appointmentId` | `string` | No | Appointment that scheduled this encounter |
| `basedOnId` | `string` | No | ServiceRequest that initiated this encounter |
| `partOfId` | `string` | No | Parent encounter (for sub-encounters) |
| `hospitalization` | `object` | No | Inpatient details (admitSource, dischargeDisposition, etc.) |
### Hospitalization
For inpatient encounters (`class: 'IMP'`), include hospitalization details:
| Field | Type | Description |
| - | - | - |
| `admitSource` | `string` | Where admitted from (physician referral, transfer, ER) |
| `dischargeDisposition` | `string` | Discharge destination (home, SNF, expired) |
| `reAdmission` | `string` | Re-admission type if applicable |
| `dietPreference` | `string[]` | Diet preferences (vegetarian, kosher, etc.) |
| `specialArrangement` | `string[]` | Wheelchair, translator, stretcher, etc. |
| `destination` | `string` | Discharge destination facility |
| `origin` | `string` | Originating facility |
## read
```ts theme={null}
const { data, meta } = await clinik.encounters.read(id: string, options?: ReadOptions): Promise>
```
## update
```ts theme={null}
const { data, meta } = await clinik.encounters.update(id: string, request: EncounterUpdateRequest): Promise>
```
## delete
```ts theme={null}
const { data, meta } = await clinik.encounters.delete(id: string): Promise>
```
## search
```ts theme={null}
const { data, meta } = await clinik.encounters.search(params?: ResourceSearchParams): Promise>>
```
| Parameter | Type | Description |
| - | - | - |
| `patientId` | `string` | Filter by patient |
| `status` | `string` | Filter by status |
| `dateFrom` | `string` | Start date filter |
| `dateTo` | `string` | End date filter |
| `sort` | `string` | Sort field (prefix with `-` for descending) |
| `count` | `number` | Results per page |
| `cursor` | `string` | Pagination cursor |
# Enrollment Requests
Source: https://docs.clinikapi.com/sdk/enrollment-requests
SDK reference for enrollment request operations.
# clinik.enrollmentRequests
Enrollment Requests (FHIR `EnrollmentRequest`) represent requests to enroll a patient in an insurance plan. ClinikAPI simplifies the enrollment workflow — use the [FHIR passthrough](/sdk/fhir-passthrough) for advanced scenarios.
## create
```ts theme={null}
const { data, meta } = await clinik.enrollmentRequests.create(request): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `status` | `string` | No | active, cancelled, draft (defaults to active) |
| `created` | `string` | No | When created (defaults to now) |
| `insurerId` | `string` | No | Insurer Organization ID |
| `providerId` | `string` | No | Provider (Practitioner/Organization ID) |
| `candidateId` | `string` | Yes | Patient ID (the enrollment candidate) |
| `coverageId` | `string` | No | Coverage ID |
## Example
```ts theme={null}
const { data } = await clinik.enrollmentRequests.create({
candidateId: 'pt_abc123',
insurerId: 'org_ins456',
providerId: 'Practitioner/prac_dr789',
coverageId: 'cov_plan001',
});
```
## read / update / delete / search
Same pattern as other resources. Update supports `status` only. Search supports `candidateId`, `status`, `insurerId` filters.
# Enrollment Responses
Source: https://docs.clinikapi.com/sdk/enrollment-responses
SDK reference for enrollment response operations.
# clinik.enrollmentResponses
Enrollment Responses (FHIR `EnrollmentResponse`) represent an insurer's response to an enrollment request. Track outcomes, dispositions, and processing status.
## create
```ts theme={null}
const { data, meta } = await clinik.enrollmentResponses.create(request): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `status` | `string` | No | active, cancelled, draft (defaults to active) |
| `requestId` | `string` | No | EnrollmentRequest ID |
| `outcome` | `string` | No | queued, complete, error, partial |
| `disposition` | `string` | No | Disposition message |
| `created` | `string` | No | When created (defaults to now) |
| `organizationId` | `string` | No | Insurer Organization ID |
| `requestProviderId` | `string` | No | Request provider (Practitioner/Organization ID) |
## Example
```ts theme={null}
const { data } = await clinik.enrollmentResponses.create({
requestId: 'enr_req_abc123',
outcome: 'complete',
disposition: 'Enrollment approved for plan year 2024-2025',
organizationId: 'org_ins456',
});
```
## read / update / delete / search
Same pattern as other resources. Update supports `status` and `disposition`. Search supports `status`, `outcome` filters.
# Explanation of Benefits
Source: https://docs.clinikapi.com/sdk/eobs
SDK reference for explanation of benefit operations.
# clinik.eobs
Explanation of Benefits (FHIR `ExplanationOfBenefit`) provide a complete picture of claim adjudication. ClinikAPI exposes the most commonly used fields — use the [FHIR passthrough](/sdk/fhir-passthrough) for advanced EOB scenarios.
## create
```ts theme={null}
const { data, meta } = await clinik.eobs.create(request): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `status` | `string` | Yes | active, cancelled, draft |
| `type` | `string` | Yes | institutional, oral, pharmacy, professional, vision |
| `use` | `string` | Yes | claim, preauthorization, predetermination |
| `patientId` | `string` | Yes | Patient ID |
| `created` | `string` | No | When created (defaults to now) |
| `insurerId` | `string` | Yes | Insurer Organization ID |
| `providerId` | `string` | Yes | Provider (Practitioner/Organization ID) |
| `outcome` | `string` | Yes | queued, complete, error, partial |
| `disposition` | `string` | No | Disposition message |
| `claimId` | `string` | No | Claim ID |
| `claimResponseId` | `string` | No | ClaimResponse ID |
| `billablePeriod` | `{ start?, end? }` | No | Billable period |
| `insurance` | `Array` | Yes | Insurance coverage (min 1) |
| `item` | `Array` | No | Line items with adjudication |
| `total` | `Array` | No | Totals by category |
| `payment` | `object` | No | Payment details |
| `processNote` | `Array` | No | Processing notes |
### Insurance Object
| Field | Type | Required | Description |
| - | - | - | - |
| `focal` | `boolean` | Yes | Whether this is the focal coverage |
| `coverageId` | `string` | Yes | Coverage resource ID |
### Item Object
| Field | Type | Required | Description |
| - | - | - | - |
| `sequence` | `number` | Yes | Sequence number |
| `productOrService` | `string` | Yes | Product or service code |
| `quantity` | `{ value, unit? }` | No | Quantity |
| `unitPrice` | `{ value, currency? }` | No | Unit price |
| `net` | `{ value, currency? }` | No | Net amount |
| `adjudication` | `Array` | No | Adjudication details |
## Example
```ts theme={null}
const { data } = await clinik.eobs.create({
status: 'active',
type: 'professional',
use: 'claim',
patientId: 'pt_abc123',
insurerId: 'org_ins_bluecross',
providerId: 'Practitioner/prac_dr456',
outcome: 'complete',
claimId: 'claim_xyz456',
insurance: [{ focal: true, coverageId: 'cov_primary789' }],
item: [
{
sequence: 1,
productOrService: '99214',
unitPrice: { value: 200.00, currency: 'USD' },
net: { value: 200.00, currency: 'USD' },
adjudication: [
{ category: 'submitted', amount: { value: 200.00, currency: 'USD' } },
{ category: 'benefit', amount: { value: 144.00, currency: 'USD' } },
],
},
],
total: [
{ category: 'submitted', amount: { value: 200.00, currency: 'USD' } },
{ category: 'benefit', amount: { value: 144.00, currency: 'USD' } },
],
payment: {
type: 'complete',
amount: { value: 144.00, currency: 'USD' },
date: '2024-04-01',
},
});
```
## read / update / delete / search
Same pattern as other resources. Update supports `status`, `disposition`. Search supports `patientId`, `status`, `use`, `outcome`, `claimId` filters.
# Error Handling
Source: https://docs.clinikapi.com/sdk/error-handling
SDK error types, retry behavior, and best practices.
# Error Handling
The SDK throws typed errors that you can catch and handle gracefully.
## Error Types
```ts theme={null}
try {
const { data } = await clinik.patients.create({ firstName: '', lastName: '' });
} catch (err) {
if (err.name === 'ClinikValidationError') {
// 422 — request body failed validation
console.error('Issues:', err.issues);
} else if (err.name === 'ClinikRateLimitError') {
// 429 — rate limit exceeded
console.error('Retry after:', err.retryAfter, 'seconds');
} else if (err.name === 'ClinikNotFoundError') {
// 404 — resource not found
console.error('Not found:', err.message);
} else if (err.name === 'ClinikApiError') {
// Any other API error
console.error('Code:', err.code);
console.error('Status:', err.status);
console.error('Request ID:', err.requestId);
}
}
```
## Error Properties
All errors include:
| Property | Type | Description |
| - | - | - |
| `name` | `string` | Error class name |
| `message` | `string` | Human-readable message |
| `code` | `string` | Machine-readable error code |
| `status` | `number` | HTTP status code |
| `requestId` | `string` | Request ID for support |
`ClinikValidationError` also includes:
| Property | Type | Description |
| - | - | - |
| `issues` | `Array` | Validation issue details |
## Automatic Retries
The SDK retries automatically on:
* `5xx` server errors
* `429` rate limit responses
* Network failures
Retry behavior uses **jittered exponential backoff** to prevent thundering herd:
```
Attempt 1: random(0, 2000ms)
Attempt 2: random(0, 4000ms)
Attempt 3: random(0, 8000ms)
Cap: 10,000ms
```
Configure retries:
```ts theme={null}
const clinik = new Clinik(key, {
retries: 3, // default: 2
timeout: 15000, // default: 30000ms
});
```
Set `retries: 0` to disable automatic retries.
## PHI Sanitization
Error messages never contain Protected Health Information. Validation errors include field names and constraint descriptions, but never field values:
```json theme={null}
{
"issues": [
{
"severity": "error",
"code": "invalid",
"diagnostics": "firstName: String must contain at least 1 character(s)"
}
]
}
```
## Best Practices
* Always wrap SDK calls in try/catch
* Log `requestId` for support tickets
* Monitor `rateLimitRemaining` in `meta` to avoid hitting limits
* Use `retries: 0` for idempotency-sensitive operations
* Handle `ClinikValidationError` separately to show field-level errors to users
# Family History
Source: https://docs.clinikapi.com/sdk/family-history
SDK reference for family member history operations.
# clinik.familyHistory
Family member history records significant health conditions for a person related to the patient, relevant in the context of care (e.g., genetic risk factors, hereditary conditions).
## create
```ts theme={null}
const { data, meta } = await clinik.familyHistory.create(request): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `status` | `string` | Yes | partial, completed, health-unknown |
| `patientId` | `string` | Yes | Patient this history belongs to |
| `date` | `string` | No | When the history was recorded |
| `name` | `string` | No | Family member's name |
| `relationship` | `string` | Yes | Relationship to patient (mother, father, sibling, etc.) |
| `sex` | `string` | No | Family member's sex |
| `bornDate` | `string` | No | Family member's birth date |
| `ageString` | `string` | No | Approximate age (e.g. "around 50") |
| `estimatedAge` | `boolean` | No | Whether the age is estimated |
| `deceasedBoolean` | `boolean` | No | Whether the family member is deceased |
| `deceasedDate` | `string` | No | Date of death |
| `reasonCode` | `string[]` | No | Why the history was recorded |
| `note` | `string` | No | Additional notes |
| `condition` | `Array` | No | Health conditions (code, outcome, contributedToDeath, onsetString, note) |
## Example
```ts theme={null}
const { data } = await clinik.familyHistory.create({
status: 'completed',
patientId: 'pt_jane_doe',
date: '2025-01-15',
name: 'Robert Doe',
relationship: 'father',
sex: 'male',
deceasedBoolean: true,
deceasedDate: '2020-06-10',
condition: [
{
code: 'Type 2 Diabetes Mellitus',
onsetString: 'Age 45',
note: 'Managed with metformin',
},
{
code: 'Coronary Artery Disease',
contributedToDeath: true,
onsetString: 'Age 60',
outcome: 'Fatal myocardial infarction',
},
],
note: 'Father had significant cardiovascular risk factors',
});
```
## read / update / delete / search
Same pattern as other resources. Search supports `patientId`, `status`, `relationship`, `dateFrom`, `dateTo` filters.
# FHIR Passthrough
Source: https://docs.clinikapi.com/sdk/fhir-passthrough
SDK reference for raw FHIR R4 requests.
# clinik.fhir
The FHIR escape hatch lets you send raw FHIR R4 requests when the simplified SDK methods don't cover your use case.
## request
```ts theme={null}
const { data, meta } = await clinik.fhir.request(
method: string,
path: string,
body?: unknown
): Promise>
```
| Parameter | Type | Required | Description |
| - | - | - | - |
| `method` | `string` | Yes | GET, POST, PUT, PATCH, DELETE |
| `path` | `string` | Yes | FHIR resource path (e.g. `/Patient`, `/Observation/123`) |
| `body` | `unknown` | No | Request body (for POST, PUT, PATCH) |
Do not include `/v1/` in the path — the SDK prepends it automatically.
Tenant isolation is enforced on all passthrough requests.
## Examples
```ts theme={null}
// Create a raw FHIR Patient
const { data } = await clinik.fhir.request('POST', '/Patient', {
resourceType: 'Patient',
name: [{ family: 'Smith', given: ['John'] }],
gender: 'male',
birthDate: '1990-01-15',
});
// Search with custom FHIR parameters
const { data: bundle } = await clinik.fhir.request(
'GET',
'/Observation?code=8867-4&date=ge2024-01-01&_sort=-date'
);
// Read a specific resource
const { data: patient } = await clinik.fhir.request('GET', '/Patient/pt_abc123');
// FHIR operation
const { data: everything } = await clinik.fhir.request(
'GET',
'/Patient/pt_abc123/$everything'
);
// Delete
await clinik.fhir.request('DELETE', '/Observation/obs_xyz789');
```
## When to Use
* Custom FHIR search parameters not exposed in the simplified SDK
* FHIR operations (`$everything`, `$validate`, etc.)
* Resource types not yet simplified by ClinikAPI
* Complex FHIR queries with chained parameters
## Important Notes
* Returns raw FHIR R4 resources, not the simplified format
* Tenant tag injection and filtering is still enforced
* Rate limits and authentication work the same as simplified endpoints
# Goals
Source: https://docs.clinikapi.com/sdk/goals
SDK reference for goal operations.
# clinik.goals
Goals represent intended objectives for a patient's care, including clinical targets, behavioral goals, and treatment milestones.
## create
```ts theme={null}
const { data, meta } = await clinik.goals.create(request): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `lifecycleStatus` | `string` | Yes | proposed, planned, accepted, active, on-hold, completed, cancelled, rejected |
| `description` | `string` | Yes | What the goal is |
| `patientId` | `string` | Yes | Patient ID |
| `achievementStatus` | `string` | No | in-progress, improving, worsening, achieved, etc. |
| `category` | `string[]` | No | Goal categories (treatment, dietary, behavioral) |
| `priority` | `string` | No | high-priority, medium-priority, low-priority |
| `startDate` | `string` | No | When pursuit of the goal began |
| `target` | `Array` | No | Target outcomes with measures and due dates |
| `statusDate` | `string` | No | When status was last changed |
| `statusReason` | `string` | No | Reason for current status |
| `expressedById` | `string` | No | Who created the goal |
| `addressesIds` | `string[]` | No | Condition/Observation IDs this goal addresses |
| `note` | `string` | No | Additional notes |
| `outcomeCode` | `string[]` | No | Outcome codes |
## Example
```ts theme={null}
const { data } = await clinik.goals.create({
lifecycleStatus: 'active',
description: 'Reduce HbA1c to below 7%',
patientId: 'pt_abc123',
achievementStatus: 'in-progress',
category: ['treatment'],
priority: 'high-priority',
startDate: '2024-01-01',
target: [
{
measure: 'HbA1c',
detailQuantity: { value: 7, unit: '%' },
dueDate: '2024-06-30',
},
],
expressedById: 'prac_dr456',
addressesIds: ['cond_diabetes789'],
note: 'Patient motivated, starting metformin and dietary changes',
});
```
## read / update / delete / search
Same pattern as other resources. Update supports `lifecycleStatus`, `achievementStatus`, `statusReason`, `note`, `target`. Search supports `patientId`, `lifecycleStatus`, `achievementStatus`, `category` filters.
# Healthcare Services
Source: https://docs.clinikapi.com/sdk/healthcare-services
SDK reference for healthcare service operations.
# clinik.healthcareServices
Healthcare services describe the services offered by an organization — specialties, availability, referral methods, and eligibility requirements.
## create
```ts theme={null}
const { data, meta } = await clinik.healthcareServices.create(request): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `name` | `string` | Yes | Service name |
| `active` | `boolean` | No | Whether active (default: true) |
| `providedById` | `string` | No | Organization providing the service |
| `category` | `string[]` | No | Broad categories |
| `type` | `string[]` | No | Service types |
| `specialty` | `string[]` | No | Specialties handled |
| `locationNames` | `string[]` | No | Location names |
| `comment` | `string` | No | Additional description |
| `phone` | `string` | No | Contact phone |
| `email` | `string` | No | Contact email |
| `appointmentRequired` | `boolean` | No | Whether appointment is required |
| `availableTime` | `Array` | No | Availability schedules |
| `notAvailable` | `Array` | No | Unavailable periods |
| `availabilityExceptions` | `string` | No | Free-text exceptions |
| `program` | `string[]` | No | Programs this service is part of |
| `referralMethod` | `string[]` | No | Accepted referral methods |
| `communication` | `string[]` | No | Languages offered |
## Example
```ts theme={null}
const { data } = await clinik.healthcareServices.create({
name: 'Cardiology Consultation',
providedById: 'org_sunrise_medical',
category: ['specialist'],
type: ['cardiology'],
specialty: ['Cardiology'],
appointmentRequired: true,
availableTime: [
{ daysOfWeek: ['mon', 'wed', 'fri'], availableStartTime: '09:00:00', availableEndTime: '17:00:00' },
],
notAvailable: [
{ description: 'Holiday closure', during: { start: '2025-12-24', end: '2025-12-26' } },
],
referralMethod: ['phone', 'fax', 'electronic'],
communication: ['en', 'es'],
});
```
## read / update / delete / search
Same pattern as other resources. Search supports `name`, `type`, `specialty`, `active` filters.
# Imaging Studies
Source: https://docs.clinikapi.com/sdk/imaging-studies
SDK reference for imaging study operations.
# clinik.imagingStudies
Imaging Studies (FHIR `ImagingStudy`) represent radiology and diagnostic imaging exams. ClinikAPI simplifies series to key fields and skips instance-level detail — use the [FHIR passthrough](/sdk/fhir-passthrough) for DICOM-level access.
## create
```ts theme={null}
const { data, meta } = await clinik.imagingStudies.create(request): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `status` | `string` | Yes | registered, available, cancelled |
| `patientId` | `string` | Yes | Patient ID |
| `encounterId` | `string` | No | Encounter ID |
| `modality` | `string[]` | No | Imaging modalities (CT, MR, US, XR, NM, PT) |
| `started` | `string` | No | When the study started |
| `referrerId` | `string` | No | Referring Practitioner ID |
| `interpreterIds` | `string[]` | No | Interpreting Practitioner IDs |
| `numberOfSeries` | `number` | No | Number of series |
| `numberOfInstances` | `number` | No | Number of instances |
| `procedureCode` | `string[]` | No | Procedure codes |
| `locationId` | `string` | No | Location ID |
| `reasonCode` | `string[]` | No | Reason codes |
| `description` | `string` | No | Study description |
| `note` | `string` | No | Additional notes |
| `basedOn` | `string[]` | No | ServiceRequest/CarePlan IDs |
| `series` | `Array` | No | Series data |
### Series Object
| Field | Type | Required | Description |
| - | - | - | - |
| `uid` | `string` | Yes | Series instance UID |
| `number` | `number` | No | Series number |
| `modality` | `string` | Yes | Series modality |
| `description` | `string` | No | Series description |
| `numberOfInstances` | `number` | No | Number of instances |
| `bodySite` | `string` | No | Body site imaged |
| `laterality` | `string` | No | Left, right, bilateral |
| `started` | `string` | No | When series started |
## Example
```ts theme={null}
const { data } = await clinik.imagingStudies.create({
status: 'available',
patientId: 'pt_abc123',
encounterId: 'enc_visit456',
modality: ['CT'],
started: '2024-03-15T10:00:00Z',
referrerId: 'prac_dr789',
numberOfSeries: 2,
numberOfInstances: 120,
procedureCode: ['CT chest with contrast'],
description: 'CT Chest — rule out pulmonary embolism',
reasonCode: ['Shortness of breath', 'Chest pain'],
series: [
{
uid: '1.2.840.113619.2.55.3.604688119.969.1364202859.234',
number: 1,
modality: 'CT',
description: 'Axial images',
numberOfInstances: 80,
bodySite: 'Chest',
},
{
uid: '1.2.840.113619.2.55.3.604688119.969.1364202859.235',
number: 2,
modality: 'CT',
description: 'Coronal reformats',
numberOfInstances: 40,
bodySite: 'Chest',
},
],
});
```
## read / update / delete / search
Same pattern as other resources. Update supports `status`, `description`, `note`. Search supports `patientId`, `status`, `modality`, `dateFrom`, `dateTo` filters.
# Immunization Evaluations
Source: https://docs.clinikapi.com/sdk/immunization-evaluations
SDK reference for immunization evaluation operations.
# clinik.immunizationEvaluations
Immunization Evaluations (FHIR `ImmunizationEvaluation`) assess whether an immunization event meets the protocol requirements for a target disease. Use these to track vaccine series compliance.
## create
```ts theme={null}
const { data, meta } = await clinik.immunizationEvaluations.create(request): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `status` | `string` | Yes | completed |
| `patientId` | `string` | Yes | Patient ID |
| `date` | `string` | No | Evaluation date |
| `authorityId` | `string` | No | Authority Organization ID |
| `targetDisease` | `string` | Yes | Disease being evaluated against |
| `immunizationEventId` | `string` | Yes | Immunization ID |
| `doseStatus` | `string` | Yes | valid, not-valid |
| `doseStatusReason` | `string[]` | No | Reasons for the dose status |
| `description` | `string` | No | Description of the evaluation |
| `series` | `string` | No | Vaccine series name |
| `doseNumber` | `number` | No | Dose number within series |
| `seriesDoses` | `number` | No | Recommended number of doses |
## Example
```ts theme={null}
const { data } = await clinik.immunizationEvaluations.create({
status: 'completed',
patientId: 'pt_abc123',
date: '2024-03-20',
targetDisease: 'COVID-19',
immunizationEventId: 'imm_vax456',
doseStatus: 'valid',
series: 'Primary Series',
doseNumber: 2,
seriesDoses: 2,
description: 'Second dose of primary series meets protocol requirements',
});
```
## read / update / delete / search
Same pattern as other resources. Update supports `status` and `description`. Search supports `patientId`, `status`, `immunizationEventId`, `targetDisease` filters.
# Immunization Recommendations
Source: https://docs.clinikapi.com/sdk/immunization-recommendations
SDK reference for immunization recommendation operations.
# clinik.immunizationRecommendations
Immunization Recommendations (FHIR `ImmunizationRecommendation`) provide patient-specific vaccine recommendations based on immunization history and clinical guidelines.
## create
```ts theme={null}
const { data, meta } = await clinik.immunizationRecommendations.create(request): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `patientId` | `string` | Yes | Patient ID |
| `date` | `string` | Yes | When recommendations were created |
| `authorityId` | `string` | No | Organization ID for the authority |
| `recommendation` | `Array` | Yes | Recommendation entries |
| `recommendation[].vaccineCode` | `string[]` | No | Vaccine codes |
| `recommendation[].targetDisease` | `string` | No | Target disease |
| `recommendation[].forecastStatus` | `string` | Yes | Forecast status (e.g. due, overdue, immune, contraindicated) |
| `recommendation[].forecastReason` | `string[]` | No | Forecast reasons |
| `recommendation[].description` | `string` | No | Description |
| `recommendation[].series` | `string` | No | Series name |
| `recommendation[].doseNumber` | `number` | No | Recommended dose number |
| `recommendation[].seriesDoses` | `number` | No | Total doses in series |
| `recommendation[].dateCriterion` | `Array` | No | Date criteria |
| `recommendation[].dateCriterion[].code` | `string` | Yes | Criterion code (e.g. "Earliest Date", "Recommended Date") |
| `recommendation[].dateCriterion[].value` | `string` | Yes | Criterion date value |
## Example
```ts theme={null}
const { data } = await clinik.immunizationRecommendations.create({
patientId: 'pt_child456',
date: '2024-06-15T10:00:00Z',
authorityId: 'org_cdc',
recommendation: [
{
vaccineCode: ['MMR'],
targetDisease: 'Measles',
forecastStatus: 'due',
series: 'Primary Series',
doseNumber: 2,
seriesDoses: 2,
dateCriterion: [
{ code: 'Earliest Date', value: '2024-07-01' },
{ code: 'Recommended Date', value: '2024-08-15' },
{ code: 'Latest Date', value: '2024-12-31' },
],
},
{
vaccineCode: ['Tdap'],
targetDisease: 'Tetanus',
forecastStatus: 'overdue',
description: 'Booster dose overdue by 6 months',
doseNumber: 1,
seriesDoses: 1,
},
],
});
```
## read / delete / search
Immunization recommendations support `read`, `delete`, and `search` — but are **not commonly updated**. Search supports `patientId`, `vaccineCode`, `targetDisease`, `dateFrom`, `dateTo` filters.
# Immunizations
Source: https://docs.clinikapi.com/sdk/immunizations
SDK reference for immunization operations.
# clinik.immunizations
Immunizations (FHIR `Immunization`) record vaccine administration events including vaccine details, dose information, and reactions.
## create
```ts theme={null}
const { data, meta } = await clinik.immunizations.create(request): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `status` | `string` | Yes | completed, not-done |
| `vaccineCode` | `string \| object` | Yes | Vaccine code (string or `{ system?, code, display? }`) |
| `patientId` | `string` | Yes | Patient ID |
| `encounterId` | `string` | No | Encounter context |
| `occurrenceDateTime` | `string` | No | When administered (defaults to now) |
| `recorded` | `string` | No | When recorded |
| `primarySource` | `boolean` | No | Whether from primary source |
| `manufacturer` | `string` | No | Vaccine manufacturer |
| `lotNumber` | `string` | No | Lot number |
| `expirationDate` | `string` | No | Expiration date |
| `site` | `string` | No | Body site (e.g. left arm) |
| `route` | `string` | No | Route (e.g. intramuscular) |
| `doseQuantity` | `{ value, unit? }` | No | Dose quantity |
| `performer` | `Array` | No | Performers |
| `note` | `string` | No | Additional notes |
| `reasonCode` | `string[]` | No | Reason codes |
| `statusReason` | `string` | No | Reason for not-done status |
| `isSubpotent` | `boolean` | No | Whether dose is subpotent |
| `reaction` | `Array` | No | Observed reactions |
| `protocolApplied` | `Array` | No | Protocol applied records |
## Example
```ts theme={null}
const { data } = await clinik.immunizations.create({
status: 'completed',
vaccineCode: { system: 'http://hl7.org/fhir/sid/cvx', code: '208', display: 'COVID-19 mRNA' },
patientId: 'pt_abc123',
occurrenceDateTime: '2024-03-15T10:30:00Z',
manufacturer: 'Pfizer-BioNTech',
lotNumber: 'EW0182',
expirationDate: '2024-09-30',
site: 'Left deltoid',
route: 'Intramuscular',
doseQuantity: { value: 0.3, unit: 'mL' },
performer: [{ function: 'Administering', actorId: 'prac_nurse456' }],
protocolApplied: [{
series: 'Primary Series',
doseNumber: 2,
seriesDoses: 2,
targetDisease: ['COVID-19'],
}],
note: 'Patient tolerated well, observed for 15 minutes post-administration',
});
```
## read / update / delete / search
Same pattern as other resources. Search supports `patientId`, `status`, `vaccineCode`, `dateFrom`, `dateTo` filters.
# Installation
Source: https://docs.clinikapi.com/sdk/installation
Install and configure the ClinikAPI TypeScript SDK.
# Installation
```bash theme={null}
npm install @clinikapi/sdk
```
## Requirements
* Node.js 18+ (or any runtime with `fetch` support)
* TypeScript 5+ (recommended, but not required)
## Quick Setup
```ts theme={null}
import { Clinik } from '@clinikapi/sdk';
const clinik = new Clinik(process.env.CLINIKAPI_SECRET_KEY!);
```
The SDK is **server-side only**. It authenticates with your secret API key — never import it in client-side code.
For frontend UI, use `@clinikapi/react` with the [proxy pattern](/components/overview).
## Configuration Options
```ts theme={null}
const clinik = new Clinik(process.env.CLINIKAPI_SECRET_KEY!, {
baseUrl: 'https://api.clinikapi.com', // default
timeout: 30000, // request timeout in ms (default: 30s)
retries: 2, // auto-retry on 5xx/429 (default: 2)
});
```
| Option | Type | Default | Description |
| - | - | - | - |
| `baseUrl` | `string` | `https://api.clinikapi.com` | API base URL |
| `timeout` | `number` | `30000` | Request timeout in milliseconds |
| `retries` | `number` | `2` | Max retry attempts on 5xx / 429 |
## Framework Examples
### Next.js (Server Action)
```ts theme={null}
'use server';
import { Clinik } from '@clinikapi/sdk';
const clinik = new Clinik(process.env.CLINIKAPI_SECRET_KEY!);
export async function getPatient(id: string) {
const { data } = await clinik.patients.read(id);
return data;
}
```
### Express.js
```ts theme={null}
import express from 'express';
import { Clinik } from '@clinikapi/sdk';
const app = express();
const clinik = new Clinik(process.env.CLINIKAPI_SECRET_KEY!);
app.get('/api/patients/:id', async (req, res) => {
const { data, meta } = await clinik.patients.read(req.params.id);
res.json({ patient: data, requestId: meta.requestId });
});
```
### Hono
```ts theme={null}
import { Hono } from 'hono';
import { Clinik } from '@clinikapi/sdk';
const app = new Hono();
const clinik = new Clinik(process.env.CLINIKAPI_SECRET_KEY!);
app.get('/patients/:id', async (c) => {
const { data } = await clinik.patients.read(c.req.param('id'));
return c.json(data);
});
```
# Intakes
Source: https://docs.clinikapi.com/sdk/intakes
SDK reference for intake form (QuestionnaireResponse) operations.
# clinik.intakes
Intakes represent completed patient intake forms, stored as FHIR QuestionnaireResponse resources. Each intake contains structured question-answer pairs with full recursive nesting support.
## submit
```ts theme={null}
const { data, meta } = await clinik.intakes.submit(request: IntakeSubmitRequest): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `patientId` | `string` | Yes | Patient reference |
| `encounterId` | `string` | No | Encounter reference |
| `authorId` | `string` | No | Who filled out the form |
| `sourceId` | `string` | No | Who provided the answers |
| `questionnaire` | `string` | No | Reference to Questionnaire definition |
| `status` | `string` | No | in-progress, completed, amended, stopped |
| `authored` | `string` | No | When answers were gathered |
| `basedOn` | `string[]` | No | CarePlan or ServiceRequest IDs this intake fulfills |
| `partOf` | `string[]` | No | Observation or Procedure IDs this intake is part of |
| `items` | `IntakeItem[]` | Yes | Question-answer pairs (recursive) |
### Item Structure
Each item has a `linkId`, optional `definition`, `text`, `answer` values, and nested `items`:
```ts theme={null}
const { data } = await clinik.intakes.submit({
patientId: 'pt_abc123',
encounterId: 'enc_xyz789',
questionnaire: 'https://forms.clinikapi.com/new-patient-intake',
status: 'completed',
basedOn: ['sr_referral123'],
items: [
{
linkId: 'chief-complaint',
text: 'What is your primary reason for visiting today?',
answer: [{ valueString: 'Annual physical exam' }],
},
{
linkId: 'allergies',
text: 'Do you have any known allergies?',
answer: [{ valueBoolean: true }],
},
{
linkId: 'pain-level',
text: 'Rate your current pain level (0-10)',
answer: [{ valueInteger: 3 }],
},
{
linkId: 'temperature',
text: 'Body temperature',
answer: [{ valueQuantity: { value: 98.6, unit: '°F' } }],
},
{
linkId: 'smoking-status',
text: 'Smoking status',
answer: [{
valueCoding: {
system: 'http://snomed.info/sct',
code: '266919005',
display: 'Never smoker',
},
}],
},
{
linkId: 'vitals-group',
text: 'Vitals',
items: [
{
linkId: 'weight',
text: 'Weight',
answer: [{ valueQuantity: { value: 165, unit: 'lbs' } }],
},
{
linkId: 'height',
text: 'Height',
answer: [{ valueString: '5\'10"' }],
},
],
},
],
});
```
### Answer Types
| Field | Type | Use Case |
| - | - | - |
| `valueString` | `string` | Free text answers |
| `valueBoolean` | `boolean` | Yes/no questions |
| `valueInteger` | `number` | Whole numbers |
| `valueDecimal` | `number` | Decimal numbers |
| `valueDate` | `string` | Date answers (YYYY-MM-DD) |
| `valueDateTime` | `string` | Date-time answers (ISO 8601) |
| `valueTime` | `string` | Time answers (HH:mm:ss) |
| `valueCoding` | `{ system?, code, display? }` | Coded answers (SNOMED, ICD, etc.) |
| `valueQuantity` | `{ value, unit? }` | Measurements |
| `valueUri` | `string` | URI answers |
## read / update / delete / search
Same pattern as other resources. Search supports `patientId`, `status`, `dateFrom`, `dateTo` filters.
# Invoices
Source: https://docs.clinikapi.com/sdk/invoices
SDK reference for invoice operations.
# clinik.invoices
Invoices (FHIR `Invoice`) represent billing documents for healthcare services. ClinikAPI exposes the most commonly used fields — use the [FHIR passthrough](/sdk/fhir-passthrough) for advanced invoice scenarios.
## create
```ts theme={null}
const { data, meta } = await clinik.invoices.create(request: InvoiceCreateRequest): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `status` | `string` | Yes | draft, issued, balanced, cancelled |
| `patientId` | `string` | No | Patient the invoice is for |
| `type` | `string` | No | Invoice type |
| `recipientId` | `string` | No | Recipient (Organization/Patient reference) |
| `date` | `string` | No | Invoice date (defaults to now) |
| `issuerId` | `string` | No | Issuing Organization ID |
| `accountId` | `string` | No | Account ID |
| `participant` | `Array` | No | Participants involved |
| `lineItem` | `Array` | No | Line items with charge codes and pricing |
| `totalNet` | `{ value, currency? }` | No | Total net amount |
| `totalGross` | `{ value, currency? }` | No | Total gross amount |
| `paymentTerms` | `string` | No | Payment terms text |
| `cancelledReason` | `string` | No | Reason for cancellation |
| `note` | `string` | No | Additional notes |
### Participant Object
| Field | Type | Required | Description |
| - | - | - | - |
| `role` | `string` | No | Participant role |
| `actorId` | `string` | Yes | Actor reference ID |
### Line Item Object
| Field | Type | Required | Description |
| - | - | - | - |
| `sequence` | `number` | No | Sequence number |
| `chargeItemCode` | `string` | Yes | Charge item code |
| `priceComponent` | `Array` | No | Price components |
## Example
```ts theme={null}
const { data } = await clinik.invoices.create({
status: 'issued',
patientId: 'pt_abc123',
type: 'professional-services',
issuerId: 'org_clinic456',
lineItem: [
{
sequence: 1,
chargeItemCode: '99213',
priceComponent: [
{ type: 'base', amount: { value: 150.00, currency: 'USD' } },
],
},
],
totalNet: { value: 150.00, currency: 'USD' },
totalGross: { value: 150.00, currency: 'USD' },
paymentTerms: 'Net 30',
});
```
## read / update / delete / search
Same pattern as other resources. Update supports `status`, `cancelledReason`, `note`. Search supports `patientId`, `status`, `dateFrom`, `dateTo`, `issuerId` filters.
# Labs
Source: https://docs.clinikapi.com/sdk/labs
SDK reference for lab report (DiagnosticReport) operations.
# clinik.labs
## create
```ts theme={null}
const { data, meta } = await clinik.labs.create(request: LabCreateRequest): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `status` | `string` | Yes | registered, partial, preliminary, final, amended, corrected, appended, cancelled |
| `code` | `string \| { system?, code, display? }` | Yes | LOINC report type |
| `patientId` | `string` | Yes | Patient reference |
| `encounterId` | `string` | No | Encounter reference |
| `effectiveDateTime` | `string` | No | Clinically relevant time (point in time) |
| `effectivePeriod` | `{ start?, end? }` | No | Clinically relevant time (range) |
| `resultIds` | `string[]` | No | Observation IDs in this report |
| `category` | `string` | No | LAB, RAD, PAT |
| `conclusion` | `string` | No | Clinical conclusion text |
| `conclusionCodes` | `Array<{ system?, code, display? }>` | No | SNOMED findings |
| `performer` | `string` | No | Who performed the diagnostic |
| `resultsInterpreter` | `string` | No | Who interpreted results |
| `specimenIds` | `string[]` | No | Specimen references |
| `presentedForm` | `Array<{ contentType, data?, url?, title? }>` | No | Attached documents |
| `basedOn` | `string[]` | No | ServiceRequest IDs this report is based on |
| `media` | `Array<{ comment?, linkId }>` | No | Media/images linked to this report |
## read
Supports `_include` for referenced observations:
```ts theme={null}
const { data } = await clinik.labs.read('lab_abc123', {
include: ['Observation'],
});
```
## update
```ts theme={null}
const { data, meta } = await clinik.labs.update(id: string, request: LabUpdateRequest): Promise>
```
Updatable fields: `status`, `conclusion`, `conclusionCodes`, `resultIds`, `resultsInterpreter`, `presentedForm`, `effectiveDateTime`, `effectivePeriod`.
## delete / search
Same pattern as other resources.
# Locations
Source: https://docs.clinikapi.com/sdk/locations
SDK reference for location operations.
# clinik.locations
Locations represent physical places where healthcare services are provided — clinics, hospitals, rooms, buildings, or mobile units.
## create
```ts theme={null}
const { data, meta } = await clinik.locations.create(request): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `name` | `string` | Yes | Location name |
| `status` | `string` | No | active, suspended, inactive (default: active) |
| `description` | `string` | No | Additional details about the location |
| `mode` | `string` | No | instance (specific place) or kind (class of locations) |
| `type` | `string[]` | No | Location type codes |
| `alias` | `string[]` | No | Alternate names |
| `phone` | `string` | No | Phone number |
| `email` | `string` | No | Email address |
| `address` | `Address` | No | Physical address |
| `physicalType` | `string` | No | Physical form (building, wing, room, bed, etc.) |
| `position` | `object` | No | GPS coordinates (longitude, latitude, altitude) |
| `managingOrganizationId` | `string` | No | Organization that manages this location |
| `partOfId` | `string` | No | Parent location ID |
| `hoursOfOperation` | `Array` | No | Operating hours (daysOfWeek, allDay, openingTime, closingTime) |
| `availabilityExceptions` | `string` | No | Description of availability exceptions |
## Example
```ts theme={null}
const { data } = await clinik.locations.create({
name: 'Sunrise Medical Center — Main Building',
status: 'active',
description: 'Primary care facility with 3 floors and 40 exam rooms',
mode: 'instance',
type: ['HOSP'],
phone: '555-0100',
email: 'info@sunrise-medical.com',
address: {
line: ['100 Health Blvd'],
city: 'Austin',
state: 'TX',
postalCode: '78701',
country: 'US',
},
physicalType: 'building',
position: { longitude: -97.7431, latitude: 30.2672 },
managingOrganizationId: 'org_sunrise',
hoursOfOperation: [
{ daysOfWeek: ['mon', 'tue', 'wed', 'thu', 'fri'], openingTime: '08:00:00', closingTime: '18:00:00' },
{ daysOfWeek: ['sat'], openingTime: '09:00:00', closingTime: '13:00:00' },
],
availabilityExceptions: 'Closed on federal holidays',
});
```
## read / update / delete / search
Same pattern as other resources. Search supports `name`, `status`, `type`, `address` filters.
# Measure Reports
Source: https://docs.clinikapi.com/sdk/measure-reports
SDK reference for measure report operations.
# clinik.measureReports
Measure Reports (FHIR `MeasureReport`) contain the results of evaluating a measure against a population or individual patient.
## create
```ts theme={null}
const { data, meta } = await clinik.measureReports.create(request): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `status` | `string` | Yes | complete, pending, error |
| `type` | `string` | Yes | individual, subject-list, summary, data-collection |
| `measureId` | `string` | Yes | Measure reference (canonical URL or ID) |
| `patientId` | `string` | No | Patient ID |
| `date` | `string` | No | Report date (defaults to now) |
| `reporterId` | `string` | No | Reporter (Practitioner/Organization ID) |
| `period` | `object` | Yes | Reporting period |
| `period.start` | `string` | Yes | Period start |
| `period.end` | `string` | Yes | Period end |
| `group` | `Array` | No | Report groups |
| `group[].code` | `string` | No | Group code |
| `group[].population` | `Array` | No | Population results |
| `group[].population[].code` | `string` | No | Population code |
| `group[].population[].count` | `number` | No | Population count |
| `group[].measureScore` | `object` | No | Measure score |
| `group[].measureScore.value` | `number` | Yes | Score value |
| `group[].measureScore.unit` | `string` | No | Score unit |
## Example
```ts theme={null}
const { data } = await clinik.measureReports.create({
status: 'complete',
type: 'summary',
measureId: 'diabetes-hba1c-control',
period: { start: '2024-01-01', end: '2024-03-31' },
reporterId: 'org_clinic789',
group: [{
code: 'initial-population',
population: [
{ code: 'initial-population', count: 500 },
{ code: 'denominator', count: 480 },
{ code: 'numerator', count: 72 },
],
measureScore: { value: 0.15, unit: '%' },
}],
});
```
## read / update / delete / search
Same pattern as other resources. Update supports `status`. Search supports `patientId`, `status`, `measureId`, `dateFrom`, `dateTo` filters.
# Measures
Source: https://docs.clinikapi.com/sdk/measures
SDK reference for measure operations.
# clinik.measures
Measures (FHIR `Measure`) define quality measures, clinical guidelines, and performance metrics used in healthcare quality reporting.
## create
```ts theme={null}
const { data, meta } = await clinik.measures.create(request): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `status` | `string` | Yes | draft, active, retired |
| `name` | `string` | No | Computer-friendly name |
| `title` | `string` | No | Human-friendly title |
| `description` | `string` | No | Description |
| `purpose` | `string` | No | Why this measure is defined |
| `usage` | `string` | No | Clinical usage description |
| `publisher` | `string` | No | Publisher |
| `date` | `string` | No | Publication date |
| `version` | `string` | No | Business version |
| `url` | `string` | No | Canonical URL |
| `experimental` | `boolean` | No | For testing purposes |
| `scoring` | `string` | No | proportion, ratio, continuous-variable, cohort |
| `type` | `string[]` | No | process, outcome, structure, patient-reported-outcome, composite |
| `riskAdjustment` | `string` | No | Risk adjustment description |
| `rationale` | `string` | No | Rationale |
| `clinicalRecommendationStatement` | `string` | No | Clinical recommendation |
| `guidance` | `string` | No | Implementation guidance |
| `topic` | `string[]` | No | Topic categories |
| `group` | `Array` | No | Measure groups |
| `group[].code` | `string` | No | Group code |
| `group[].description` | `string` | No | Group description |
## Example
```ts theme={null}
const { data } = await clinik.measures.create({
status: 'active',
name: 'diabetes-hba1c-control',
title: 'Diabetes: HbA1c Poor Control (>9%)',
description: 'Percentage of patients 18-75 with diabetes whose HbA1c was >9.0%',
scoring: 'proportion',
type: ['outcome'],
topic: ['Diabetes', 'Quality Measure'],
group: [{
code: 'initial-population',
description: 'Patients 18-75 with diabetes',
}],
});
```
## read / update / delete / search
Same pattern as other resources. Update supports `status`, `title`, `description`, `version`. Search supports `status`, `name`, `title`, `topic` filters.
# Media
Source: https://docs.clinikapi.com/sdk/media
SDK reference for media operations.
# clinik.media
Media (FHIR `Media`) captures images, videos, and audio recordings from clinical encounters. Track diagnostic images, wound photos, ultrasound recordings, and other clinical media.
## create
```ts theme={null}
const { data, meta } = await clinik.media.create(request): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `status` | `string` | Yes | preparation, in-progress, not-done, on-hold, stopped, completed |
| `type` | `string` | No | image, video, audio |
| `modality` | `string` | No | Acquisition equipment type |
| `view` | `string` | No | Imaging view |
| `patientId` | `string` | No | Patient ID |
| `encounterId` | `string` | No | Encounter ID |
| `createdDateTime` | `string` | No | When the media was created |
| `issued` | `string` | No | When the media was issued |
| `operatorId` | `string` | No | Operator Practitioner ID |
| `reasonCode` | `string[]` | No | Reason codes |
| `bodySite` | `string` | No | Body site |
| `deviceName` | `string` | No | Device name |
| `deviceId` | `string` | No | Device ID |
| `height` | `number` | No | Image height in pixels |
| `width` | `number` | No | Image width in pixels |
| `frames` | `number` | No | Number of frames |
| `duration` | `number` | No | Duration in seconds |
| `content` | `object` | Yes | Media content (see below) |
| `note` | `string` | No | Additional notes |
| `basedOn` | `string[]` | No | ServiceRequest/CarePlan IDs |
### Content Object
| Field | Type | Required | Description |
| - | - | - | - |
| `contentType` | `string` | Yes | MIME type (e.g. image/jpeg, video/mp4) |
| `data` | `string` | No | Base64-encoded content |
| `url` | `string` | No | URL to the media |
| `title` | `string` | No | Title of the media |
## Example
```ts theme={null}
const { data } = await clinik.media.create({
status: 'completed',
type: 'image',
patientId: 'pt_abc123',
encounterId: 'enc_visit456',
operatorId: 'prac_dr789',
bodySite: 'Left knee',
height: 1920,
width: 1080,
content: {
contentType: 'image/jpeg',
url: 'https://storage.example.com/images/knee-xray-001.jpg',
title: 'Left knee X-ray — AP view',
},
note: 'Pre-operative imaging for total knee replacement evaluation',
});
```
## read / update / delete / search
Same pattern as other resources. Update supports `status` and `note`. Search supports `patientId`, `status`, `type`, `modality`, `dateFrom`, `dateTo` filters.
# Medication Dispenses
Source: https://docs.clinikapi.com/sdk/medication-dispenses
SDK reference for medication dispense operations.
# clinik.medicationDispenses
Medication Dispenses (FHIR `MedicationDispense`) track the supply of medications to patients — typically by a pharmacy. Use `clinik.prescriptions` for medication orders and `clinik.medications` for drug definitions.
## create
```ts theme={null}
const { data, meta } = await clinik.medicationDispenses.create(request: MedicationDispenseCreateRequest): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `status` | `string` | Yes | preparation, in-progress, cancelled, on-hold, completed, stopped, declined |
| `medication` | `string \| { system?, code, display? }` | Yes | Medication code or name |
| `patientId` | `string` | Yes | Patient ID |
| `encounterId` | `string` | No | Encounter ID |
| `statusReasonCodeableConcept` | `string` | No | Reason for current status |
| `category` | `string` | No | Category of dispense |
| `performer` | `Array` | No | Who performed the dispense |
| `locationId` | `string` | No | Location ID |
| `authorizingPrescriptionIds` | `string[]` | No | MedicationRequest IDs |
| `type` | `string` | No | trial fill, partial fill, emergency fill |
| `quantity` | `{ value, unit? }` | No | Quantity dispensed |
| `daysSupply` | `number` | No | Number of days supply |
| `whenPrepared` | `string` | No | When prepared |
| `whenHandedOver` | `string` | No | When handed over |
| `dosageText` | `string` | No | Dosage instructions |
| `substitution` | `object` | No | Substitution details |
| `note` | `string` | No | Additional notes |
## Example
```ts theme={null}
const { data } = await clinik.medicationDispenses.create({
status: 'completed',
medication: {
system: 'http://www.nlm.nih.gov/research/umls/rxnorm',
code: '197361',
display: 'Lisinopril 10 MG Oral Tablet',
},
patientId: 'pt_abc123',
authorizingPrescriptionIds: ['rx_order456'],
quantity: { value: 30, unit: 'tablets' },
daysSupply: 30,
whenPrepared: '2024-03-15T10:00:00Z',
whenHandedOver: '2024-03-15T14:30:00Z',
dosageText: 'Take 1 tablet daily in the morning',
});
```
## read / update / delete / search
Same pattern as other resources. Update supports `status`, `statusReasonCodeableConcept`, `note`. Search supports `patientId`, `status`, `medication` filters.
# Medication Knowledge
Source: https://docs.clinikapi.com/sdk/medication-knowledge
SDK reference for medication knowledge operations.
# clinik.medicationKnowledge
Medication Knowledge (FHIR `MedicationKnowledge`) provides detailed drug information — dosage forms, ingredients, costs, and packaging. This is a drug reference database, not a prescription or dispense record.
## create
```ts theme={null}
const { data, meta } = await clinik.medicationKnowledge.create(request: MedicationKnowledgeCreateRequest): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `code` | `string \| { system?, code, display? }` | No | Drug code or name |
| `status` | `string` | No | active, inactive (default: active) |
| `manufacturer` | `string` | No | Manufacturer name |
| `doseForm` | `string` | No | Dosage form (tablet, capsule, etc.) |
| `amount` | `{ value, unit? }` | No | Amount of drug in package |
| `synonym` | `string[]` | No | Alternate names |
| `productType` | `string[]` | No | Product types |
| `ingredient` | `Array` | No | Ingredients with strength |
| `preparationInstruction` | `string` | No | Preparation instructions |
| `intendedRoute` | `string[]` | No | Intended routes (oral, IV, etc.) |
| `cost` | `Array` | No | Cost information |
| `packaging` | `object` | No | Packaging details |
### Cost Object
| Field | Type | Required | Description |
| - | - | - | - |
| `type` | `string` | Yes | Cost type (e.g. wholesale, retail) |
| `source` | `string` | No | Source of cost data |
| `cost` | `{ value, currency? }` | Yes | Cost amount |
## Example
```ts theme={null}
const { data } = await clinik.medicationKnowledge.create({
code: {
system: 'http://www.nlm.nih.gov/research/umls/rxnorm',
code: '197361',
display: 'Lisinopril 10 MG Oral Tablet',
},
status: 'active',
doseForm: 'tablet',
manufacturer: 'Teva Pharmaceuticals',
ingredient: [
{
item: { code: '29046', display: 'Lisinopril' },
isActive: true,
strength: {
numerator: { value: 10, unit: 'mg' },
denominator: { value: 1, unit: 'tablet' },
},
},
],
intendedRoute: ['oral'],
cost: [
{ type: 'wholesale', cost: { value: 0.15, currency: 'USD' } },
{ type: 'retail', cost: { value: 0.85, currency: 'USD' } },
],
packaging: { type: 'bottle', quantity: { value: 100, unit: 'tablets' } },
});
```
## read / update / delete / search
Same pattern as other resources. Update supports `status`, `doseForm`, `preparationInstruction`. Search supports `code`, `status`, `doseForm`, `manufacturer` filters.
# Medication Statements
Source: https://docs.clinikapi.com/sdk/medication-statements
SDK reference for medication statement operations.
# clinik.medicationStatements
Medication Statements (FHIR `MedicationStatement`) record what medications a patient is taking or has taken — as reported by the patient, clinician, or other source. Unlike prescriptions, these are informational records, not orders.
## create
```ts theme={null}
const { data, meta } = await clinik.medicationStatements.create(request: MedicationStatementCreateRequest): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `status` | `string` | Yes | active, completed, stopped, on-hold, intended, not-taken |
| `medication` | `string \| { system?, code, display? }` | Yes | Medication code or name |
| `patientId` | `string` | Yes | Patient ID |
| `encounterId` | `string` | No | Encounter ID |
| `statusReason` | `string[]` | No | Reasons for current status |
| `category` | `string` | No | Category (inpatient, outpatient, community) |
| `effectiveDateTime` | `string` | No | When the medication was taken |
| `effectivePeriod` | `{ start?, end? }` | No | Period of medication use |
| `dateAsserted` | `string` | No | When the statement was asserted |
| `informationSourceId` | `string` | No | Who provided the info |
| `reasonCode` | `string[]` | No | Reason codes for taking the medication |
| `dosageText` | `string` | No | Dosage instructions |
| `note` | `string` | No | Additional notes |
| `basedOn` | `string[]` | No | MedicationRequest/CarePlan/ServiceRequest IDs |
| `partOf` | `string[]` | No | Part of other resource IDs |
## Example
```ts theme={null}
const { data } = await clinik.medicationStatements.create({
status: 'active',
medication: 'Metformin 500mg Tablet',
patientId: 'pt_abc123',
category: 'community',
effectivePeriod: {
start: '2024-01-15',
},
dosageText: 'Take 1 tablet twice daily with meals',
informationSourceId: 'Patient/pt_abc123',
reasonCode: ['Type 2 diabetes management'],
note: 'Patient reports good adherence, no side effects',
});
```
## read / update / delete / search
Same pattern as other resources. Update supports `status`, `statusReason`, `note`, `effectiveDateTime`, `effectivePeriod`. Search supports `patientId`, `status`, `medication`, `category` filters.
# Medications
Source: https://docs.clinikapi.com/sdk/medications
SDK reference for medication operations.
# clinik.medications
Medications represent drug definitions — the medication itself, not a prescription or administration. Use `clinik.prescriptions` for medication orders.
## create
```ts theme={null}
const { data, meta } = await clinik.medications.create(request: MedicationCreateRequest): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `code` | `string \| { system?, code, display? }` | Yes | RxNorm, SNOMED CT, or free-text name |
| `status` | `'active' \| 'inactive'` | No | Medication status (default: active) |
| `form` | `string` | No | Dosage form (e.g. "tablet", "capsule", "injection") |
| `manufacturer` | `string` | No | Manufacturer name |
| `amount` | `{ numerator: { value, unit }, denominator: { value, unit } }` | No | Total amount in package |
| `ingredient` | `Array` | No | Active and inactive ingredients |
| `batch` | `{ lotNumber?, expirationDate? }` | No | Batch/lot information |
### Examples
```ts theme={null}
// Simple — free-text name
const { data } = await clinik.medications.create({
code: 'Lisinopril 10mg Oral Tablet',
status: 'active',
form: 'tablet',
});
// Coded — RxNorm
const { data: coded } = await clinik.medications.create({
code: {
system: 'http://www.nlm.nih.gov/research/umls/rxnorm',
code: '197361',
display: 'Lisinopril 10 MG Oral Tablet',
},
status: 'active',
form: 'tablet',
ingredient: [
{
item: {
system: 'http://www.nlm.nih.gov/research/umls/rxnorm',
code: '29046',
display: 'Lisinopril',
},
isActive: true,
strength: {
numerator: { value: 10, unit: 'mg' },
denominator: { value: 1, unit: 'tablet' },
},
},
],
batch: {
lotNumber: 'LOT-2025-001',
expirationDate: '2026-12-31',
},
});
```
## read
```ts theme={null}
const { data, meta } = await clinik.medications.read(id: string): Promise>
```
## update
```ts theme={null}
const { data, meta } = await clinik.medications.update(id: string, request: MedicationUpdateRequest): Promise>
```
```ts theme={null}
await clinik.medications.update('med_abc123', {
status: 'inactive',
batch: { expirationDate: '2025-06-30' },
});
```
## delete
```ts theme={null}
const { data, meta } = await clinik.medications.delete(id: string): Promise>
```
## search
```ts theme={null}
const { data, meta } = await clinik.medications.search(params?: ResourceSearchParams): Promise>>
```
| Parameter | Type | Description |
| - | - | - |
| `status` | `string` | Filter by active/inactive |
| `count` | `number` | Results per page (max: 100) |
| `cursor` | `string` | Pagination cursor |
# Notes
Source: https://docs.clinikapi.com/sdk/notes
SDK reference for clinical note (DocumentReference) operations.
# clinik.notes
## create
```ts theme={null}
const { data, meta } = await clinik.notes.create(request: NoteCreateRequest): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `patientId` | `string` | Yes | Patient reference |
| `authorId` | `string` | No | Practitioner who authored the note |
| `encounterId` | `string` | No | Encounter reference |
| `type` | `NoteType` | No | Type of clinical note |
| `title` | `string` | Yes | Note title |
| `content` | `string` | Yes | Note content (plain text or markdown) |
| `contentType` | `string` | No | MIME type (default: text/plain) |
| `docStatus` | `string` | No | preliminary, final, amended |
| `category` | `string` | No | Category tag |
| `date` | `string` | No | Clinically relevant date |
| `relatesTo` | `Array<{ code, targetId }>` | No | Relationships to other documents |
| `securityLabel` | `Array<{ system?, code, display? }>` | No | Document security tags |
| `authenticatorId` | `string` | No | Who authenticated the document |
| `custodianId` | `string` | No | Organization maintaining the document |
| `servicePeriod` | `{ start?, end? }` | No | Time period of service documented |
| `facilityType` | `string` | No | Kind of facility |
| `practiceSetting` | `string` | No | Clinical specialty |
### Note Types
| Type | Description |
| - | - |
| `progress-note` | Progress note |
| `discharge-summary` | Discharge summary |
| `consultation-note` | Consultation note |
| `history-and-physical` | H\&P |
| `operative-note` | Operative note |
| `procedure-note` | Procedure note |
| `referral-note` | Referral note |
| `transfer-summary` | Transfer summary |
| `other` | Other |
### Relates To Codes
| Code | Description |
| - | - |
| `replaces` | This note replaces the target |
| `transforms` | This note transforms the target |
| `signs` | This note signs the target |
| `appends` | This note appends to the target |
## search / read / update / delete
Same pattern as other resources.
# Nutrition Orders
Source: https://docs.clinikapi.com/sdk/nutrition-orders
SDK reference for nutrition order operations.
# clinik.nutritionOrders
Nutrition orders (FHIR `NutritionOrder`) represent dietary orders for patients — oral diets, supplements, and enteral formulas.
## create
```ts theme={null}
const { data, meta } = await clinik.nutritionOrders.create(request): Promise>
```
| Field | Type | Required | Description |
| - | - | - | - |
| `status` | `string` | Yes | draft, active, on-hold, revoked, completed |
| `intent` | `string` | Yes | proposal, plan, directive, order |
| `patientId` | `string` | Yes | Patient reference |
| `encounterId` | `string` | No | Encounter context |
| `dateTime` | `string` | No | Order date (defaults to now) |
| `ordererId` | `string` | No | Ordering practitioner ID |
| `allergyIntoleranceIds` | `string[]` | No | Allergy references |
| `foodPreferenceModifier` | `string[]` | No | Food preferences |
| `excludeFoodModifier` | `string[]` | No | Foods to exclude |
| `oralDiet` | `object` | No | Oral diet specification |
| `supplement` | `Array