Download the PHP package clinically/laravel-halaxy without Composer
On this page you can find all versions of the php package clinically/laravel-halaxy. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download clinically/laravel-halaxy
More information about clinically/laravel-halaxy
Files in clinically/laravel-halaxy
Package laravel-halaxy
Short Description Laravel SDK for the Halaxy FHIR R4B healthcare API
License MIT
Homepage https://github.com/clinically-au/laravel-halaxy
Informations about the package laravel-halaxy
clinically/laravel-halaxy
A Laravel SDK for the Halaxy FHIR R4B healthcare API.
[!IMPORTANT] This is an independent, unofficial project. It is not affiliated with, endorsed by, or supported by Halaxy. Halaxy is a trademark of its respective owner.
Features
- Fluent resource API for every documented Halaxy endpoint
- FHIR query builder with pagination (
paginate(), lazyall()) - Multi-tenant support with per-tenant OAuth token caching
- AU/EU region switching
- Webhook handling via
spatie/laravel-webhook-clientwith typed events - Typed exceptions for authentication, validation, rate-limit, and server errors
Requirements
- PHP 8.5+
- Laravel 13+
Installation
Publish the configuration:
Set your credentials in .env (created per practice in Halaxy's developer settings):
Usage
Patients
Query Builder
Appointments
Booking uses Halaxy's $book operation, which expects a FHIR Parameters
resource (not a bare Appointment) and creates related resources (invoice,
clinical note) as part of the booking:
Appointments have no writable status field. Cancellation is done by
patching the patient participant's modifierExtension:
Referrals
Halaxy referrals use Halaxy-specific property names rather than the generic
FHIR ServiceRequest names. A Coverage record must already exist. Use the typed
payload to produce coverage, created, active, comment, and attachments:
Halaxy's referral PATCH endpoint only appends attachments. It does not update or replace other referral properties:
Schedules and Slots
Region Switching
Multi-Tenant Usage
Each tenant (e.g. clinic) can use its own Halaxy credentials with isolated OAuth token caching:
Direct Client Access
Available Resources
| Group | Method | Operations |
|---|---|---|
| People | patients() |
find, list, create, update, replace, exportIds |
| People | practitioners() |
find, list, create |
| People | practitionerRoles() |
find, list, create |
| People | organizations() |
find, list, create |
| Scheduling | appointments() |
find, list, book/create, update, findAvailable |
| Scheduling | schedules() |
find, list, create, generateSlots |
| Scheduling | slots() |
find, list |
| Scheduling | healthcareServices() |
find, list |
| Financial | chargeItemDefinitions() |
find, list |
| Financial | coverages() |
find, list, create, update |
| Financial | invoices() |
find, list |
| Financial | invoiceLines() |
find, list |
| Financial | paymentTransactions() |
find, list |
| Financial | referrals() |
find, list, create, addAttachments |
| Financial | referralDefinitions() |
find, list |
| Clinical | documentReferences() |
create |
| Foundations | capabilities() |
get |
| Foundations | searchParameters() |
list |
The SDK deliberately exposes only the operations Halaxy documents — there is
no delete() anywhere because the Halaxy API has no delete endpoint, and
replace() (PUT) exists only on patients.
Halaxy API Quirks
Verified against the live API — worth knowing before you integrate:
- Nothing can be deleted. No resource has a delete endpoint. Records you create (patients, contacts, notes) persist until removed via the Halaxy UI.
- Patient
identifierandactiveare read-only. Identifiers sent on create are silently dropped, so you cannot tag patients for later lookup; store Halaxy patient IDs on your side. Writes toactiveare silently ignored — archiving is UI-only. - PUT replace is destructive. Writable properties omitted from a
replace()payload are removed. Send the complete desired state. - Patient phone values use compact international format. Mobile numbers
use
system=sms,use=mobile; fixed phones usesystem=phonewith ahomeorworkpurpose. Prefer the typedContactPointfactories so invalid payloads fail before an HTTP request is sent. - Appointment status is not directly writable. Book with the
statusparameter; cancel via the participantmodifierExtension(see above). - Polymorphic search parameters need
Type/idvalues. e.g.recipient=Patient/123— a bare ID returns HTTP 422. Some documented patient-scoping parameters are silently ignored by the server; verify filters against a control query before trusting them. - A
User-Agentheader is mandatory. Halaxy's gateway rejects requests without one (HTTP 403). The SDK always sendshalaxy.user_agent. -
Most resources cannot be updated at all. Only
Patient,Coverage,Appointment,ReferralandDocumentReferenceacceptpatch.Practitioner,PractitionerRoleandOrganizationare create-and-search only — aPATCHreturns HTTP 405 with an empty body. The resource classes mirror this by omittingupdate(), so a 405 means something bypassed them viagetClient()->patch(...).Halaxy::capabilities()is the authority: - Only a practice PractitionerRole may author a DocumentReference. Halaxy
keeps two disjoint role namespaces: the practice's own (
PR-…, profilehx-practitioner-role, organizationCL-…) and external referrer roles created through the API (EP-…, profilehx-external-practitioner-role, organizationSP-…). PractitionerRole search returns both, andGET PractitionerRole/EP-…answers 200 — so a caller cannot distinguish them by whether the reference resolves. Naming an external role asauthorfails the create with 404 "Author not found", which reads like a broken reference and is not: the role exists, it is just not an eligible author.authoris optional, so a document whose only known author is an external referrer should be filed with no author rather than misattributed to a practice clinician who did not write it.
Webhooks
The SDK integrates spatie/laravel-webhook-client to receive Halaxy webhooks.
Webhook handling is disabled by default and must be explicitly enabled with a
signing secret. Requests fail closed if the secret is missing.
Halaxy webhook payloads identify which resource changed but not what happened to it, so each event type gets its own endpoint. When creating each webhook in Halaxy (Settings > Integrations > Webhooks), point it at the URL matching its event:
| Halaxy event | Endpoint |
|---|---|
| Patient Create | https://your-app/webhooks/halaxy/patient-created |
| Patient Update | https://your-app/webhooks/halaxy/patient-updated |
| Appointment Create | https://your-app/webhooks/halaxy/appointment-created |
| Appointment Update | https://your-app/webhooks/halaxy/appointment-updated |
| Appointment Delete | https://your-app/webhooks/halaxy/appointment-deleted |
| Invoice Create | https://your-app/webhooks/halaxy/invoice-created |
| Invoice Update | https://your-app/webhooks/halaxy/invoice-updated |
| Invoice Delete | https://your-app/webhooks/halaxy/invoice-deleted |
Set the webhook's "Authentication Header" in Halaxy to your
HALAXY_WEBHOOK_SECRET value.
[!WARNING]
HALAXY_WEBHOOKS_ENABLED=truewithoutHALAXY_WEBHOOK_SECRETrejects every webhook request. Configure the same secret as the webhook's Authentication Header in Halaxy before enabling the endpoints.
Exclude the webhook routes from CSRF verification in bootstrap/app.php:
Run the spatie migration to create the webhook_calls table:
Each endpoint dispatches its typed event — PatientCreated, PatientUpdated,
AppointmentCreated, AppointmentUpdated, AppointmentDeleted,
InvoiceCreated, InvoiceUpdated, InvoiceDeleted — exposing
resourceReference, timestamp, webhookCall, and an ID accessor
(e.g. patientId()). Requests to the base path dispatch the generic
HalaxyWebhookReceived.
Multi-tenant hosts
Disable auto-registration and register the routes inside your own tenant-scoped group:
Point each Halaxy webhook at the tenant URL, e.g.
https://your-app/app/{tenant}/webhooks/halaxy/appointment-created.
For per-tenant secrets, substitute your own validator (and any other
component) in config/halaxy.php:
Entries named halaxy/halaxy-* in a host's published webhook-client.php
are superseded by the package's entries — put overrides in
config/halaxy.php's webhooks block instead.
Error Handling
Every exception extends HalaxyException and carries the status, request
method, request URL and parsed OperationOutcome. Persist
$e->getOperationOutcome() when logging a failure — the one-line message is
often too little to diagnose from later.
isRetryable() says whether repeating the identical request could plausibly
succeed. A 4xx is a verdict on the request, so retrying one only burns
attempts and multiplies noise in your error tracker; 408, 429 and 5xx (bar
501) are worth another go. Use it to fail a queued job fast:
Testing
Integration tests (live API)
The Integration suite exercises the real Halaxy API and is excluded from
composer test. To run it, copy .env.example to .env, add credentials
for a practice with curated test patients, and pin their IDs:
Tests skip cleanly when credentials are absent. Write tests are gated behind
HALAXY_ALLOW_WRITES, only ever touch the pinned test patients, and clean up
after themselves where the API allows (booked appointments are cancelled);
endpoints that would create undeletable records in the practice are skipped
by design — see tests/Integration/UnexercisedWriteEndpointsTest.php.
License
MIT License. See LICENSE for details.
All versions of laravel-halaxy with dependencies
illuminate/cache Version ^13.0
illuminate/contracts Version ^13.0
illuminate/http Version ^13.0
illuminate/support Version ^13.0
spatie/laravel-webhook-client Version ^3.4