# Healthcare document exchange - IHE, TEFCA, eHealth Exchange

SOAP 1.2, MTOM, WS-Addressing and signed SAML - the stack the IHE profiles mandate for TEFCA, eHealth Exchange and ePA.

The IHE profiles - XDS.b for document submission and retrieval, XCA for cross-community access, XUA for user assertions - underlie the large document-exchange networks: TEFCA and eHealth Exchange in the United States, gematik's ePA in Germany, the Swiss EPD. All of them use the same transport stack, because the IHE volumes mandate it.

## What the profiles mandate {#what-the-profiles-mandate}

| Requirement | Where it comes from | In Zato |
| --- | --- | --- |
| SOAP 1.2 | IHE ITI, Appendix V | The **SOAP version** dropdown |
| MTOM for documents | XDS.b (ITI-41, ITI-43) | The **MTOM** checkbox |
| WS-Addressing headers | IHE ITI, Appendix V | The **WS-Addressing** checkbox |
| A signed SAML assertion naming the requesting user | XUA (ITI-40) | A [WS-Security definition](https://zato.io/docs/dev/soap/security/index.html#saml) in SAML mode with **Sign** |
| TLS, frequently mutual | Each network's participation agreement | The connection's **Security** tab |

## Configuring the connection {#configuring-the-connection}

**Step 1.** Create the SAML definition under **Security** > **WS-Security**: mode **SAML**, the **Issuer** and **Subject** your network agreement assigns, **Sign** enabled, and the **Signing key** with its **Signing certificate chain** in the Crypto material tab.

**Step 2.** Create the outgoing connection under **Connections** > **Outgoing** > **SOAP**, pointing at the responding gateway. In the SOAP tab, set the version to 1.2 and enable both WS-Addressing and MTOM:

**Step 3.** In the Security tab, attach the SAML definition - and when the network requires mutual TLS, fill in the client certificate paths on the same tab.

None of this appears in the service - it submits a document as `bytes` and reads the registry's reply:

```python
request = SOAPMessage()
request.namespace = 'urn:ihe:iti:xds-b:2007'
request.Document = document_bytes

response = self.soap['Document Exchange'].invoke('ProvideAndRegisterDocumentSet', request)

status = response.ProvideAndRegisterDocumentSetResponse.status
```

On the wire, that one call sends a SOAP 1.2 envelope with `wsa:Action` and `wsa:MessageID` headers, a signed SAML assertion in `wsse:Security`, and the document as an MTOM part - all of it added by the platform from the connection's configuration.

## Receiving submissions {#receiving-submissions}

The same profiles apply when you are the repository other systems submit to. Create a channel under **Connections** > **Channels** > **SOAP** with the version set to 1.2 and MTOM enabled for the responses:

The channel accepts multipart submissions of either packaging, resolves the document parts into `bytes`, and provides your service with a dot-accessed payload:

```python
request = self.request.payload

# An MTOM part reads as plain bytes
document = request.Document

response = SOAPMessage()
response.status = 'urn:ihe:iti:2007:ResponseStatusType:Success'

self.response.payload = response
```

The [receiving tutorial](https://zato.io/tutorials/soap/receiving.html) covers the whole channel side, using document submission as its running example.

## Learn more {#learn-more}

- [SOAP integrations](https://zato.io/docs/dev/soap/) - Envelopes, versions and Python objects instead of XML
- [SOAP as Python objects](https://zato.io/docs/dev/soap/python-objects/) - Build requests and read responses with dot access, no schemas
- [SOAP security](https://zato.io/docs/dev/soap/security/) - WS-Security, credentials in the body and client certificates
- [MTOM and SwA attachments](https://zato.io/docs/dev/soap/attachments/) - Binary content out of the envelope and into MIME parts
- [SOAP mandates](https://zato.io/docs/dev/soap/mandates/) - What each national and sector profile requires, and how to meet it
- [SOAP tutorial](https://zato.io/tutorials/soap/calling.html) - Call any SOAP service with Python objects, start to finish
