← All Whitepapers

The Complete Guide to REST API Design Principles

REST API Design Software Architecture HTTP Web Services

Introduction

Representational State Transfer, or REST, is the architectural style that defines how the modern web communicates. It was introduced by Roy Thomas Fielding in his 2000 doctoral dissertation at the University of California, Irvine, titled Architectural Styles and the Design of Network-based Software Architectures. The dissertation was the product of six years of work that Fielding had conducted alongside his involvement in standardizing the Hypertext Transfer Protocol. Fielding co-authored the HTTP 1.0 specification, served as the primary author of HTTP 1.1, contributed to the URI specification, and co-founded the Apache web server project. REST was not an abstract thought experiment. It was a distillation of the architectural principles that had guided the development of the protocols on which the web already ran (Fielding, 2000; oleb.net, 2018).

Despite this origin, REST is among the most widely misunderstood concepts in software engineering. The term has been applied so broadly that, as Fielding himself wrote in a 2008 blog post, most APIs that claim to be RESTful bear little resemblance to the architectural style he described. The gap between what Fielding defined and what the industry practices is significant, and understanding that gap is essential for anyone who designs, builds, or consumes APIs (Fielding, 2008).

This paper examines each of the six constraints that define REST, traces how they have been adopted and departed from in practice, and provides documented examples of how leading API providers implement these principles in their production systems.

I. The Context in Which REST Was Created

To understand REST, it is necessary to understand the problem Fielding was solving. His dissertation was not about how to build APIs on top of HTTP. It was about HTTP itself. Fielding was working within the W3C and IETF working groups that were creating the formal descriptions of the web's three primary standards: URI, HTTP, and HTML. He needed a framework for evaluating design proposals and identifying architectural mismatches before they became codified in standards (Two Bit History, 2020).

REST emerged from that process. Fielding began with what he called the "null style," a system with no constraints at all, and then incrementally added architectural constraints until the resulting style matched the properties he believed a global-scale distributed hypermedia system required. Each constraint introduced specific trade-offs: some improved scalability at the cost of per-request efficiency, others improved portability at the cost of implementation complexity. The final set of constraints represented the architectural style that Fielding believed best supported the web's requirements for scalability, independent evolution, and longevity (Fielding, 2000, Chapter 5).

Fielding originally referred to this style as the "HTTP object model," but renamed it because the original name led people to confuse it with the implementation model of an HTTP server. The name "Representational State Transfer" was chosen to evoke the image of a well-designed web application: a network of pages acting as a virtual state machine, where the user progresses by selecting links (state transitions), and each new page (the next state) is transferred to the client and rendered for use (oleb.net, 2018).

II. The Six Constraints of REST

REST is defined by six architectural constraints. Five are mandatory, and one is optional. The combination of all six produces the set of properties that Fielding identified as essential for a global-scale distributed system: performance, scalability, simplicity, modifiability, visibility, portability, and reliability (Wikipedia, "REST," 2025; REST API Tutorial, n.d.).

1. Client-Server

The first constraint establishes a separation of concerns between the client (the user interface) and the server (the data storage and business logic). By separating these responsibilities, each component can evolve independently. A mobile application can be redesigned without modifying the server, and a server can be migrated to a different database without affecting any client. This constraint improves the portability of the user interface across multiple platforms and simplifies the server components, which in turn improves scalability (Fielding, 2000, Chapter 5).

In practice, this constraint is the most universally followed. The entire modern web and mobile ecosystem operates on a client-server model. Every API call from a mobile application to a backend service reflects this separation. Stripe's API, for example, cleanly separates the client-side Stripe.js library (which handles sensitive card data in the browser) from the server-side API (which processes charges, manages subscriptions, and handles payouts). The two components communicate exclusively through well-defined API calls, and either side can be updated without requiring changes to the other (Stripe API Reference, n.d.).

2. Statelessness

The second constraint requires that each request from a client to a server contain all the information necessary for the server to understand and process it. The server must not store any session state between requests. Every request is self-contained, and the server treats each one as an independent transaction (Fielding, 2000, Chapter 5).

Statelessness provides three direct benefits. It improves visibility because a monitoring system can understand any individual request in isolation, without needing to reconstruct a session history. It improves reliability because the failure of one server does not destroy session state that another server cannot reconstruct. And it improves scalability because the server does not need to manage, store, or synchronize session data across a cluster of machines (Red Hat, 2025).

