Skip to main content

Webhooks

i-screen sends HTTP POST requests to your configured partner endpoints when specific events occur.

warning

Please contact i-screen with your webhook URLs for both sandbox and production environments before going live.

Verifying webhook requests​

Every webhook request includes an Authorization header:

Authorization: Bearer <Partner's token>

This is the same partner token you use to authenticate to the API (see Authentication), sent by itself, without a practitioner token. Check this header against your known partner token to confirm a request genuinely came from i-screen before processing it.

Event overview​

EventwebhookUri fieldtype in payloadFires fromNotes
Request form is readyformReadyform-readyInvoice settlement, or an order placed via the Partner APIFires once per test, not once per order/invoice. An order or invoice with 3 form-generating tests fires 3 separate form-ready calls, one per test. Test kits never fire this (see caveat below).
Results are readyresultsReadyresults-readyA test's results are marked availableFires once per test, same as above.
Invoice settled notificationinvoiceSettledinvoice-settledAn invoice is paid. This includes invoices you create via POST /invoices — the patient settles it on the practitioner portal's invoice page, and that settlement is what fires the webhookFires once per invoice, consolidating every test under it, whether or not each individual test generated a request form.
Order ready notificationorderReadyorder-readyAn order is placed via the Partner APIFires once per order, consolidating every test under it, same as invoice settled.
Patient link request approvedpatientLinkRequestApprovedpatient-link-request-approvedA patient approves a connection requestFires once per approval.

On type: every event now includes a type field in its payload, so if you point more than one webhookUri.* field at the same receiving endpoint, you can dispatch on type directly rather than inferring the event from payload shape. See the changelog for when this landed.

note

Per-test vs per-order/invoice: formReady and resultsReady operate at the individual test level, so a single order or invoice containing multiple tests can trigger several calls to the same webhook URL, one per test. invoiceSettled and orderReady operate at the order/invoice level instead: regardless of how many tests are in it, or how many of those generated a request form, you get exactly one call with every test listed inside it.

note

A caveat worth knowing if you use the practitioner portal alongside the Partner API for the same practitioner account: the practitioner portal has two separate order-creation paths, a direct-purchase flow and an invoice-payment flow. Only the invoice-payment flow currently sends Request form is ready. This is a practitioner-portal-only gap and does not affect orders placed via the Partner API, which always sends this webhook. We are deciding whether to close this gap; noting it here so it isn't a surprise if you're also watching practitioner-portal activity for the same account.


Request form is ready​

Sent after an invoice is settled or an order is made and a test's request form is available. Called separately for each test, not once per order or invoice. Test kits do not generate request forms and will not trigger this webhook.

note

If an order or invoice contains 3 tests and all 3 generate a request form, you'll receive 3 separate form-ready calls, one per test. If one of those 3 is a test kit, you'll only receive 2. Compare this with Order ready / Invoice settled, which consolidate the whole order or invoice into a single call regardless of how many tests are inside it.

Payload​

ParameterDescription
type stringAlways "form-ready"
invoiceId stringThe invoice's record ID (if referred from an invoice)
orderNumber stringThe order number (if purchased directly)
test.\_id stringThe test's record ID
test.title stringThe test's title
test.requestForm stringThe request form URL
{
"type": "form-ready",
"invoiceId": "6253a3e470f8f41f66b1f1ee",
"test": {
"_id": "610ad1070ae7ef00115c0a25",
"title": "Well Man Check",
"requestForm": "https://iscreen.s3.ap-southeast-2.amazonaws.com/sandbox/requestForms/..."
}
}

Trigger: Settle Invoice (staging only)​

Settles an active invoice, generates tests, and triggers the Request form is ready webhook for each applicable test.

POST /triggers/settle

ParameterRequiredDescription
invoiceId stringYesThe invoice's record ID
curl -X POST https://partner-staging.i-screen.com.au/v1/triggers/settle \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer f3ee05b1e3d140a3b17456fb69d28cd9-5f6a46513aa48d0bf80a04c7d52c9805633070a7803d3bd4"
{ "invoiceId": "6253a3e470f8f41f66b1f1ee" }
note

You can also re-fetch from the tests endpoints to retrieve request form URLs without relying on webhooks.


Results are ready​

Sent when a test's status changes to results-available.

Payload​

ParameterDescription
type stringAlways "results-ready"
testId stringThe test's record ID
patientId stringThe patient's record ID
result objectThe test's result object
attachments arrayThe test's attachments
note

