SOAP vs. REST: What’s the Difference?
SOAP is a messaging protocol; REST is an architectural style. Learn how their contracts, HTTP semantics, caching, tooling and trade-offs differ.

SOAP and REST describe different things. SOAP is a protocol specification for exchanging structured messages. REST is an architectural style for distributed systems. SOAP commonly runs over HTTP, but it is not limited to HTTP. REST commonly uses HTTP, but REST is not the same thing as “JSON over HTTP.”
That distinction answers the headline question, but choosing an approach requires looking at contracts, interaction patterns, HTTP semantics, caching, tooling, security requirements and the systems you must integrate with.
SOAP and REST in one minute
| Axis | SOAP | REST |
|---|---|---|
| What it is | A protocol specification for structured message exchange. | An architectural style defined by constraints. |
| Interface model | Operations and messages, often described with WSDL. | Resources and a uniform interface; the actual design should be checked against REST constraints. |
| Message format | XML envelopes defined by SOAP. | No mandatory format. JSON, XML and other representations can be used. |
| Transport | Often HTTP, but other transports are possible. | Frequently HTTP, with its methods, status codes and caching semantics. |
| Contract tooling | WSDL can describe messages and bindings and support generated clients. | No WSDL requirement; documentation and schemas vary by API. |
| Caching | Not automatic merely because a message uses HTTP. | Cacheability is a REST constraint that can be implemented with HTTP caching. |
The W3C’s Web Services Architecture describes SOAP and WSDL in the web-services context. Roy Fielding’s REST dissertation chapter defines REST’s architectural constraints.
What SOAP actually provides
A SOAP message has a defined XML structure. The envelope identifies the message, an optional header carries processing information, and the body contains the operation request or response. Fault messages provide a standardized place for error details.

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:inv="https://example.com/inventory">
<soap:Header>
<inv:RequestId>abc-123</inv:RequestId>
</soap:Header>
<soap:Body>
<inv:GetStock>
<inv:sku>SKU-42</inv:sku>
</inv:GetStock>
</soap:Body>
</soap:Envelope>
WSDL (Web Services Description Language) can describe the service’s messages, operations, data types and concrete bindings. That explicit contract is useful when several teams or vendors generate clients from the same definition. A SOAP service may also use WS-* specifications for concerns such as addressing, reliable messaging or security, but you must examine the particular service and its configuration; SOAP is not automatically secure or reliable.
Calling a SOAP endpoint with cURL
curl -X POST 'https://api.example.com/Inventory' \
-H 'Content-Type: application/soap+xml; charset=utf-8' \
--data-binary @request.xml
Save the envelope above as request.xml. The endpoint, namespace and authentication headers are service-specific. Some SOAP 1.1 services instead require text/xml and a SOAPAction header, so follow the WSDL and service documentation.
Calling SOAP from Python
import requests
xml = '''<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:inv="https://example.com/inventory">
<soap:Body><inv:GetStock><inv:sku>SKU-42</inv:sku></inv:GetStock></soap:Body>
</soap:Envelope>'''
r = requests.post(
'https://api.example.com/Inventory',
data=xml.encode('utf-8'),
headers={'Content-Type': 'application/soap+xml; charset=utf-8'},
timeout=30,
)
r.raise_for_status()
print(r.text)
What REST actually means
REST is defined by constraints: client-server separation, stateless requests, cacheability, a uniform interface, a layered system and optional code-on-demand. A practical API can use HTTP and JSON while satisfying only some of those constraints. Microsoft’s API design guidance distinguishes ordinary HTTP APIs from an API that strictly follows REST.
REST does not mandate JSON. A resource can be represented as JSON, XML, HTML, a binary document or another media type. The HTTP method and response metadata communicate semantics:
GETretrieves a representation and is normally safe and cacheable.POSTsubmits data or requests processing; repeating it may create another result.PUTreplaces a resource at a known URI and is intended to be idempotent.PATCHapplies a partial modification when the API defines its patch format.DELETEremoves a resource.
Calling a REST endpoint with cURL
curl --fail-with-body 'https://api.example.com/inventory/SKU-42' \
-H 'Accept: application/json'
Calling REST from Python
import requests
r = requests.get(
'https://api.example.com/inventory/SKU-42',
headers={'Accept': 'application/json'},
timeout=30,
)
r.raise_for_status()
stock = r.json()
print(stock)
Calling REST from Node.js
const res = await fetch('https://api.example.com/inventory/SKU-42', {
headers: { Accept: 'application/json' }
});
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
const stock = await res.json();
console.log(stock);
How the interaction models differ
SOAP commonly asks a service to perform a named operation, such as GetStock or SubmitPayment. REST commonly identifies a resource, such as /inventory/SKU-42, and applies a uniform operation to it. Neither pattern guarantees a good design: a SOAP service can expose resources, and an HTTP API can expose RPC-style actions.
REST’s stateless constraint means each request contains the context needed to process it; the server does not rely on conversational session state between requests. Cacheability requires explicit, correct cache behavior in requests and responses. A service that accepts GET but changes data, omits useful cache headers or hides state in a server session is not automatically RESTful.
Contracts, schemas and errors
SOAP’s WSDL gives consumers a formal service description and is often used by code generators. REST has no single required contract language. An API may publish an OpenAPI document, JSON Schema, media-type profiles or human documentation. Evaluate whether your client generators, validation tools and release process support the chosen contract.
SOAP faults have a standard envelope location, but applications still need to interpret fault codes and details. REST APIs usually combine HTTP status codes with an application error representation:
HTTP/1.1 422 Unprocessable Entity
Content-Type: application/problem+json
{
"type": "https://api.example.com/problems/invalid-sku",
"title": "Invalid SKU",
"status": 422,
"detail": "SKU-42 is not active"
}
Do not treat every non-200 response as a transport failure. Define which errors are retryable, how clients correlate requests, and whether a repeated request is safe.
When SOAP is a sensible choice
- Your partner or legacy platform already requires SOAP and WSDL.
- Generated client code from a formal contract reduces integration risk.
- The environment depends on SOAP-specific extensions or message-processing rules.
- You need to preserve an existing service boundary instead of redesigning it.
These are environment requirements, not proof that SOAP is universally more secure, reliable or enterprise-ready. Security depends on authentication, authorization, transport protection, message protection, validation and the threat model.
When REST is a sensible choice
- Resources and standard HTTP methods describe the domain clearly.
- Intermediary caching, conditional requests or normal HTTP observability are useful.
- Clients already have strong HTTP libraries and do not need WSDL-generated code.
- You can define stable representations, status codes, pagination and error formats.
Check the implementation against REST’s constraints before calling it strictly RESTful. Many teams use “REST API” as shorthand for an HTTP API, but the label does not guarantee statelessness, cacheability or a uniform interface.
A practical decision checklist
- List partner and platform constraints. A mandatory WSDL or SOAP gateway usually decides the transport.
- Choose the contract clients need: WSDL, OpenAPI, schemas or another documented format.
- Map the domain. Use resources and HTTP semantics when they fit; use explicit operations when the action cannot be represented clearly as a resource change.
- Define representations, validation rules, authentication, authorization and error bodies.
- Decide retry and idempotency behavior before production. Include request identifiers for diagnosis.
- Design caching deliberately. Set validators and freshness rules only where the data permits it.
- Measure the actual workload. Payload size, serialization, network latency, server code and intermediaries matter more than the label.
Performance, reliability and cost considerations
The supplied sources do not establish a universal performance winner. XML envelopes can add bytes and parsing work, while a poorly designed REST endpoint can make many round trips or return oversized representations. Compare representative payloads, connection reuse, compression, latency, concurrency, cache hit rates and failure behavior in your own environment.
Reliability comes from timeouts, bounded retries with backoff, idempotency, circuit breaking, validation, observability and tested recovery procedures. Neither SOAP nor REST supplies all of these automatically. Cost includes implementation effort, gateway and proxy behavior, generated-client maintenance, payload transfer, compute and operational support.
Common mistakes and troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| HTTP 415 from a SOAP service | Wrong SOAP version or media type. | Check the WSDL; try the required Content-Type and SOAP version. |
| SOAP fault says action is unknown | Missing or incorrect operation namespace, action header or body element. | Generate the envelope from the WSDL and compare namespaces exactly. |
| REST client receives HTML | Wrong route, proxy error or authentication redirect. | Inspect status, Content-Type, final URL and response body before parsing JSON. |
| REST update happens twice after retry | The operation is not idempotent or has no idempotency key. | Use an idempotent method where appropriate or define and send an idempotency key. |
| Cached data is stale | Missing validators or incorrect freshness headers. | Define Cache-Control, ETag and conditional request behavior. |
| Intermittent timeouts | No client timeout, overloaded dependency or slow payload processing. | Set bounded timeouts, collect request IDs and latency data, then tune or isolate the dependency. |
Documenting API behavior with screenshots
When an API guide includes a web console, rendered documentation or a visual regression check, you can capture the page yourself with a browser. A typical Playwright workflow is:
import { chromium } from 'playwright';
const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: 1440, height: 900 } });
await page.goto('https://example.com/docs', { waitUntil: 'networkidle' });
await page.screenshot({ path: 'docs.png', fullPage: true });
await browser.close();
Or skip the browser setup
ScreenshotNeo provides a website screenshot API and MCP server. One GET request returns a PNG, JPEG, WebP or PDF. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups and chat widgets; each step can be turned off. Bot checks, blank pages, timeouts, failed loads and cache hits are not billed, and response headers report the page verdict and billing result.
See the ScreenshotNeo documentation for all options. A minimal call is:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
Options include full-page capture with lazy images loaded, CSS-selector element capture, dark mode, 12 device presets or any viewport, retina scale, PDF paper sizes and margins, custom CSS and JavaScript, clicks, selector or network-idle waits, request blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, selectable cache TTLs, signed links, asynchronous jobs with signed webhooks, bulk capture for 100 URLs per call, a usage API and an OpenAPI specification. An MCP server exposes take_screenshot, get_page_info and capture_pdf to Claude, Cursor and other MCP clients.
There is a free plan with 1,000 screenshots per month and no card. Paid plans start at $5 for 3,000 shots; every feature is available on every plan. Create a free ScreenshotNeo account to start.
FAQ
Is SOAP a REST alternative?
They can solve overlapping integration problems, but they are different categories: SOAP is a protocol specification and REST is an architectural style.

Does REST require HTTP?
REST’s constraints are not the same as HTTP, although most practical REST systems use HTTP. HTTP alone does not make an API RESTful.
Is every JSON API RESTful?
No. JSON is a representation format. REST requires architectural constraints such as statelessness, cacheability and a uniform interface.
Can SOAP use JSON?
SOAP defines XML-based envelopes. A service may carry other data in particular elements, but its SOAP message structure remains XML-based.
Which is faster?
Neither wins universally. Measure the actual payloads, serialization, network path, caching and server implementation.
Should a new API use SOAP or REST?
Start with partner requirements, contract and tooling needs, domain interaction patterns, HTTP semantics, security controls and operational constraints. Choose the style that fits those requirements and document its behavior precisely.