The trade-off is that statelessness can reduce per-request efficiency. Because the client must include all necessary context with every request, some data is transmitted repeatedly. Fielding acknowledged this cost but argued that the scalability and reliability benefits outweigh it for systems operating at web scale (Fielding, 2000, Chapter 5).

Stripe implements statelessness rigorously. Every API request includes an API key for authentication, and the request body contains all the parameters needed to execute the operation. There is no concept of a server-side session. A request to create a charge includes the amount, currency, customer identifier, and payment method, all within a single self-contained call. This design allows Stripe to distribute requests across any available server without affinity requirements (Stripe API Reference, n.d.).

3. Cacheability

The third constraint requires that responses from the server explicitly indicate whether they are cacheable or not. When a response is cacheable, the client (or an intermediary such as a CDN or proxy) can store the response and reuse it for equivalent future requests, eliminating the need to contact the server again. This reduces user-perceived latency, decreases server load, and improves overall network efficiency (Fielding, 2000, Chapter 5).

Fielding considered caching one of the most important constraints for performance. He wrote that the most efficient network request is one that does not use the network at all. HTTP provides built-in mechanisms for cache control through headers such as Cache-Control, ETag, and Last-Modified. A well-designed REST API uses these headers to give clients and intermediaries the information they need to cache responses appropriately (REST API Tutorial, n.d.).

GitHub's REST API provides a practical example. API responses include ETag headers, and clients can send conditional requests using the If-None-Match header. If the resource has not changed, the server returns a 304 Not Modified response with no body, saving bandwidth and processing time. GitHub explicitly documents that conditional requests that receive a 304 response do not count against the API's rate limit, creating a direct incentive for clients to implement caching (GitHub REST API Documentation, n.d.).

4. Uniform Interface

The fourth constraint is what Fielding identified as the central feature that distinguishes REST from other network-based architectural styles. The uniform interface requires that the interaction between clients and servers follow a standardized, generic contract that is independent of any specific application domain. This constraint simplifies the overall architecture, improves the visibility of interactions to intermediaries, and decouples implementations from the services they provide, allowing each to evolve independently (Fielding, 2000, Chapter 5).

The uniform interface is further defined by four sub-constraints. The first is identification of resources: every resource in the system is identified by a URI. The second is manipulation of resources through representations: when a client holds a representation of a resource (such as a JSON object), that representation contains enough information for the client to modify or delete the resource. The third is self-descriptive messages: each message includes enough metadata (such as media type and cache control headers) for the recipient to understand how to process it. The fourth is hypermedia as the engine of application state, commonly abbreviated as HATEOAS: the server's response includes hyperlinks that tell the client what actions are available and what states it can transition to next (Fielding, 2000, Chapter 5; REST API Tutorial, n.d.).

The first three sub-constraints are widely implemented across the industry. Stripe uses resource-oriented URLs (/v1/charges, /v1/customers) where each URL identifies a specific resource or collection. Responses are returned as self-descriptive JSON objects with consistent structure. Twilio follows the same pattern, with resources such as /Accounts/{AccountSid}/Messages identified by URIs and manipulated through standard HTTP methods (Stripe API Reference, n.d.).

The fourth sub-constraint, HATEOAS, is where theory and practice diverge most sharply. In Fielding's model, a REST client should need only an initial URI and knowledge of standardized media types. From that starting point, every available action should be discoverable through hyperlinks embedded in the server's responses. The client should never need to construct URLs from documentation or hardcode endpoint paths. In practice, almost no major commercial API implements HATEOAS in this manner. Most APIs rely on external documentation (often in OpenAPI format) that clients consult to understand available endpoints and expected request structures (Florian Kraemer, 2025; BCS, 2023).

GitHub's API is one of the few that provides hypermedia-style links in its responses, including pagination links and related resource URLs. However, even GitHub's implementation is partial: clients still rely on documentation to understand the structure of requests and the meaning of response fields. The industry has, broadly, adopted the resource-oriented and self-descriptive aspects of the uniform interface while largely setting aside the hypermedia constraint (htmx.org, n.d.).

5. Layered System

