Manage practice group settings, access tokens, and configuration. Use the access token endpoint to generate short-lived JWTs for Hero Elements.
Hero Health Public API (1.0.0)
The Hero Health Public API enables healthtech partners to integrate with NHS GP practices connected to EMIS Web and TPP SystmOne.
- Patient messaging — Send SMS, email, and NHS App messages on behalf of a practice
- Appointment booking — List available slots, create reservations, and confirm bookings
- Patient management — Register and look up patients via PDS (Personal Demographics Service)
- Webhooks — Subscribe to events such as appointment confirmations and write-to-record outcomes
- Booking & form links — Generate sharable links for patient self-service flows
- Elements — Generate access tokens for embedding pre-built Hero UI components
All endpoints require an x-api-key and x-practice-group-id header. API keys are scoped to specific functionality (messaging, booking, booking links). Contact Hero support to request your key.
Request
Register a patient by tracing them against the NHS Spine via PDS (Personal Demographics Service). Provide an NHS number and date of birth, or alternatively a combination of forename, surname, DOB, and postcode.
If the patient already exists in Hero for this practice group, their existing patient_id is returned. If not found, Hero will create a new patient record using the demographics retrieved from PDS.
Common use case: Call this endpoint before sending a message or creating a booking to obtain the Hero patient_id.
- Mock serverhttps://developer.herohealth.net/_mock/apis/public-api/openapi/v1/patients/register_pds
- Staginghttps://api.staging.htech.app/v1/patients/register_pds
- Productionhttps://api.herohealth.net/v1/patients/register_pds
- curl
- NodeJS
- Ruby
curl -i -X POST \
https://developer.herohealth.net/_mock/apis/public-api/openapi/v1/patients/register_pds \
-H 'Content-Type: application/json' \
-H 'x-api-key: YOUR_API_KEY_HERE' \
-H 'x-practice-group-id: YOUR_API_KEY_HERE' \
-d '{
"dob": "1989-04-11",
"postcode": "string",
"forename": "string",
"surname": "string",
"ehr_partner": "string",
"ehr_partner_id": "string"
}'{ "message": "string", "login_url": "string" }
Request
Create or update a patient based on the data sent. If a patient with matching NHS number and DOB exists for the practice group, it will be updated. Otherwise, a new patient record is created.
Unlike Register Patient via PDS, this endpoint does not perform a Spine lookup — you provide the full patient demographics directly. Use this when you already hold the patient's details and do not need PDS tracing.
- Mock serverhttps://developer.herohealth.net/_mock/apis/public-api/openapi/v1/patients/register
- Staginghttps://api.staging.htech.app/v1/patients/register
- Productionhttps://api.herohealth.net/v1/patients/register
- curl
- NodeJS
- Ruby
curl -i -X POST \
https://developer.herohealth.net/_mock/apis/public-api/openapi/v1/patients/register \
-H 'Content-Type: application/json' \
-H 'x-api-key: YOUR_API_KEY_HERE' \
-H 'x-practice-group-id: YOUR_API_KEY_HERE' \
-d '{
"ehr_partner_id": "string",
"nhs_number": "string",
"dob": "string",
"first_name": "string",
"last_name": "string",
"sex": "Not known",
"title": "Baron",
"landline": "string",
"address_line_1": "string",
"address_line_2": "string",
"address_line_3": "string",
"country": "string",
"postcode": "string",
"town": "string",
"county": "string",
"data_source": "hero",
"caller": "string",
"mobile": "string",
"email": "string"
}'{ "patient_id": "string" }
- Mock serverhttps://developer.herohealth.net/_mock/apis/public-api/openapi/v1/patients/{id}/billing_info
- Staginghttps://api.staging.htech.app/v1/patients/{id}/billing_info
- Productionhttps://api.herohealth.net/v1/patients/{id}/billing_info
- curl
- NodeJS
- Ruby
curl -i -X GET \
'https://developer.herohealth.net/_mock/apis/public-api/openapi/v1/patients/{id}/billing_info' \
-H 'x-api-key: YOUR_API_KEY_HERE' \
-H 'x-practice-group-id: YOUR_API_KEY_HERE'{ "id": "string", "external_billing_id": "string", "insurance": { "insurer": "string", "membership_number": "string", "auth_code": "string" }, "billing_note": "string", "confidential": true }