The Structure of a SOAP Message

In order to gain a complete understanding of services-oriented architecture (SOA), one of the basic pieces of knowledge is the structure of a SOAP messages.  At a high level, SOAP is a lightweight protocol for exchange of information in a decentralized, distributed environment.  But that description gives short shrift to the true utility of SOAP, that being the transmission of a request for service between two heterogeneous and networked applications.  In this article, we look at the structure of a SOAP message in great detail, as well as put the SOAP message into the context of the HTTP request.  This second part has to potential to be a fleeting reference, as there is nothing in the SOAP specification that requires that HTTP be the conduit.  However the ubiquity of HTTP has made it the de facto standard for transmission and it will probably be a few years before it is displaced.


For the purposes of this document, SOAP is a Remote Procedure Calling protocol that works over HTTP.

The body of the request is in XML. A procedure executes on the server and the value it returns is also formatted in XML.

Procedure parameters and returned values can be scalars, numbers, strings, dates, etc.; and can also be complex record and list structures.

Request example 

Here's an example of a SOAP request:

POST /examples HTTP/1.1
User-Agent: Radio UserLand/7.0 (WinNT)
Host: localhost:81
Content-Type: text/xml; charset=utf-8
Content-length: 474
SOAPAction: "/examples"




Header requirements 

The format of the URI in the first line of the header is not specified. For example, it could be empty, a single slash, if the server is only handling SOAP calls. However, if the server is handling a mix of incoming HTTP requests, we allow the URI to help route the request to the code that handles SOAP requests. (In the example, the URI is /examples, telling the server to route the request to the "examples" responder.)

A User-Agent and Host must be specified.

The Content-Type is text/xml. The charset may be specified, if not, the default is US-ASCII. Other acceptable charsets are UTF-8 and UTF-16. UTF-8 is recommended for maximum interop. See the note on UTF character encodings, below.

The Content-Length may be specified, if it is, it must be correct.

As with the URI in the first line, SOAPAction is used to route the request to a handler on the server that will respond. It's entirely up to the application to determine how this header element is used. In many implementations the URI and the SOAPAction header will have the same value.

Payload format 

The payload is in XML, a single element.

All the attributes of the are required as shown in the example above.

The must contain a single element, which contains a single element which is the procedure call. The name of the procedure is the name of this element. Note that the procedure name must be a valid XML element name.

The elements contained within the procedure call are the parameters to the procedure. The names of the parameters is significant, the order of the parameters are not. Parameter type is indicated by the xsi:type attribute.

For example, the procedure name could be the name of a file containing a script that executes on an incoming request. It could be the name of a cell in a database table. Or it could be a path to a file contained within a hierarchy of folders and files.

A procedure call may take no parameters, if so, the procedure element must not contain sub-elements.

Scalar values 

The following scalar value types are supported by this subset of SOAP 1.1.

Type value Type Example
xsd:int 32-bit signed integer -12
xsd:boolean a boolean value, 1 or 0 1
xsd:string string of characters hello world
xsd:float or xsd:double signed floating point number -12.214
xsd:timeInstant date/time 2001-03-27T00:00:01-08:00
SOAP-ENC:base64 base64-encoded binary eW91IGNhbid0IHJlYWQgdGhpcyE=


A value can also be a struct, which is specified by an XML element that contains sub-elements. structs can be nested, and may contain any other type, including an array, described below.

Here's an example of a two-element struct:


The names of struct elements are significant, the order of the elements is not.


A value can also be an array, which is specified by an XML element with a SOAP-ENC:arrayType attribute whose value begins with ur-type[, followed by the number of array elements, followed by ].

Here's an example of a four-element array:


The order of array elements is significant, the names of the elements are not.

You can mix types as the example above illustrates.

If the array elements are of a single type, the value of the array element's SOAP-ENC:arrayType specifies the type of the array's sub-elements, for example, SOAP-ENC:arrayType="xsd:int[4]" means an array of four xsd:int elements.

For mixed-type arrays, the SOAP-ENC:arrayType attribute always specifies xsd:ur-type.

For single-type arrays, the xsi:type attribute is optional for array item sub-elements, but its inclusion is recommended.

Null values 

A value can also be a null, which is specified by an XML element with an attribute, xsi:null, whose value is 1 as follows: .

Response example 

HTTP/1.1 200 OK
Connection: close
Content-Length: 499
Content-Type: text/xml; charset=utf-8
Date: Wed, 28 Mar 2001 05:05:04 GMT
Server: UserLand Frontier/7.0-WinNT

         South Dakota



Response format 

Unless there's an error, return 200 OK.

The Content-Type is text/xml.

Content-Length may be specified, if it is, it must be correct.

The body of the response is in XML, a single element.

The must contain a single element, which contains a single element which is the returned value of the procedure.

The single element contained in the has an arbitrary name which must match the name of the procedure that was called, with the word "Response" tacked on to the end of its name. Let's call this element the wrapper for the response. Even this is not the actual value of the response, which is contained in the single optional sub-element of the wrapper and must be a valid parameter.

The namespace of the wrapper element should match the namespace in the request.

If the wrapper has no sub-elements then the procedure did not return a value

Fault example 

HTTP/1.1 500 Server Error
Connection: close
Content-Length: 511
Content-Type: text/xml; charset=utf-8
Date: Wed, 28 Mar 2001 05:06:32 GMT
Server: UserLand Frontier/7.0-WinNT

         Can't call getStateName because there are too many parameters.



Fault format 

If there's an error return 500 Server Error.

The may contain a which must contain two elements, and .

is intended for use by software to provide an algorithmic mechanism for identifying the fault. is intended to provide a human-readable explanation of the fault.

A may not contain both a and a wrapper (returned value).

When to fault 

If you can't process a request, for any reason, you must generate a fault.

Examples of fault conditions include:

1. An element or attribute in a request that is in an XML namespace which has not been declared.

2. A header in the request with a mustUnderstand="1" attribute that you don't understand.

3. A parameter is of a type that you don't support.