An API interaction is at its core a question-and-answer game: the application sends a request (say, "give me order 8821"), and the API sends back a response, the requested data or an error message. Per call, there is exactly one round trip.

On the web, this exchange happens over HTTP, the same protocol your browser uses to load web pages. The client (an app or a browser) sends the request, the server responds. The convenient part: request and response are built to the same scheme.

Both messages share the same basic structure: a start line, optional headers (metadata), a blank line, and optionally a body (the payload). The start line and headers together are called the head, the part after it is the body.

Structure of a request

  • Start line (request-line) with three parts: method, request target, and HTTP version. The method (e.g. GET to retrieve, POST to send data) describes the intent. The request target is usually the path, often with a query string appended in the format key=value (e.g. /users?page=2). The version is almost always HTTP/1.1.
  • Headers: metadata as Name: Value lines. Important ones include Host (target domain), Authorization (proof of access, e.g. a token), Content-Type (format of the body, e.g. application/json) and Content-Length (length of the body in bytes).
  • Body (optional): the actual data, e.g. the fields of a form or a JSON object. GET requests typically have no body, POST requests do.

Structure of a response

  • Status line with three parts: HTTP version, status code and an optional reason phrase. The numeric status code indicates success or failure, commonly 200 (OK), 201 (created), 404 (not found) or 302 (redirect). The text after it (e.g. Created) is purely informational.
  • Headers: metadata about the response, such as Content-Type (format of the returned content, usually application/json), Location (URL of a newly created resource), Server, Date or Cache-Control.
  • Body (optional): the returned resource, for APIs usually JSON.

In HTTP/1.x these messages are text-based and readable. From HTTP/2 onward they are packed into binary frames and the version statement is dropped from the message, but the meaning of the parts stays the same. Header names are case-insensitive.

Request
GET /users?page=2 HTTP/1.1
Host: api.example.com
Authorization: Bearer abc123token
Accept: application/json
Response
HTTP/1.1 200 OK
Content-Type: application/json

{
  "page": 2,
  "users": [ { "id": 7, "name": "Anna" } ]
}

GET retrieves existing data, the server responds with 200 OK and the data as JSON.

Request
POST /users HTTP/1.1
Host: api.example.com
Content-Type: application/json
Content-Length: 52

{ "firstName": "Example", "email": "a@example.com" }
Response
HTTP/1.1 201 Created
Content-Type: application/json
Location: http://api.example.com/users/123

{
  "message": "New user created",
  "user": { "id": 123 }
}

POST creates new data, the server responds with 201 Created and the address of the new resource.

Sources

Keep reading