What an HTTP response contains
Every HTTP response has a status line, a block of headers and, usually, a body. The status line reports the outcome. Headers describe the body and tell browsers and caches how to handle it, and the body is the content itself: HTML, JSON, an image or nothing at all.
A typical response for an HTML page looks like this:
HTTP/1.1 200 OK
Date: Sun, 25 Oct 2026 09:30:00 GMT
Content-Type: text/html; charset=utf-8
Content-Encoding: br
Content-Length: 18342
Cache-Control: private, no-cache
ETag: "5d8c72a1"
Vary: Accept-Encoding
Set-Cookie: session_id=8f3a2c91; Path=/; Secure; HttpOnly; SameSite=Lax
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
<!doctype html>
<html lang="en">
...The status line
The first line, HTTP/1.1 200 OK, holds the protocol version, a three-digit status code and a reason phrase. Software acts on the code. The reason phrase is a label for humans that clients should ignore, and HTTP/2 and HTTP/3 drop it entirely.
The first digit gives the class: 1xx informational, 2xx success, 3xx redirection, 4xx a problem with the request and 5xx a failure on the server side.
The response headers that matter most
Headers carry the metadata. These are the ones to read first when a page or API behaves unexpectedly:
- Content-Type says what the body is and, for text, its character encoding, such as text/html; charset=utf-8. A wrong value makes browsers mishandle the body, for example by showing HTML as plain text.
- Content-Length gives the body size in bytes, counting the compressed bytes when Content-Encoding is gzip or br. When the server streams a body without knowing its size, HTTP/1.1 sends Transfer-Encoding: chunked instead, and each piece states its own length. HTTP/2 and HTTP/3 frame the body themselves and never use chunked encoding.
- Cache-Control says whether browsers and shared caches may reuse the response. A max-age=3600 directive allows reuse for an hour. With no-cache, a cache may store the response but must check with the server before each reuse, and no-store forbids storing it at all.
- ETag identifies this version of the resource. The browser sends it back in an If-None-Match header, and if nothing changed the server answers 304 Not Modified with no body.
- Set-Cookie asks the browser to store a cookie. Attributes such as Secure, HttpOnly and SameSite limit where it is sent and whether scripts can read it, and each cookie needs its own Set-Cookie line.
- Location gives the URL to go to next. It appears on 3xx redirects and on 201 Created, where it points to the new resource.
- Security headers ask the browser to apply protections. Strict-Transport-Security makes it use HTTPS for future visits, Content-Security-Policy limits where scripts and other resources load from, and X-Content-Type-Options: nosniff stops it guessing the content type.
The response body, and when there is none
The body follows the blank line after the headers, in the format Content-Type declares. Some responses never have one: replies to HEAD requests, 204 No Content, 304 Not Modified and every 1xx response.
An empty or tiny body on a 200 response deserves a second look. It can mean the application failed but still reported success, which is one form of soft 404.
How to see raw response headers with curl
Browser developer tools show headers in the Network panel, but curl shows exactly what the server sent, with no browser cache or extensions in the way. Three commands cover most needs.
The -I flag sends a HEAD request, and a few servers answer HEAD differently from GET. The -sv form avoids that by making a normal GET and discarding the body. Verbose output goes to stderr, so add 2>&1 before piping it to grep.
# Response headers only (curl sends a HEAD request)
curl -I https://example.com
# A normal GET with the full exchange: lines starting with > were sent,
# lines starting with < were received, and * lines are connection and TLS details
curl -sv -o /dev/null https://example.com
# Follow redirects and print the headers of every hop
curl -sIL https://example.com