# Immunization registries - CDC IIS

SOAP 1.2 over TLS with the submitter's credentials inside the message body, per the CDC WSDL.

U.S. state and city immunization registries expose the interface the CDC publishes for immunization information systems - a small WSDL with `connectivityTest` and `submitSingleMessage`, with HL7 v2 messages such as VXU submissions and QBP queries sent as text inside the SOAP body.

The credentials go in the business message itself, as the first elements of the operation, and not in a SOAP header.

## What the interface mandates {#what-the-interface-mandates}

| Requirement | Where it comes from | In Zato |
| --- | --- | --- |
| SOAP 1.2 | The CDC WSDL's binding | The **SOAP version** dropdown |
| TLS | Registry onboarding agreements | The connection's address and **TLS validation** |
| `username` and `password` as the operation's first elements | The CDC WSDL's message definitions | [Body credentials](https://zato.io/docs/dev/soap/security/index.html#body-credentials) rows |
| One SOAP action per operation | The CDC WSDL | The **SOAP action** field, one connection per operation |

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

**Step 1.** Create a [WS-Security](https://zato.io/docs/security/ws-security.html) definition in UsernameToken mode under **Security** > **WS-Security** to hold the credentials the registry issued, and set the password through its **Change password** link. The definition is only a credentials store here - the values are sent in the body, not in a header.

**Step 2.** Create the outgoing connection under **Connections** > **Outgoing** > **SOAP** with the registry's address and the operation's SOAP action, and set the version to 1.2 in the SOAP tab:

**Step 3.** Attach the definition in the Security tab, then define the body mapping in the Body credentials tab - one row for `username`, one for `password`, in that order:

The service submits HL7 and reads the acknowledgment - the credentials are injected during `invoke`, so they never appear in code or logs:

```python
request = SOAPMessage()
request.namespace = 'urn:cdc:iisb:2014'
request.hl7Message = 'MSH|^~\\&|MYAPP|MYFAC|IIS|STATE|20260115||VXU^V04^VXU_V04|123|P|2.5.1'

response = self.soap['State Registry'].invoke('submitSingleMessage', request)
```

On the wire, the operation element opens with `<username>` and `<password>` in the registry's namespace, followed by the fields the service assigned, as the CDC message definitions prescribe.

## Hosting an IIS-style endpoint {#hosting-an-iis-style-endpoint}

The reverse arrangement - systems submitting immunization messages to you over the same interface - is a SOAP channel under **Connections** > **Channels** > **SOAP**. The service reads the HL7 message through dot access and answers with an HL7 ACK:

```python
request = self.request.payload

hl7_message = request.hl7Message
facility = request.facilityID

response = SOAPMessage()
response.namespace = 'urn:cdc:iisb:2014'
response.acknowledgment = build_hl7_ack(hl7_message)

self.response.payload = response
```

The channel wraps the reply in an envelope of whichever SOAP version the caller used, and a validation error raised by the service - a missing facility, a malformed message - reaches the caller as a fault of the same version.

## 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
