Skip to main content

Changelog

This page tracks notable, user-facing changes across the Eirly Health platform — the REST API and webhooks, the practitioner portal, and the consumer website. Entries are listed newest-first.

Each entry is tagged with the area it affects:

TagArea
APIThe REST API. Where relevant, the affected version is noted (e.g. API · v1.1.0).
WebhooksWebhook events and delivery.
PortalThe practitioner portal — ordering, results, organisation & member management, branding.
WebsiteThe consumer website — buying tests, viewing results, importing your own results.
API versioning

The API is versioned via the Accept header (see API Versioning). Backwards-incompatible changes to existing response shapes are introduced behind a new version; additive fields may appear on an existing version without a version bump. For the full, always-current contract, see the REST API reference and the interactive Swagger Documentation.

October 2026​

  • API · Results include the laboratory's report as text. GET /v1/results and GET /v1/results/{uuid} have a new report with pit: one entry per message the laboratory sent for the result that included report text, in the order received, each the laboratory's report in PIT format with its line numbers kept. It sits alongside the PDF in resultAttachment, and is the whole result for reports with no individual biomarkers (histology, some serology, breath tests). null for results released before it was collected. Additive; applies to both v1.0.0 and v1.1.0. See The laboratory's report.

  • API · person.dob now arrives as the documented YYYY-MM-DD date, and can be null. Referral and result responses were sending it as a UTC timestamp ("1986-07-11T00:00:00.000Z"); they now send "1986-07-11", on every version. A record with no date of birth returns dob: null, and one with no gender returns gender: "". Those records previously failed to load, or were left out of GET /v1/referrals. See Create Referral.

  • API · Results carry the patient as the laboratory identified them, and keep who they were released to. GET /v1/results and GET /v1/results/{uuid} have a new labPatient: the patient exactly as the laboratory sent them, including their Medicare number when sent, for matching patients to your own records. For a result you released from your incoming results, person is now recorded when you release it and no longer changes if the client's record is edited later. Additive; applies to both v1.0.0 and v1.1.0. See The laboratory's patient.

  • API · Results you release from your incoming results are returned by the API. GET /v1/results and GET /v1/results/{uuid} now include results a laboratory sent to your organisation directly and you released to a client. Their referralUuid and referenceNumber are null, and person is the client you released them to. Before, the list left them out and the single fetch refused them. See Results not ordered through us.

  • API · Webhooks · Every result says how it reached you. Results and the result.* webhook payload have a new provenance: ORDERED, INCOMING, or UPLOADED, which is reserved for results your organisation uploads and not sent yet. Handle all three now. It is not a referral's origin, which is unchanged. The result reference previously described an origin field that was never sent on results; it has been removed. Additive; applies to both v1.0.0 and v1.1.0.

  • API · Results now carry a canonical value, so they can be compared across laboratories. Every biomarker on GET /v1/results and GET /v1/results/{uuid} has a new canonical object: the same result in the biomarker's agreed unit, with a status saying whether it was already in that unit, was converted, or why there is no canonical value. The laboratory's own value, unit and ranges are unchanged. Result biomarkers also gain mostCommonUnit. GET /v1/biomarkers and the biomarkers on GET /v1/tests?include=biomarkers gain canonicalUnit, mostCommonUnit and standardStatus. These are additive and apply to both v1.0.0 and v1.1.0. See Canonical values.

