REST API Fundamentals: HTTP Methods, Status Codes and JSON Payloads
~13 min read
REST is the dominant style for web APIs: HTTP methods say what ACTION you want, status codes say what HAPPENED, and JSON is the near-universal format for the actual data exchanged.
REST (REpresentational State Transfer) is by far the most common style of API you'll encounter on the web, including virtually every LLM provider's API. Rather than a totally custom protocol for every service, REST reuses the same underlying protocol your browser already speaks — HTTP — and layers a consistent set of conventions on top, so once you understand REST, you can work with almost any REST API using the same mental model.
HTTP methods say what ACTION you want to perform, and they map cleanly onto CRUD (Create, Read, Update, Delete) operations you'd want on any piece of data. GET retrieves data without changing anything (like reading a message — safe to repeat as many times as you want). POST creates something new (like submitting a new order, or in AI APIs, submitting a new prompt to generate a response). PUT (or PATCH for partial updates) modifies something that already exists. DELETE removes something. Using the right method for the right action isn't just convention — it tells caching layers, logging systems, and other developers reading your code exactly what kind of operation is happening, at a glance.
Status codes tell you what HAPPENED, as a 3-digit number in every response, grouped by their first digit. 2xx means success (200 OK is the standard 'it worked' response; 201 Created specifically confirms something new was made). 4xx means the CLIENT made a mistake (400 Bad Request — malformed input; 401 Unauthorized — missing or invalid credentials; 404 Not Found — that endpoint or resource doesn't exist; 429 Too Many Requests — you're being rate-limited, extremely common with LLM APIs under heavy use). 5xx means the SERVER made a mistake (500 Internal Server Error — something broke on their end, not yours). Checking the status code is the very first thing well-written API-calling code does, before even looking at the response body.
JSON (JavaScript Object Notation) is the near-universal format for the actual DATA in REST requests and responses — a simple, human-readable text format built from nested key-value objects, arrays, strings, numbers, booleans, and null, that maps naturally onto data structures in virtually every programming language (Python dicts and lists, specifically, translate to and from JSON almost losslessly). When you send a POST request to an LLM API, the PROMPT and settings (temperature, max tokens, etc.) go in a JSON request body; the generated text and metadata (token counts, finish reason) come back in a JSON response body.
💻 Code example
# Modeling the REST pieces -- HTTP method + JSON body -> status code +
# JSON response -- with a minimal fake HTTP layer (no network needed).
import json
def fake_http_request(method: str, path: str, body: dict = None) -> tuple[int, dict]:
"""Stand-in for a real HTTP call -- returns (status_code, json_body),
exactly the two things every REST response gives you."""
if method == "GET" and path == "/users/42":
return 200, {"id": 42, "name": "Ada"}
if method == "POST" and path == "/completions":
if not body or "prompt" not in body:
return 400, {"error": "Bad Request: 'prompt' is required"}
return 200, {"text": f"Response to: {body['prompt']}", "tokens_used": 12}
if method == "GET" and path == "/users/999":
return 404, {"error": "Not Found"}
return 405, {"error": "Method Not Allowed"}
def call_api(method, path, body=None):
status, response_body = fake_http_request(method, path, body)
print(f"{method} {path} -> {status}")
print(f" body: {json.dumps(response_body)}")
if 200 <= status < 300:
print(" (success -- safe to use response data)")
elif 400 <= status < 500:
print(" (client error -- fix the request)")
return status, response_body
call_api("GET", "/users/42")
call_api("POST", "/completions", body={"prompt": "Say hi"})
call_api("POST", "/completions", body={}) # missing required field -> 400
call_api("GET", "/users/999") # doesn't exist -> 404
💬 Deep Dive with AI
Key points
- •REST reuses standard HTTP with consistent conventions, so the same mental model works across almost every REST API
- •HTTP methods signal the ACTION: GET (read), POST (create), PUT/PATCH (update), DELETE (remove) — mapping onto CRUD operations
- •Status codes signal the OUTCOME: 2xx success, 4xx client-side error (400 bad input, 401 unauthorized, 404 not found, 429 rate-limited), 5xx server-side error
- •Always check the status code before trusting the response body — it's the first thing well-written API-calling code does
- •JSON is the near-universal data format for REST request/response bodies — nested key-value data that maps naturally onto Python dicts and lists