The fifth constraint allows the architecture to be composed of hierarchical layers, where each component cannot see beyond the layer with which it is directly interacting. A client cannot know whether it is connected directly to the origin server or to an intermediary such as a load balancer, cache, or security gateway. This constraint enables the insertion of shared infrastructure components (CDNs, firewalls, authentication proxies) without requiring any changes to clients or servers (Fielding, 2000, Chapter 5).

This constraint is so foundational to modern infrastructure that it is taken for granted. Every API that operates behind a content delivery network, API gateway, or load balancer is relying on the layered system constraint. When a request to Stripe's API passes through Cloudflare's network, through Stripe's API gateway, and then to an application server, none of those intermediary layers are visible to the client. The client interacts with a single URL and has no knowledge of the layers behind it (Red Hat, 2025).

6. Code on Demand (Optional)

The sixth constraint is the only optional one. It allows a server to extend the functionality of a client by transferring executable code, such as JavaScript. This constraint enables thin clients that can be customized after deployment. The web browser is the clearest example: when a browser loads a web page, the server can include JavaScript that extends the browser's capabilities for that specific application (Fielding, 2000, Chapter 5).

In the API context, code on demand is rarely invoked directly. However, it has an indirect analogue in the practice of providing client libraries. When Stripe publishes its server-side SDKs for Ruby, Python, Node.js, Java, and other languages, it is effectively distributing code that extends the client's ability to interact with the API. While this is not code on demand in the strict sense that Fielding described (the code is downloaded and installed before use, not transferred at runtime), it reflects the same principle: the server-side provider supplies executable logic that reduces the complexity of client implementation (EBSCO Research, n.d.).

III. The HATEOAS Gap: Where Theory and Practice Diverge

The divergence between Fielding's REST and the industry's REST is most visible in the treatment of HATEOAS. In 2008, Fielding published a blog post titled "REST APIs must be hypertext-driven," in which he expressed frustration with the widespread misuse of the term REST. He wrote that if the engine of application state is not being driven by hypertext, the interface in question is not RESTful and is not a REST API. He described a specific example, the SocialSite REST API, as being so thoroughly coupled that it was functionally an RPC interface masquerading under the REST label (Fielding, 2008).

The practical reality is that most modern "REST APIs" operate at what the Richardson Maturity Model calls Level 2: they use HTTP methods correctly, they organize endpoints around resources, and they return appropriate status codes. Level 3, which requires HATEOAS, remains largely unimplemented in commercial APIs. The reasons are pragmatic. Implementing HATEOAS requires agreement on hypermedia formats (such as HAL, JSON-LD, or Siren), and no single standard has achieved universal adoption. Client developers, for their part, tend to prefer consulting API documentation and constructing URLs directly rather than parsing hyperlinks from server responses (BCS, 2023; htmx.org, n.d.).

Fielding addressed this tension directly. He explained that the strictness of REST's constraints was intentional and that REST was designed for software longevity and independent evolution over decades, not for short-term efficiency. He acknowledged that many of the constraints are directly opposed to short-term efficiency, but argued that the long-term benefits justify the costs. The industry, operating under different time horizons and incentive structures, has largely chosen the short-term efficiency path (Wikipedia, "HATEOAS," 2026).

The result is a pragmatic middle ground. The APIs that dominate the modern landscape are heavily influenced by REST but do not fully implement it as Fielding defined it. An essay on htmx.org captures this succinctly: the meaning of REST has been nearly inverted in common usage, where the term now describes exactly the kind of tightly coupled, documentation-dependent RPC-style APIs that REST was originally designed to replace (htmx.org, n.d.).

IV. How REST Displaced SOAP

REST did not become the dominant paradigm for web APIs immediately. Throughout the early 2000s, SOAP (Simple Object Access Protocol) was the established standard for enterprise web services, backed by Microsoft and IBM and formalized as a W3C recommendation. SOAP provided a highly structured, XML-based messaging framework with built-in support for complex data types, security, and transactional integrity (Wikipedia, "SOAP," 2025).

The shift away from SOAP began in the mid-2000s as a growing community of web developers found SOAP's verbosity and complexity to be at odds with the simplicity they wanted in their APIs. SOAP required XML envelopes, namespaces, schemas, and WSDL (Web Services Description Language) documents. A simple API call that could be expressed in a single HTTP request with a JSON body instead required hundreds of lines of XML configuration under SOAP. Ruby on Rails dropped SOAP support in 2007, and framework creator David Heinemeier Hansson summarized the prevailing sentiment by stating that SOAP was overly complicated (Two Bit History, 2020).