September 2026​

  • API · Manage webhooks over the API. Create, list, update and delete webhooks with POST /v1/webhooks, GET /v1/webhooks, GET/PATCH/DELETE /v1/webhooks/{id}, and list the event names you can subscribe to with GET /v1/webhook-events, so an integration no longer needs someone to set its webhooks up in the portal. Webhooks created either way are the same webhooks. The signing secret is not returned over the API; copy it from Settings > Api Keys. See Webhooks.

  • Webhooks · Webhook changes made over the API are emailed to the people who manage them. When a webhook is created, pointed at a different URL, or deleted with an API key, every owner and every member who can manage webhooks is emailed: which webhook, the old and new URL, its events and when. Pointing a webhook somewhere new redirects every future event, so the people who could undo it are told. The URL never appears in the subject or the inbox preview. Changes made in the portal, and a pause or change of events over the API, don't send one.

  • Webhooks · Saving a webhook is now checked. A webhook URL must use https and must not point at a private or internal address, event names must be ones we send, and an event can be sent to a given URL by only one of your webhooks, since a second would deliver every event twice. These apply in the portal and over the API, and existing webhooks keep working unchanged. In the portal, a refused save now says why instead of showing a generic error. See Rules for every webhook.

  • API · Pathology provider ids use one spelling everywhere. Some multi-word labs reached you under two ids: results that came from a lab's HL7 feed carried the underscore form (douglass_hanly_moir), while the provider catalogue and collection centres used the hyphenated one (douglass-hanly-moir). Everything the API returns now uses the hyphenated form. If you stored the underscore form from an older result, map it by replacing underscores with hyphens.

  • API · Referral lookups no longer fail on some older records. GET /v1/referrals and GET /v1/referrals/{uuid} could return a 500 for a referral with no recorded gender, or with an attached file that could no longer be found. Both now return the referral.

  • Webhooks · referral.issued is delivered immediately. It used to wait for a batch that ran once a minute, so it could arrive up to a minute after the referral was issued. It is now sent as soon as the referral is issued. The referral PDF is always retrievable by the time the event arrives, and events for one referral still arrive in order.

  • API · emailSentAt is null when you deliver the referral yourself. A referral created with emailReferralToCustomer: false reported an emailSentAt time even though no email was sent (the value was the time the referral was issued). It is now null for those referrals, and unchanged for referrals we email.

  • API · The Swagger documentation declares the API version and the real response shapes. "Try it out" had no way to send a version, so it always exercised 1.0.0; every operation now has a version picker for the Accept header. Four endpoints (POST /v1/calculate, GET /v1/referrals, GET /v1/results and GET /v1/bundles) declared a response shape they don't return, and now declare the right one. Generated clients and the developer MCP server both read this document.

  • Webhooks · collection_centres.updated, and changedSince on GET /v1/collection-centres. Subscribe to hear when the collection centre list changes: at most one delivery per weekly refresh, only when something changed, naming the centres created, updated, come back, gone missing or retired. changedSince fetches exactly those, retired centres included, so a copy you keep stays in sync; pass the delivery's ranAt. The centres a delivery names can also be fetched by uuid: GET /v1/collection-centres/{uuid}, or up to 100 at once with ?uuids=. See Collection Centre Events.

  • API · Paging reports the page size it applied, and says what is wrong with a bad paging parameter. On every list endpoint, cursor.count is now the page size the server used; it always read 20 before. A count above an endpoint's maximum is still capped rather than refused, so stop paging when cursor.resultCount is less than cursor.count, not less than the count you sent: comparing with your own value stops after the first page whenever you ask for more than the maximum. A negative count, a sort other than asc/desc, or an unreadable cursor now returns 400 INVALID_PARAMETER with the problem named in errorList, where before it was a 400 with an empty message. Every request that worked before returns the same records. See Pagination.

  • API · Find collection centres with GET /v1/collection-centres. Every collection centre of the labs we work with, about 5,900 across Australia, so you can show a patient where to go once a referral is ordered. Filter by pathology provider, vendor, state, postcode or free-text search (name, venue, street or suburb); search around a patient's location, nearest first with distanceKm, with or without a radius; or load a map viewport. Filters combine, and an unknown parameter or value is rejected rather than ignored. Each centre carries its regular weekly opening hours, parsed into 24-hour local times, where the lab publishes them. See List Collection Centres.

  • API · GET /v1/tests now tells you which tests can be ordered under Medicare. Each test carries a medicareListed boolean, so you no longer have to infer it from testType or discover it by having an order rejected.

    The field says whether we will accept the test in the medicareTests array on an order. It is deliberately not called "eligible": whether a test is Medicare-eligible for a particular patient, and whether it ends up bulk billed, are determined by the collecting laboratory and the patient's circumstances at the time of collection, and the patient may still be charged a gap or the full fee. Sending a test with "medicareListed": false in medicareTests returns INVALID_MEDICARE_TEST. See List Tests.

  • API · Manage Medicare provider records over the API. A new /v1/providers resource lets you register a doctor's provider number, referral details and signature against your organisation without that doctor needing an account with us — create, list, fetch, update and retire. Once a number and signature are on file, that practitioner can order Medicare tests immediately.

    Getting results back is a separate step: POST /v1/providers/{providerNumber}/routing records your attestation that you hold the doctor's authority and queues a request per lab. It sends nothing itself; our team notifies the labs in batches, and you poll GET /v1/providers/{providerNumber} to watch each lab move from NOT_SUBMITTED to PENDING_CONFIRMATION to CONNECTED. Until a lab is CONNECTED, results for that practitioner do not route to you automatically.

    Signatures are PNG only and are returned on read, so you can show a customer what we hold. GET /v1/vendors lists the labs you can request routing from and the ids to name. Records created over the API also appear in the portal under Settings > Result routing. See the Providers reference.

  • API · Error responses are now JSON for clients that send no Accept header. Previously such a request received a plain-text body instead of the documented {error, message, code, errorList} envelope. The status code was always correct; only the body was affected.

  • API · Biomarkers on GET /v1/tests, and a cents-denominated price. GET /v1/tests accepts a new include parameter. Pass ?include=biomarkers and each test carries a biomarkers array listing the biomarkers it is expected to report. Entries have the same shape as GET /v1/biomarkers, so one parser serves both. Tests with no linked biomarkers return an empty array.

    The default response is unchanged, and without the parameter the biomarkers key is absent rather than empty. That keeps the default response at 374 KB instead of 893 KB. include takes a comma-separated list so it can carry more sections later; an unrecognised value returns 400 INVALID_PARAMETER rather than being ignored.

    Each test also carries priceCents, the price as a whole number of cents. The existing price field is in dollars and is unchanged. priceCents is there so you are not doing float arithmetic on money, and so tests agree with POST /v1/calculate, which has always returned cents.

    Additive, on both API versions. A caller that ignores the new fields sees exactly what it saw before. See List Tests.

  • API · Developer MCP server. Point your AI coding assistant at https://mcp.staging.eirly.health/dev/v1 and it answers from this API's real contract: endpoints, request and response shapes, error codes, webhook events and the available tests. The endpoint reference is generated from the deployed API, so it cannot fall behind a release. Public and read-only, with no sign-up and no authentication, and it holds no patient or customer data. See MCP Server.

  • API · v1.1.0 · Bundle visibility on GET /v1/bundles. Each bundle now carries a visibility field, and a new includeUnlisted=true query parameter opts into returning link-only (PRIVATE) bundles alongside the listed (PUBLIC) ones.

    Additive, and the default response is unchanged. Every existing bundle is PUBLIC, so a caller that ignores both continues to see exactly what it saw before. Treat visibility as an open set rather than switching exhaustively on it. See List Bundles.

  • Portal · A provider number belongs to one organisation. Registering a provider number that another organisation already holds is now refused, rather than silently creating a second claim on it. A practitioner working at two practice locations still registers the two distinct numbers Medicare issues them.

  • Website · Shareable result links. A patient can now share chosen biomarkers from a result with any doctor, by link plus a 6-character access code, without the recipient holding an account. They pick the expiry (1 to 30 days), choose whether their name, date of birth and sex travel with it, and can revoke at any time. This sits alongside the existing share-with-an-organisation flow, which is unchanged.

  • Portal · Add and edit clients. A client can be created and corrected directly, rather than only arriving through an order. Gated on the existing Edit clients capability. An identifier that could describe two different people is now refused rather than resolved to one of them.

  • Portal · Owner is protected from Administrators. An Administrator can no longer remove an Owner, demote one, or grant the Owner role. See Roles & Permissions.

  • Portal · Shared with me has moved onto the same list framework as the rest of the portal, with the same search, filtering, sorting and paging.

