Part 1: Introduction to SOAP and XML Message Structure
Why I Had to Learn SOAP
I spent the first few years of my career building REST APIs and assumed SOAP was something I could safely ignore. That assumption ended the day I needed to integrate a Python backend with a Danish government tax reporting service. The only API they offered was SOAP. No REST alternative, no JSON, no choice.
I had two options: complain or learn. I chose to learn, and it turned out to be genuinely useful knowledge. Enterprise banking platforms, insurance claim systems, national health record APIs β a large fraction of the world's critical data infrastructure speaks SOAP. Knowing how it works makes you a more capable engineer.
This first part covers what SOAP actually is, how its XML messages are structured, and how to set up a Python environment to start working with it.
What is SOAP?
SOAP (Simple Object Access Protocol) is a messaging protocol for exchanging structured information in distributed systems. It uses XML as its message format and is transport-independent β though in practice, HTTP is by far the most common transport.
SOAP was developed by Microsoft in 1998 and became a W3C standard. At its peak in the mid-2000s, it was the dominant approach for building web services. REST later displaced it for most public-facing APIs, but SOAP never went away from enterprise environments where its formal contract model and built-in security standards are valued features, not bureaucratic overhead.
What SOAP Gives You
Strict contracts: A WSDL file formally defines every operation, message format, and data type. Both sides know exactly what to expect.
Language agnostic: Any language that can produce and parse XML can use SOAP β Python, Java, C#, PHP, and many more.
Transport agnostic: HTTP is standard, but SOAP can run over JMS, SMTP, or TCP.
WS-Security: A message-level security standard for signing, encrypting, and authenticating SOAP messages independent of transport.
Built-in error protocol: SOAP Faults are a standardised way to communicate errors across service boundaries.
SOAP Message Structure
A SOAP message is an XML document. It always has the same outer shell and follows a strict structure.
There are four parts to understand:
1. Envelope
The <soap:Envelope> is the root element. It wraps the entire message and declares the XML namespaces that define which version of SOAP is being used.
SOAP 1.1:
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"SOAP 1.2:
xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
The namespace is how you distinguish SOAP 1.1 from SOAP 1.2 messages.
2. Header
The <soap:Header> element is optional. When present, it carries metadata that is not part of the core business message β things like:
Authentication credentials (WS-Security UsernameToken)
Message routing directives
Timestamps for replay prevention
Transaction identifiers
Custom application headers
3. Body
The <soap:Body> is required and contains the actual payload β the operation request or response.
A request body for an operation that looks up a product might look like:
And the corresponding response:
4. Fault
When something goes wrong, the SOAP body contains a <soap:Fault> element instead of a normal response:
SOAP Faults and their differences between SOAP 1.1 and 1.2 are covered in depth in Part 6.
SOAP 1.1 vs SOAP 1.2
Both versions are in active use. It is common to encounter both in a single integration project. Understanding the differences prevents hard-to-diagnose bugs.
Namespace
http://schemas.xmlsoap.org/soap/envelope/
http://www.w3.org/2003/05/soap-envelope
HTTP Content-Type
text/xml
application/soap+xml
Fault structure
faultcode, faultstring, faultactor, detail
Code, Reason, Node, Role, Detail
WS-I compliance
Requires literal encoding
Native WS-I Basic Profile 1.1
HTTP binding
Separate specification
Part of the core specification
W3C status
Note
Recommendation
In my experience, most legacy enterprise systems use SOAP 1.1. SOAP 1.2 is more common in systems designed after 2007 or systems that explicitly target WS-I compliance.
Communication Styles: RPC vs Document
SOAP supports two communication styles that affect how the body is structured.
RPC Style
RPC (Remote Procedure Call) style treats the web service like a function call. The body element is named after the operation being called, and contains the operation parameters as child elements.
Useful when: You are modelling procedural operations and migrating from traditional RPC systems.
Document Style
Document style (also called message-oriented) sends an arbitrary XML document in the body. The structure is defined entirely by the XSD schema in the WSDL. The body element is not necessarily named after the operation.
Useful when: You are modelling complex business documents (invoices, orders, claims), which is common in B2B integration.
In practice, Document/Literal is the most widely used combination and is the WS-I Basic Profile recommendation. When you encounter a SOAP service in the wild, assume Document/Literal unless you have reason to think otherwise.
SOAP vs REST vs gRPC
Understanding where SOAP fits compared to the alternatives helps you use the right tool.
Message format
XML
JSON (typically)
Protocol Buffers (binary)
Contract
WSDL (mandatory)
OpenAPI (optional)
.proto files (mandatory)
Transport
HTTP, JMS, SMTP, TCP
HTTP only
HTTP/2 only
Security standard
WS-Security (message level)
OAuth 2.0 / API keys (transport)
mTLS, token-based
Streaming
No
No (SSE workaround)
Native bidirectional
Performance
Slower (XML parsing overhead)
Moderate
Fastest
Browser support
Poor
Excellent
Needs proxy
Legacy compatibility
Excellent
Good
None
Enterprise adoption
Dominant in legacy
Dominant in new
Growing
When to choose SOAP
From personal experience, SOAP is the right choice when:
You are integrating with an existing system that only offers a SOAP endpoint (banking, government, ERP, CRM platforms like SAP, Salesforce, older versions)
The integration requires message-level security that is independent of transport (signing and encrypting the XML body itself, not just using TLS)
You need formal, enforceable contracts between organisations β the WSDL acts as a legal specification
You are working in regulated industries where SOAP-based WS-* specifications are mandated (healthcare HL7, financial ISO 20022 transport, insurance)
Your message is a structured business document (invoice, purchase order, claim) rather than a simple CRUD operation
When not to choose SOAP
Building a new public-facing API β REST with OpenAPI is simpler and better understood
Mobile or JavaScript frontends β JSON parsing is far easier
High-performance microservice communication β gRPC's binary format is faster
Teams without XML/WSDL knowledge and no time to learn
Setting Up the Python Environment
I use Python for all examples in this series. The two central libraries are:
zeep β a modern, actively maintained SOAP client. I use this to consume external SOAP services.
spyne β a Python framework for building SOAP services. I use this to build and host SOAP endpoints.
Verify the installation:
Sending Your First SOAP Request
Before building anything, I find it useful to manually construct a raw SOAP message using requests. This removes all abstraction and shows exactly what travels over the wire.
I will use a publicly available SOAP service: http://www.dneonline.com/calculator.asmx β a simple arithmetic calculator offered as a demo service.
The response will be:
This is the complete SOAP request/response cycle. The same thing happens when you use zeep β it just handles building the XML and parsing the response for you.
Notice the SOAPAction header in the request. This is a SOAP 1.1 requirement β the server uses it to route the request to the correct operation handler. SOAP 1.2 uses a different mechanism (the action parameter in the Content-Type header) and does not require SOAPAction.
Parsing a SOAP Response with lxml
When using raw requests instead of zeep, you need to parse the XML response yourself. Here is how to do that with lxml:
In Part 4, zeep handles all of this automatically. But understanding the raw XML structure means you can debug problems that zeep abstracts away.
What's Next
You now understand:
What SOAP is and why it still matters
The four parts of a SOAP message: Envelope, Header, Body, Fault
SOAP 1.1 vs 1.2 differences
RPC vs Document style
How a raw SOAP request works in Python
In Part 2, we look at WSDL β the XML document that formally describes what a SOAP service does, what operations it exposes, and what data types it accepts and returns.
Last updated