# HTTP Response

> Learn what an HTTP response is and how servers reply to client requests. Understand response structure, status codes, headers, and body content.

Source: https://howhttpworks.com/glossary/response
Last reviewed: 2026-10-05

> **TL;DR:** An HTTP response is the server's answer to a request: a status code (like `200` or `404`), headers, and usually a body. Read all three. A `202` means the work hasn't finished yet, and a `204` or HEAD response has no body to parse.

## The Three Parts Most People Need First

The status code tells you how the request went. Headers describe the body and how to handle it: type, length, caching, cookies. The body is the payload: HTML, JSON, a file, or an error message.

In HTTP/1.1, these appear as a status line, header lines, a blank line, and any body. HTTP/2 and HTTP/3 send binary frames with a `:status` pseudo-header instead, so there's no literal `HTTP/1.1 200 OK` line on the wire. See [MDN's HTTP messages guide](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Messages).

## A Simple Example

Here's an example HTTP/1.1 response. The JSON is 24 UTF-8 bytes, with no trailing newline:

```http
HTTP/1.1 200 OK
Date: Mon, 05 Oct 2026 12:00:00 GMT
Content-Type: application/json
Content-Length: 24
Cache-Control: private, max-age=60

{"id":42,"name":"Avery"}
```

`private` keeps shared caches like CDNs from storing it. `max-age=60` makes it fresh for 60 seconds, measured against the response's age. That sets how long a cached copy stays fresh; whether anything gets cached at all still depends on the other cache rules.

## Why Responses Matter In Practice

When something breaks, look at the whole response, not just the JSON. A 401 has to carry a `WWW-Authenticate` challenge. A redirect's `Location` tells the client where to go next. `Set-Cookie` asks the browser to store a cookie, subject to browser policy, and JavaScript can't read it as a response header.

```bash
curl -i 'https://example.com/'
curl -L -D - -o /dev/null 'https://example.com/'
```

The second command follows redirects and prints the headers of every response along the way, throwing away the final body.

## Not Every Successful Response Looks The Same

201 means a resource was created. 202 means the server accepted the request for processing, but the work isn't done and could fail. 204 means success with no body. Skip `response.json()` for a 204, a HEAD response, or a 304; there's nothing to parse.

[RFC 9110 §6.4.1](https://www.rfc-editor.org/rfc/rfc9110.html#section-6.4.1) also excludes content from informational responses. A 304 tells the client or cache to reuse the copy it already has instead of sending a new one.

## Good Practical Habit

Fetch resolves normally on HTTP error statuses, so check the status before treating a response as success:

```javascript
const response = await fetch('/api/documents')
if (!response.ok) throw new Error(`HTTP ${response.status}`)
if (response.status !== 204) {
  console.log(await response.json()) // This API promises JSON for content responses.
}
```

If parsing fails on a successful status, compare `response.headers.get('Content-Type')` with the actual body in DevTools. A common culprit is an HTML login page or proxy error page arriving where your API usually returns JSON.

Network and CORS failures are different: Fetch rejects before your code ever gets a readable response. DevTools usually shows more about those failures than JavaScript can see.

## Related

- [Status Code](https://howhttpworks.com/glossary/status-code)
- [CORS](https://howhttpworks.com/guides/cors)