The counter-argument in favor of the simpler approach needed a name, and "REST" became the rallying point. The irony, as Two Bit History documented in a detailed analysis, is that many of the APIs that called themselves RESTful bore little resemblance to Fielding's dissertation. What the industry was actually building was a lighter-weight RPC style that used HTTP methods and JSON payloads. But the label "REST" provided a coherent alternative identity to SOAP, and it stuck (Two Bit History, 2020).

By the early 2010s, REST (in its industry-interpreted form) had become the default architectural choice for new web APIs. Salesforce, which had launched its API as a SOAP service in 2000, added a REST API in 2010. The market followed. According to data from ProgrammableWeb's API directory, the number of publicly available APIs grew from under 1,000 in 2005 to over 10,000 by 2013, and the vast majority of new entries used REST-style architectures (Postman Blog, 2024).

V. REST in Practice: How Leading APIs Implement the Principles

Resource-Oriented URL Design

The most visible REST principle in modern APIs is the organization of endpoints around resources identified by nouns rather than verbs. Stripe's API follows this convention consistently: /v1/customers represents the customer collection, /v1/customers/{id} represents a specific customer, and /v1/customers/{id}/charges represents the charges associated with that customer. The HTTP method (GET, POST, PUT, DELETE) determines the action, and the URL identifies the resource being acted upon. This design means that a developer can often predict the correct endpoint for an operation without consulting documentation (Stripe API Reference, n.d.).

Twilio follows the same pattern. Its API represents accounts, messages, calls, and phone numbers as resources with predictable URL structures. A call record is accessed at /Accounts/{AccountSid}/Calls/{CallSid}. The consistency of this pattern across different resource types reduces the cognitive load on developers integrating with the API.

HTTP Method Semantics

REST-aligned APIs use HTTP methods according to their defined semantics. GET retrieves a resource without side effects. POST creates a new resource. PUT replaces a resource entirely. PATCH modifies a resource partially. DELETE removes a resource. Critically, GET, PUT, and DELETE are defined as idempotent, meaning that calling them multiple times produces the same result as calling them once. POST is not inherently idempotent, which is why it requires special handling in systems where duplicate requests could cause harm (Strapi, 2025).

Stripe has invested considerable engineering effort into making POST requests safe for retries. Because a duplicate POST to /v1/charges could result in a customer being charged twice, Stripe implemented an idempotency key system. Clients include a unique value in the Idempotency-Key header with each POST request. The server stores the result of the first request associated with that key, and subsequent requests with the same key return the stored result without executing the operation again. This design allows clients to safely retry any failed request without risking duplicate side effects (Stripe Blog, "Idempotency," 2017; Stripe API Reference, n.d.).

Versioning

API versioning is a practical necessity that Fielding's dissertation did not directly address. Fielding later commented that a "v1" in an API URL indicates RPC-style design rather than REST, because a properly RESTful API should achieve evolvability through hypermedia rather than versioning. The industry has largely set that view aside and adopted versioning as a core practice (Andreas Reiser, Medium, 2018).

Stripe's versioning system is one of the most sophisticated in the industry. Rather than using traditional URL-path versioning (/v1/ vs. /v2/), Stripe implements rolling date-based versions (such as 2024-11-20). When a user first makes an API request, their account is pinned to the current version. All subsequent requests are processed against that version unless the client explicitly overrides it with a Stripe-Version header. Backwards-incompatible changes are encapsulated in modular "version change" modules that can transform responses between versions. This system allows Stripe to make significant changes to its API while maintaining compatibility with existing integrations (Stripe Blog, "API Versioning," 2017).

GitHub uses a different approach, placing the version in the URL path (/v3/) and in the Accept header (application/vnd.github.v3+json). Both approaches solve the same fundamental problem: allowing the API to evolve without breaking existing clients.

Error Handling

REST-aligned APIs use HTTP status codes to communicate the result of an operation. The 2xx range indicates success, 4xx indicates a client error, and 5xx indicates a server error. Within each range, specific codes carry precise meaning: 200 for a successful retrieval, 201 for a successful creation, 400 for a malformed request, 401 for an authentication failure, 404 for a missing resource, and 429 for rate limiting.