result.doctor (the reviewing doctor's firstName, lastName, qualifications, avatar, title) is only present when a doctor has been assigned to the result.

{
"type": "results-ready",
"testId": "62680e5a183a67d280bf29eb",
"patientId": "624a51c9ca695bf5c7e4b1fc",
"result": {
"segments": [
{
"label": "Male Hormone Panel",
"observations": [
{
"label": "Testosterone",
"description": "Testosterone is an anabolic hormone responsible for bone and muscle strength, as well as mood, energy and sexual function.",
"value": "3",
"units": "nmol/L",
"range": { "min": 10, "max": 35 }
}
]
}
],
"recommendations": [
{
"title": "Optimise your lifestyle",
"category": "heart",
"comment": "<p>Taking steps to improve your diet...</p>"
}
],
"comment": "<p>Congratulations on taking the Male Hormone Check!</p>",
"doctor": {
"firstName": "Raj",
"lastName": "Joshi",
"qualifications": "MBChB, MRCGP, Dip Mtn Med, Dip FIPT, FRGS",
"avatar": "https://d1rhkdlqb7psvs.cloudfront.net/assets/img/doctors/dr-raj-joshi-i-screen.jpg",
"title": "Dr"
},
"retest": { "value": 3, "period": "months" },
"availableDate": "2022-04-27T13:22:23.554Z"
},
"attachments": [
"https://iscreen-dev.s3.eu-west-1.amazonaws.com/attachments/..."
]
}

Trigger: Results Are Ready (staging only)​

Sets a test's status to results-available and triggers the Results are ready webhook.

POST /triggers/results

ParameterRequiredDescription
testId stringYesThe test's record ID
curl -X POST https://partner-staging.i-screen.com.au/v1/triggers/results \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer f3ee05b1e3d140a3b17456fb69d28cd9-5f6a46513aa48d0bf80a04c7d52c9805633070a7803d3bd4"
{ "testId": "622460e7e173b40012c4b51e" }

Invoice settled notification​

Sent after an invoice is settled. All tests under the invoice are consolidated into a single webhook call, regardless of how many tests it contains or how many of them individually generated a request form.

note

This fires for any invoice once it's paid, including ones you create via POST /invoices. Creating an invoice through the API doesn't settle it, the patient does that by paying on the invoice link (practitioner.i-screen.com.au/invoice/:id); that payment is what triggers this webhook.

Payload​

ParameterDescription
type stringWebhook type: invoice-settled
invoiceId stringThe invoice's record ID
tests arrayArray of test objects

Test object

ParameterDescription
_id stringThe test's record ID
title stringThe test's title
requestForm stringRequest form URL (if applicable)
mailerInstruction stringInstruction HTML (if applicable)
{
"type": "invoice-settled",
"invoiceId": "649546568f0a484f80f3aa10",
"tests": [
{
"_id": "649578aba5d3cb61bf81e228",
"title": "Advanced Lipid Check",
"requestForm": "https://iscreen-dev.s3.eu-west-1.amazonaws.com/requestForms/..."
},
{
"_id": "649578aba5d3cb61bf81e259",
"title": "Platinum Health Check - Male",
"requestForm": "https://iscreen-dev.s3.eu-west-1.amazonaws.com/requestForms/...",
"mailerInstruction": "<p>There are two components to the Platinum Health Check...</p>"
},
{
"_id": "649578aba5d3cb61bf81e1fc",
"title": "Iodine Loading Check",
"mailerInstruction": "Your test kit is on its way and you'll receive this in the mail in the next 2-3 business days."
}
]
}

Order ready notification​

Sent after a direct purchase order is made. All tests under the order are consolidated into a single webhook call, regardless of how many tests it contains or how many of them individually generated a request form.

Payload​

ParameterDescription
type stringWebhook type: order-ready
orderNumber stringThe order number
tests arrayArray of test objects (same structure as invoice settled)
{
"type": "order-ready",
"orderNumber": "ORD067921",
"tests": [
{
"_id": "662dfc945d7cd6e3bcc2eab2",
"title": "Vitamin B12 Check",
"requestForm": "https://iscreen-dev.s3.eu-west-1.amazonaws.com/staging/requestForms/..."
},
{
"_id": "662dfc945d7cd6e3bcc2eac7",
"title": "Biological Age Check",
"mailerInstruction": "<p>Your test kit is on its way...</p>"
}
]
}

Sent when a patient approves a connection request created via POST /patients/link-requests. Configure this event's URL separately via webhookUri.patientLinkRequestApproved on your partner record.

There is no rejection webhook. If a patient does not respond, the link request simply expires after 7 days; no webhook is sent for expiry.

Payload​

ParameterDescription
type stringAlways "patient-link-request-approved"
linkRequestId stringThe link request's record ID
patientId stringThe patient's record ID, now available to your practitioner
practitionerId stringYour practitioner's record ID
status stringAlways approved
approvedAt stringWhen the patient approved
{
"type": "patient-link-request-approved",
"linkRequestId": "610ad2a60ae7ef00115c0aa3",
"patientId": "610ad1070ae7ef00115c0a25",
"practitionerId": "6253a3e470f8f41f66b1f1ee",
"status": "approved",
"approvedAt": "2026-08-01T02:00:00.000Z"
}

See What happens when a patient approves for the side effects on the patient's account when this fires.

Approving a link request normally requires the patient to click a link in an email and log in to their own i-screen account. Since a sandbox patient may not have real i-screen credentials, this trigger performs the same approval and fires the same webhook, without needing the patient to act.

POST /patients/link-requests/:linkRequestId/simulate-approval

URL Parameters​

ParameterDescription
linkRequestIdThe link request's record ID

No request body is required.

curl -X POST https://partner-staging.i-screen.com.au/v1/patients/link-requests/610ad2a60ae7ef00115c0aa3/simulate-approval \
-H "Authorization: Bearer f3ee05b1e3d140a3b17456fb69d28cd9-5f6a46513aa48d0bf80a04c7d52c9805633070a7803d3bd4"

Response

{
"success": true,
"message": "Acme Health successfully linked to this patient."
}

If the request has already expired, you'll get a 400 Bad Request. If your practitioner is already linked to the patient, success is still true with alreadyLinked: true and no webhook is sent (approval is one-time per patient/practitioner pair).