August 2026​

  • API · v1.1.0 — The IRN is now required on Medicare orders. medicareCardNumber must carry the patient's IRN when medicareTests is present, so 11 digits rather than 10. A 10-digit number on a Medicare order now returns a 400.

    The 10 digits printed across the top of a Medicare card identify the card, and everyone named on it shares them. The IRN — the single digit printed beside each person's name — is the only part that identifies one individual, so an order under Medicare has to carry it to say which person it is for.

    This is a stricter rule on an existing version, not a new version. It changes what is accepted on the way in; no response shape has changed. A commercial order is unaffected: the card number stays optional there and the IRN is not required.

    Medicare card numbers are now checksum validated on every request, so a transposed or mistyped digit returns a 400 instead of being stored. This applies to commercial orders too, where the number is optional but must be valid if sent. See Medicare ordering.

  • API · v1.1.0 — Two validation failures now return a specific error code instead of the generic INVALID_PAYLOAD:

    FailureWasNow
    Medicare card number missing, malformed, or without the IRNINVALID_PAYLOADINVALID_MEDICARE_NUMBER
    orderingPractitioner omitted on a Medicare orderINVALID_PAYLOADMISSING_PROVIDER_NUMBER

    If you branch on the error code, this affects you — a check for INVALID_PAYLOAD on either of those failures will stop matching. The reason was always in errorList; now the code itself carries it, so it no longer has to be read out of the message text.

    Each code is returned when that field is the only problem with the payload. Alongside other validation failures the response stays INVALID_PAYLOAD with every issue listed in errorList, so a caller is never shown one problem while another is hidden. The status is 400 either way.

    These are the same codes the platform already used internally for these conditions, so a failure now has one name wherever you meet it. Other Medicare codes (INVALID_PROVIDER_NUMBER, MISSING_PROVIDER_SIGNATURE, INVALID_MEDICARE_TEST, INVALID_BUNDLE_ID, INVALID_STATUS) are unchanged. See the error codes table.

  • Portal · Website — Patient-initiated result sharing. A patient can share one of their own results with an organisation from their Shared results page — choosing the organisation by email, setting an expiry, and revoking access at any time. Works for both ordered and self-uploaded results. Organisations see these under a separate Shared with me section, gated on its own View shared results capability, distinct from the capabilities covering results the organisation ordered. See Roles & Permissions. Rolling out progressively.

  • Portal — Payouts, Webhooks Log and API Log. Settings now exposes your organisation's payouts, the webhook deliveries we've attempted, and recent API calls made with your credentials — so you can check what your endpoint received, or what a key has been doing, without asking us. Invoices now show the full history along with the date each invoice was paid.

  • Portal — Refreshed lists and tables. Results, Referrals, Clients, Test Bundles, Catalogue, Members, Optimal Ranges, Invoices and Settings now share a common page and table framework — consistent filtering, sorting and paging, referral search, and standardised status badges and notifications.

  • Website — Delete your own uploaded results. A result you uploaded yourself can now be deleted from your own record, along with the upload it came from; any access previously granted to it is withdrawn at the same time. Results from an order are unaffected.

  • Website — Preferred Partner pricing on buy pages. An organisation's Preferred Partner discount now flows through to its public buy pages, in both the displayed price and the amount charged, matching what the organisation is invoiced elsewhere. Where a discounted price can't be confirmed the page falls back to list price.