Stripe extends this convention with structured error objects in the response body. Every error response includes a type field (such as card_error, api_error, or invalid_request_error), a human-readable message, and a machine-readable code that allows clients to react programmatically. This combination of standard HTTP status codes with detailed error payloads gives clients both a quick signal for automated handling and enough detail for debugging (Stripe Documentation, "Error Handling," n.d.).

Pagination

For endpoints that return collections, REST-aligned APIs implement pagination to avoid transferring unbounded data sets. Stripe uses cursor-based pagination, where the response includes a has_more boolean and a starting_after parameter that accepts the ID of the last object in the current page. This approach is more performant and more stable than offset-based pagination, because it is not affected by insertions or deletions that change the total count between requests.

GitHub's API supports both page-based pagination (using page and per_page query parameters) and cursor-based pagination for its GraphQL API. For its REST API, GitHub includes Link headers in paginated responses that provide URLs for the first, last, next, and previous pages. This is one of the closest implementations to HATEOAS-style navigation in a major commercial API, because the client discovers the next page URL from the response itself rather than constructing it from documentation (GitHub REST API Documentation, n.d.).

VI. Common Misapplications of REST

The flexibility of REST's principles has led to several patterns that violate the spirit of the architecture while claiming adherence to it. Recognizing these patterns is important for any API designer aiming for genuine alignment with REST principles.

Verb-Oriented URLs

One of the most common violations is the use of verbs in URL paths, such as /getUser or /createOrder. In a REST-aligned API, the URL identifies the resource (the noun), and the HTTP method specifies the action (the verb). A properly designed endpoint uses GET /users/{id} rather than GET /getUser?id=123. The verb-oriented pattern is functionally an RPC call over HTTP, which is precisely the style that REST was designed to move away from (Strapi, 2025).

Session State on the Server

APIs that require clients to "log in" and then use a server-managed session token violate the statelessness constraint. In a stateless design, every request contains its own authentication credentials (typically an API key or a bearer token from an OAuth flow). The server does not maintain a session; it validates the credentials on every request independently. Fielding specifically identified the embedding of session information in URIs as a REST violation that negatively affects shared caching and server scalability (Wikipedia, "REST," 2025).

Ignoring HTTP Status Codes

Some APIs return a 200 status code for every response, including errors, and embed the actual success or failure status in the response body. This violates the self-descriptive message constraint because intermediaries (caches, load balancers, monitoring systems) rely on HTTP status codes to understand the nature of the response. An error response with a 200 status code will be cached by intermediaries that should not cache it, and will not trigger error-handling logic in monitoring systems that depend on standard status codes.

VII. REST in the Context of Modern Alternatives

REST remains the dominant paradigm for public-facing APIs, but it is no longer the only serious option. GraphQL, open-sourced by Facebook in 2015, provides an alternative model where the client specifies exactly what data it needs in a single query. This eliminates the over-fetching and under-fetching problems that arise when REST endpoints return fixed data structures. gRPC, open-sourced by Google in 2015, uses HTTP/2 and Protocol Buffers for high-performance binary communication, making it well suited for internal microservice communication where performance matters more than human readability (Wikipedia, "GraphQL," 2025; Koyeb, n.d.).

The emergence of these alternatives has clarified where REST is strongest and where it is weakest. REST excels in public-facing APIs where broad compatibility, human readability, and cacheability are priorities. Its reliance on standard HTTP semantics means that any HTTP client in any programming language can consume a REST API without specialized tooling. GraphQL excels in scenarios where the client needs fine-grained control over data retrieval, particularly in mobile applications where bandwidth is limited. gRPC excels in internal service-to-service communication where low latency and type safety are more valuable than human readability.

Rather than viewing these as competing technologies, the current industry consensus treats them as complementary tools. Many organizations use REST for their public APIs, GraphQL for their client-facing data layer, and gRPC for internal service communication. The choice depends on the specific requirements of the use case, not on a universal preference for one paradigm over another.

Conclusion

REST as Fielding defined it and REST as the industry practices it are related but distinct. The dissertation describes an architectural style optimized for the long-term health of a global-scale distributed hypermedia system. The industry has adopted the parts of that style that provide immediate, practical value (client-server separation, statelessness, resource-oriented URLs, HTTP method semantics, cacheability, and layered architecture) while largely setting aside the most theoretically demanding constraint (HATEOAS).

