NHS Spine

ebMS 2.0 over mutual TLS with NHS party identifiers and CPA ids - England's health messaging backbone.

The Spine is the messaging backbone of health and care systems in England. Its asynchronous exchanges run over ebXML Message Service (ebMS 2.0) - each message a SOAP 1.1 envelope whose header names the sending and receiving parties, the service and the action, with the clinical payloads travelling as MIME parts alongside.

What the Spine mandates

RequirementWhere it comes fromThe Zato block
ebMS 2.0 message structureThe Spine's External Interface SpecificationebXML messaging over an outgoing SOAP connection
NHS party identifiers with a type attributeThe Spine's addressing conventionsfrom_party_type and to_party_type on the call
CPA ids agreed during onboardingThe Spine directorycpa_id on the call
Mutual TLS on the health and social care networkSpine connection agreementsThe connection's Client certificate and Client key

Piecing it together

Step 1. Create the outgoing connection under Connections > Outgoing > SOAP with the message handling service's address. ebMS runs over SOAP 1.1, which is the connection's default version.

Step 2. In the Security tab, set the client certificate and key paths issued for your endpoint - the Spine authenticates message handlers at the TLS layer:

Step 3. The exchange itself is one call - the platform builds the eb:MessageHeader with a fresh message id and timestamp, the eb:Manifest, and the MIME package:

info = EbXMLInfo()
info.from_party = 'my-party-id'
info.from_party_type = 'urn:nhs:names:partyType:ocs+serviceInstance'
info.to_party = 'spine-party-id'
info.to_party_type = 'urn:nhs:names:partyType:ocs+serviceInstance'
info.cpa_id = 'S2001919A2011852'
info.conversation_id = self.cid
info.service = 'urn:nhs:names:services:pdsquery'
info.action = 'QUPA_IN000006UK02'

part = Part()
part.content_id = 'payload-1'
part.content_type = 'application/xml'
part.data = hl7v3_query

ack = self.soap['Spine MHS'].invoke_ebxml(info, [part])

The reply's parsed header comes back with ref_to_message_id pointing at the message it acknowledges - the ebXML page covers the whole call in detail.

Learn more