July 2026​

  • API · v1.1.0 — Medicare ordering. POST /v1/referrals accepts medicareTests to order tests under Medicare with the practitioner's provider number, producing a separate Medicare referral. Every referral response carries a medicare boolean. Ordering a test under Medicare is not a guarantee that the patient pays nothing — eligibility and any gap or full fee are decided by the collecting laboratory at the time of collection. See Medicare ordering.
  • API · v1.1.0 — routingMessage on Medicare referrals. The Medicare referral returned from Create now carries a plain-language summary of whether (and from which labs) the practitioner's results will route back to them automatically. Advisory only — it never blocks the order. null on commercial referrals and on all other endpoints. See the response fields.
  • Portal — Roles and permissions. Organisations now control member access through roles built from individual capabilities, with built-in Owner / Admin / Support / Read-only roles and support for custom ones (Settings → Roles). Medicare ordering is opt-in — no built-in role grants it; create a role with the Order with Medicare provider number capability. Existing members kept the access they had. Note this governs people, not API credentials — an API key authenticates as the organisation and is not limited by any member's roles. See Roles & Permissions.
  • Portal — Medicare result routing. Notify each pathology laboratory that a practitioner is ordering through Eirly, so their Medicare results route back to the right organisation (Settings → Result routing).
  • API · v1.1.0 · Portal — Medicare ordering is now live in production. After rolling out in non-production environments, Medicare ordering via POST /v1/referrals (v1.1.0+) is generally available to all organisations. No API changes are required — order under a registered provider number as documented. See Medicare ordering.
  • API · v1.1.0 · Portal — Medicare provider signatures. Ordering-provider signatures can now be captured when registering a Medicare provider (Settings → Provider Numbers) — a prerequisite for Medicare ordering. The signature dialog was redesigned with a PDF preview.
  • Website — The Import results (bring-your-own results) action moved to the site header and the PDF preview was fixed, making it easier to upload historical lab results.
  • Website — /buy links now route to the dedicated consumer app automatically, plus general buy-page fixes.
  • Portal · Website — One-click cross-app sign-in between the practitioner and consumer apps.

