REST API explained: methods, status codes and design basics
A REST API exposes resources at URLs and uses HTTP methods and status codes. See PUT vs PATCH, 401 vs 403 and a tested example, with RFC 9110 definitions.
A REST API is a web service that exposes resources at URLs and lets clients act on them with standard HTTP methods such as GET, POST, PUT and DELETE, with each result reported as a status code such as 200 or 404. REST is an architectural style that Roy Fielding defined in his 2000 dissertation, and in everyday use the term usually means an HTTP API that returns JSON.
What is a REST API, and who defined the REST style?
REST stands for Representational State Transfer. Roy Thomas Fielding introduced it in Chapter 5 of his doctoral dissertation, "Architectural Styles and the Design of Network-based Software Architectures", at the University of California, Irvine, in 2000. He describes it as an architectural style for distributed hypermedia systems, built from these constraints: client-server, stateless, cache, uniform interface, layered system and an optional code-on-demand constraint.
Two of those ideas shape every API. The first is the resource: Fielding writes that any information that can be named can be a resource, such as a document, an image or a collection of other resources. The second is statelessness: each request must contain all the information needed to understand it, which in practice means credentials travel with each request. Fielding notes the cost of this rule, which is that repeated data may be sent in a series of requests.
MDN is direct about everyday usage. HTTP APIs are colloquially called RESTful although they do not necessarily follow all the constraints, and a beginner can take a REST API to mean an HTTP service that can be called with standard web libraries and tools. REST does not require JSON either. Fielding's chapter talks about representations in standard data types, and JSON, defined in RFC 8259 as a lightweight, text-based, language-independent data interchange format, is simply the usual choice.
Which HTTP methods does a REST API use?
A REST API uses the HTTP method to say what to do with the resource at the URL. RFC 9110, the HTTP Semantics standard published in June 2022, calls a method safe when its semantics are essentially read-only, and idempotent when several identical requests have the same intended effect on the server as one. The table follows MDN's classification of the methods.
| Method | What it does | Safe | Idempotent | Cacheable |
|---|---|---|---|---|
| GET | Requests a representation of a resource | Yes | Yes | Yes |
| HEAD | Asks for the same response as GET, without the body | Yes | Yes | Yes |
| OPTIONS | Describes the communication options for a resource | Yes | Yes | No |
| POST | Submits data, often causing a change or side effect | No | No | Only with explicit freshness information |
| PUT | Replaces the resource with the request content | No | Yes | No |
| PATCH | Applies a partial modification | No | No | Only with explicit freshness information |
| DELETE | Deletes the resource | No | Yes | No |
Idempotency matters because of retries. RFC 9110 says an idempotent request can be repeated automatically if the connection drops before the client reads the response, and that a client should not automatically retry a request that is not idempotent. A repeated POST can create two orders. A repeated PUT or DELETE leaves the server in the same state.
What is the difference between PUT and PATCH?
PUT replaces a resource and PATCH changes part of it. RFC 9110 says PUT requests that the target resource be created or replaced with the enclosed representation, and that a server must answer 201 (Created) if PUT created it, or 200 (OK) or 204 (No Content) if it modified an existing one. RFC 5789, which added PATCH in March 2010, describes it as a way to modify part of a resource, because PUT only allows a complete replacement.
PATCH is neither safe nor idempotent under RFC 5789, though a request can be written so that it is idempotent. MDN gives an example: if a resource includes an auto-incrementing counter, a PUT overwrites the counter, since it replaces the whole resource, but a PATCH may not.
What do HTTP status codes mean in a REST API?
The first digit of a status code gives its class. RFC 9110 defines five classes, and a client must treat an unrecognised code as the x00 code of its class, so an unfamiliar 4xx code is handled like a 400.
| Class | Meaning in RFC 9110 | Codes to know |
|---|---|---|
| 1xx Informational | The request was received, continuing process | Not covered here |
| 2xx Successful | The request was received, understood and accepted | 200, 201, 204 |
| 3xx Redirection | Further action is needed to complete the request | Not covered here |
| 4xx Client Error | The request has bad syntax or cannot be fulfilled | 400, 401, 403, 404, 405, 409, 415, 422, 429 |
| 5xx Server Error | The server failed to fulfil an apparently valid request | 500, 503 |
The common codes, in the wording of the standards, are these.
| Code | Name | When an API sends it |
|---|---|---|
| 200 | OK | The request succeeded; the content depends on the method |
| 201 | Created | A resource was created; a Location header identifies it |
| 204 | No Content | The request succeeded and there is nothing to send back |
| 400 | Bad Request | Something looks like a client error, such as malformed syntax |
| 401 | Unauthorized | Valid authentication credentials are missing; a WWW-Authenticate header is required |
| 403 | Forbidden | The server understood the request and refuses to fulfil it |
| 404 | Not Found | No current representation exists, or the server will not disclose it |
| 405 | Method Not Allowed | The method is known but not supported by the resource; an Allow header lists the supported ones |
| 409 | Conflict | The request conflicts with the current state of the resource |
| 415 | Unsupported Media Type | The content type is not one the resource accepts |
| 422 | Unprocessable Content | The syntax is correct but the instructions cannot be processed |
| 429 | Too Many Requests | The client sent too many requests in a given time; Retry-After is optional (RFC 6585) |
| 500 | Internal Server Error | The server hit an unexpected condition |
| 503 | Service Unavailable | The server is temporarily overloaded or in maintenance; Retry-After is optional |
What is the difference between 401 and 403?
A 401 means the server does not know who is asking, and a 403 means the server knows and still says no. RFC 9110 says 401 means the request lacks valid authentication credentials and that the server must send a WWW-Authenticate header. It says 403 means the server understood the request but refuses to fulfil it, and that the client should not repeat it automatically with the same credentials.
MDN puts it in practical terms: with a 403, authenticating again makes no difference, because the failure is tied to application logic such as missing permissions. RFC 9110 also allows a server to answer 404 instead of 403 when it does not want to reveal that a forbidden resource exists.
What does a request and response look like?
A tiny API makes the methods and codes concrete. This Python server, written with only the standard library, supports GET and PUT on /books/<id>.
import json
from http.server import BaseHTTPRequestHandler, HTTPServer
books = {1: {"title": "Clean Code"}}
class Api(BaseHTTPRequestHandler):
def reply(self, status, body=None):
self.send_response(status)
self.send_header("Content-Type", "application/json")
self.end_headers()
if body is not None:
self.wfile.write(json.dumps(body).encode())
def do_GET(self):
book = books.get(int(self.path.split("/")[-1]))
self.reply(200, book) if book else self.reply(404, {"error": "not found"})
def do_PUT(self):
book_id = int(self.path.split("/")[-1])
body = self.rfile.read(int(self.headers["Content-Length"]))
status = 204 if book_id in books else 201
books[book_id] = json.loads(body)
self.reply(status)
HTTPServer(("127.0.0.1", 8000), Api).serve_forever()A client script then calls it five times.
import json
import urllib.error
import urllib.request
def call(method, path, body=None):
data = json.dumps(body).encode() if body else None
req = urllib.request.Request("http://127.0.0.1:8000" + path, data=data, method=method)
try:
with urllib.request.urlopen(req) as r:
print(method, path, r.status, r.read().decode())
except urllib.error.HTTPError as e:
print(method, path, e.code, e.read().decode())
call("GET", "/books/1")
call("GET", "/books/9")
call("PUT", "/books/9", {"title": "Refactoring"})
call("PUT", "/books/9", {"title": "Refactoring"})
call("GET", "/books/9")The output shows the codes from the table at work.
GET /books/1 200 {"title": "Clean Code"}
GET /books/9 404 {"error": "not found"}
PUT /books/9 201
PUT /books/9 204
GET /books/9 200 {"title": "Refactoring"}The first PUT creates book 9 and returns 201. The identical second PUT replaces it with the same content and returns 204. The responses differ but the server ends in the same state, which is what idempotent means.
How do pagination, versioning and error bodies work?
None of these three is fixed by REST itself, so teams follow conventions from named publishers.
For pagination, Microsoft's Azure REST API guidelines say a paginated collection should return a nextLink field holding an absolute URL that the client can GET for the next page, and should document that items may be skipped or duplicated across pages unless the operation takes a snapshot. The standards route is RFC 8288, Web Linking, from October 2017, which defines the Link header and relations such as rel="next".
For versioning, Google's AIP-185 says every Google API must include a major version number as the first part of the URI path for REST APIs and must not expose minor or patch versions. Microsoft's Azure guidelines use an api-version query parameter instead. Both are valid conventions, and a team should pick one and apply it everywhere.
For errors, RFC 9457, Problem Details for HTTP APIs, from July 2023, defines simple JSON and XML formats that describe a problem, so that clients do not have to parse a different error shape for every API.
How does REST compare with GraphQL?
GraphQL is a query language for an API and a server-side runtime for executing queries against a type system that the API defines, according to graphql.org, and its specification was open-sourced in 2015. A REST client picks a URL and a method. A GraphQL client sends a query document that lists the fields it wants.
Over HTTP, a GraphQL server must handle POST for queries and mutations and may accept GET for queries only. The GraphQL documentation notes that GET can help HTTP caching, but long queries can exceed URL length limits set by browsers and CDNs. Neither style is better in general. A client that must choose its own fields is the case GraphQL's query documents address, and resource-shaped data served over plain HTTP caching is the case REST's URLs and methods address.
What are the limits of REST?
REST is a set of trade-offs, and the standards and guidelines above name several.
- Statelessness adds repeated data to requests, as Fielding says.
- The word is used loosely. MDN notes that many HTTP APIs called RESTful skip some constraints, so two APIs with the same label can behave differently.
- Pagination can skip or repeat items when data changes between pages, which Microsoft's guidelines tell teams to document.
- Versioning and error shapes differ between providers, so every new API needs its own reading.
- Status code choices involve judgement. A server may answer 404 instead of 403 to hide a resource, and 400 versus 422 depends on whether the problem is syntax or meaning.
Where do REST APIs show up in the programme?
The Certification in Artificial Intelligence and Machine Learning is an online programme from Vishlesan i-Hub, IIT Patna, delivered on Masai's online platform, that covers Python, machine learning, deep learning, generative AI and LLMs, agentic systems and deploying models to production. Its curriculum lists REST APIs for models and containerised cloud deployment, which is where the methods and status codes above are used to serve a model to other software.
APIs also sit between the services of larger systems, a topic covered in microservices vs monolith, and a small API like the one above can be packaged in a container, as shown in Docker for beginners.
Frequently asked questions
What is a REST API?
A REST API is an HTTP service that exposes resources at URLs and uses standard methods such as GET, POST, PUT and DELETE, with status codes reporting the result. REST is the architectural style Roy Fielding defined in his 2000 dissertation. In everyday use the label usually means an HTTP API that returns JSON.
What is the difference between PUT and PATCH?
PUT replaces the whole resource with the content sent, and it is idempotent. PATCH applies a partial change and is not idempotent by definition, though a request can be written to behave idempotently. RFC 5789 added PATCH in 2010 because PUT allows only complete replacement.
What does a 401 vs 403 status code mean?
A 401 Unauthorized response means valid authentication credentials are missing, and it carries a WWW-Authenticate header. A 403 Forbidden response means the server understood the request and refuses it, so logging in again changes nothing. A server may send 404 instead of 403 to hide that a resource exists.
What does idempotent mean for an HTTP method?
An HTTP method is idempotent when several identical requests have the same intended effect on the server as one request. RFC 9110 lists PUT, DELETE and the safe methods as idempotent. The property allows a client to retry automatically after a dropped connection without creating duplicates.
Does every REST API need to return JSON?
No. Fielding's description of REST talks about representations in standard data types and does not name JSON. JSON, defined in RFC 8259, is the common format because it is lightweight, text-based and language-independent. An API can return XML or other formats and still follow REST's constraints.
When should an API return 404 instead of 403?
RFC 9110 allows a server to answer 404 in place of 403 when it does not want to confirm that a forbidden resource exists. The choice is a design decision. A 403 tells an unauthorised client that the resource is there, while a 404 hides it.
Next step
Calling an API with a script, as above, is the first step towards building and serving one. Learners who want to apply it to machine learning models can read about the Certification in Artificial Intelligence and Machine Learning.