This is not inherently wrong. Fielding himself noted that REST was designed for a specific class of system, and he acknowledged that not every API needs to implement every constraint to be useful. The important thing is to understand what the constraints are, what properties they produce, and what trade-offs are involved in following or departing from them. An API designer who deliberately chooses to omit HATEOAS because the expected client base does not benefit from it is making a defensible engineering decision. An API designer who omits it because they have never read the dissertation is operating with an incomplete understanding of the tools at their disposal.

The principles that Fielding articulated in 2000 remain the foundation on which the vast majority of web APIs are built. Understanding them fully, including the parts the industry has chosen to set aside, is essential for anyone who wants to design APIs that are scalable, evolvable, and built to last.

Sources Cited

BCS, The Chartered Institute for IT. "Hypermedia Controls in REST: The Final Hurdle." October 11, 2023. https://www.bcs.org/articles-opinion-and-research/hypermedia-controls-in-rest-the-final-hurdle

EBSCO Research Starters. "Representational State Transfer (Computing)." https://www.ebsco.com/research-starters/architecture/representational-state-transfer-computing

Fielding, Roy Thomas. Architectural Styles and the Design of Network-based Software Architectures. Doctoral Dissertation, University of California, Irvine, 2000. https://ics.uci.edu/~fielding/pubs/dissertation/top.htm

Fielding, Roy Thomas. "REST APIs Must Be Hypertext-Driven." October 20, 2008. https://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven

Florian Kraemer. "Most RESTful APIs Aren't Really RESTful." July 7, 2025. https://florian-kraemer.net/software-architecture/2025/07/07/Most-RESTful-APIs-are-not-really-RESTful.html

GitHub. REST API Documentation. https://docs.github.com/en/rest

htmx.org. "HATEOAS." https://htmx.org/essays/hateoas/

htmx.org. "How Did REST Come To Mean The Opposite of REST?" https://htmx.org/essays/how-did-rest-come-to-mean-the-opposite-of-rest/

Koyeb. "Understanding REST, gRPC, GraphQL, and OpenAPI to Build Your APIs." https://www.koyeb.com/blog/understanding-rest-grpc-graphql-and-openapi-to-build-your-apis

oleb.net. "Roy Fielding's REST Dissertation." 2018. https://oleb.net/2018/rest/

Postman Blog. "Intro to APIs: History of APIs." September 19, 2024. https://blog.postman.com/intro-to-apis-history-of-apis/

Red Hat. "REST Architecture." November 22, 2025. https://www.redhat.com/en/blog/rest-architecture

Reiser, Andreas. "Why HATEOAS Is Useless and What That Means for REST." Medium, February 27, 2018. https://medium.com/@andreasreiser94/why-hateoas-is-useless-and-what-that-means-for-rest-a65194471bc8

REST API Tutorial. "The Six Constraints." https://www.restapitutorial.com/introduction/restconstraints

REST API Tutorial. "What Is REST?" https://restfulapi.net/

Strapi. "RESTful API Design Guide: Principles and Best Practices." 2025. https://strapi.io/blog/restful-api-design-guide-principles-best-practices

Stripe. "APIs as Infrastructure: Future-proofing Stripe with Versioning." August 5, 2017. https://stripe.com/blog/api-versioning

Stripe. "Designing Robust and Predictable APIs with Idempotency." February 22, 2017. https://stripe.com/blog/idempotency

Stripe. API Reference. https://docs.stripe.com/api

Stripe. "Advanced Error Handling." https://docs.stripe.com/error-low-level

Stripe. "Idempotent Requests." https://docs.stripe.com/api/idempotent_requests

Two Bit History. "Roy Fielding's Misappropriated REST Dissertation." June 28, 2020. https://twobithistory.org/2020/06/28/rest.html

Wikipedia. "HATEOAS." Last modified February 2026. https://en.wikipedia.org/wiki/HATEOAS

Wikipedia. "GraphQL." Last modified November 2, 2025. https://en.wikipedia.org/wiki/GraphQL

Wikipedia. "REST." Last modified December 24, 2025. https://en.wikipedia.org/wiki/REST

Wikipedia. "SOAP." Last modified October 17, 2025. https://en.wikipedia.org/wiki/SOAP