June 2026​

  • API · v1.1.0 · Portal — Medicare ordering. Order Medicare-billed pathology tests alongside commercial tests via POST /v1/referrals, under a registered provider number. The request returns an array of referrals (one commercial, one Medicare) and the patient receives a single email with both referral PDFs. In the portal, provider-address and clinical-notes capture were added and prices are hidden for Medicare items. See Medicare ordering.

  • API — Referral editing & reissue. Update a referral's patient details and metadata via PATCH /v1/referrals/{uuid}; the referral PDF is regenerated automatically.

  • Website · Portal — Bring Your Own (BYO) lab results. Customers can upload, review and confirm their own historical lab results, folded into the Results page.

  • Website — A dedicated consumer app launched, with a personal mode and seamless cross-app session transfer from the practitioner app.

  • API · v1.0.0 · Portal — Address handling improved: postCode is accepted and returned consistently as a string, addressLine2 is optional, and state is captured across verification, settings and payment.

  • API · v1.0.0 — Referral responses are now resilient to imperfect stored data — returned as stored rather than failing the request.

  • Portal — Results status “Pending” renamed to “Lab Processing” and turnaround-time estimates removed; reworked profile verification flow; Knowledge Base link added to the sidebar; branding settings now show image-requirement hints.

  • Website — Account credits are now handled at checkout.

May 2026​

  • API · v1.0.0 · Portal · Website — Lipid risk-target ranges. Result biomarkers now expose additionalRanges for cardiovascular/lipid risk targets (e.g. high-risk cholesterol) alongside the standard reference range, and these are presented correctly to users.
  • Portal — White-label branding support, letting organisations theme their experience.
  • Portal — Organisation webhook configuration and member management are now generally available.
  • Website · Portal — Collection-centre map/finder UX improvements.
  • API — Added a machine-readable GET /llms.txt API description for LLM/agent tooling, and corrected the Swagger docs URL.

April 2026​

  • API · v1.0.0 — New PATCH /v1/referrals/{uuid} endpoint to update a referral.
  • API · v1.0.0 — Results now include resultAttachment, a signed URL to the result PDF.
  • API · v1.0.0 — Referrals and results now include productId and productName.
  • API · v1.0.0 · Portal · Website — Female sex-hormone biomarkers now expose cycle-phase reference ranges via additionalRanges.
  • API · v1.0.0 — Partner discount information is now returned via the API.
  • API (staging) — PUT /v1/referrals/{uuid} generates dummy results so you can exercise the results flow and webhooks end-to-end without a real lab. See Simulate Results.
  • Portal — Ability to store/import results that aren't tied to a referral (foundation for BYO).
  • Website — Support redirecting back to your site when a purchase completes.

March 2026​

  • Portal — Mobile-responsive Referrals, Results, Members and Invitations tables.
  • Portal — Extracted-PDF view for results parsed from lab (HL7) messages.
  • Portal — Staged results now show the referring and consulting doctor and can be sorted by pending biomarkers.
  • Portal — Organisation support email can now be configured.
  • Website — Minimum-age restriction enforced at ordering.

February 2026​

  • Portal — New app shell & navigation redesign.
  • Portal — Organisation member management — invite members and manage roles with an enforced role hierarchy.
  • API · v1.0.0 · Portal — Referral responses now include the full person object (patient name, contact, DOB, gender, address).
  • API · v1.0.0 · Portal — Result biomarkers now include sampleType (e.g. serum, whole-blood).
  • API · v1.0.0 · Portal — Fasting status captured and surfaced on results.
  • Portal · Website — Results page can auto-show optimal ranges.
  • Webhooks — Delivery de-duplication fixed and an event UUID added for idempotency (see Idempotency).

January 2026​

  • Website — New buy pages with customer Stripe details and a revamped checkout, plus an hCaptcha challenge on the buy page.
  • Portal — Organisation-level discounts support.
  • API · v1.0.0 — Referral responses now include referralType (e.g. blood).