
HTTP Response Structure: Reading What the Server Tells You
Learn to read and interpret every part of an HTTP response: status lines, headers, and JSON bodies. Master the art of understanding what the server is communicating.
HTTP Response Structure: Reading What the Server Tells You
Understanding responses is just as important as constructing requests. The server communicates the result of your request through a carefully structured response. In this lesson, we will dissect every component and learn to read responses like a professional.
1. The Three Components of Every Response
graph TD
A[HTTP Response] --> B["1. Status Line<br/>HTTP/1.1 200 OK"]
A --> C["2. Response Headers<br/>Content-Type, Cache-Control..."]
A --> D["3. Response Body<br/>JSON data"]
style A fill:#4f46e5,color:#fff
style B fill:#059669,color:#fff
style C fill:#0891b2,color:#fff
style D fill:#d97706,color:#fff
A raw HTTP response:
HTTP/1.1 200 OK ← Status line
Content-Type: application/json ← Response headers
X-Request-Id: req-abc-123-def ← Response headers
Cache-Control: max-age=3600 ← Response headers
Content-Length: 256 ← Response headers
← Empty line
{ ← Body
"id": 42,
"name": "Jane Doe",
"email": "jane@example.com"
}
2. The Status Line
The status line contains three elements:
HTTP/1.1 200 OK
│ │ │
│ │ └── Reason phrase (human-readable)
│ └─────── Status code (machine-readable)
└───────────────── HTTP version
The status code is the most important part. It tells you instantly whether your request succeeded or failed.
Status Code Categories
graph LR
A["1xx"] --> A1["Informational<br/>Processing..."]
B["2xx"] --> B1["Success<br/>It worked!"]
C["3xx"] --> C1["Redirection<br/>Go elsewhere"]
D["4xx"] --> D1["Client Error<br/>Your fault"]
E["5xx"] --> E1["Server Error<br/>Their fault"]
style A fill:#6b7280,color:#fff
style B fill:#059669,color:#fff
style C fill:#0891b2,color:#fff
style D fill:#d97706,color:#fff
style E fill:#dc2626,color:#fff
The Most Common Status Codes
Success (2xx):
| Code | Name | When It Happens | Typical Response |
|---|---|---|---|
| 200 | OK | GET, PUT, PATCH succeeded | JSON data |
| 201 | Created | POST succeeded | New resource JSON |
| 204 | No Content | DELETE succeeded | Empty body |
Client Errors (4xx):
| Code | Name | What Went Wrong | How to Fix |
|---|---|---|---|
| 400 | Bad Request | Invalid data | Check JSON and fields |
| 401 | Unauthorized | No auth token | Add Authorization header |
| 403 | Forbidden | Insufficient permissions | Use different account/role |
| 404 | Not Found | Wrong URL or ID | Check endpoint and resource |
| 405 | Method Not Allowed | Wrong method | Use correct HTTP method |
| 409 | Conflict | Duplicate or conflict | Check for existing data |
| 422 | Unprocessable Entity | Invalid values | Check field value formats |
| 429 | Too Many Requests | Rate limited | Wait and retry |
Server Errors (5xx):
| Code | Name | What It Means | What to Do |
|---|---|---|---|
| 500 | Internal Server Error | Server code crash | Not your fault — report |
| 502 | Bad Gateway | Upstream server down | Wait and retry |
| 503 | Service Unavailable | Server overloaded | Wait and retry |
| 504 | Gateway Timeout | Upstream too slow | Wait and retry |
3. Response Headers
Response headers tell you about the response itself: its format, size, caching policy, and more.
Common Response Headers
| Header | What It Tells You | Example |
|---|---|---|
Content-Type | Format of the body | application/json; charset=utf-8 |
Content-Length | Size in bytes | 2048 |
Cache-Control | How long to cache | max-age=3600 |
X-Request-Id | Unique request identifier | req-abc-123-def |
X-RateLimit-Limit | Max requests allowed | 100 |
X-RateLimit-Remaining | Requests left | 97 |
X-RateLimit-Reset | When limit resets (Unix timestamp) | 1708640000 |
Location | URL of created resource | /api/v1/users/43 |
ETag | Version identifier for caching | "33a64df5" |
Date | Server timestamp | Sat, 22 Feb 2026 18:00:00 GMT |
Reading Headers in Practice
curl -i https://jsonplaceholder.typicode.com/posts/1
The -i flag shows headers above the body:
HTTP/2 200
date: Sat, 22 Feb 2026 23:30:00 GMT
content-type: application/json; charset=utf-8
cache-control: max-age=43200
pragma: no-cache
x-content-type-options: nosniff
etag: W/"124-yiKdLzqO5gfBrJFrcdJ8Yq0LGnU"
{
"userId": 1,
"id": 1,
...
}
Rate Limit Headers
Many APIs include rate limit information in headers:
curl -I https://api.github.com/users/octocat
Look for:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 55
X-RateLimit-Reset: 1708643600
X-RateLimit-Used: 5
This tells you:
- You can make 60 requests per hour
- You have 55 remaining
- The counter resets at the Unix timestamp 1708643600
4. The Response Body
The response body contains the actual data. For REST APIs, this is almost always JSON.
Single Resource Response
{
"id": 42,
"name": "Jane Doe",
"email": "jane@example.com",
"createdAt": "2026-02-22T18:30:00Z"
}
Collection Response
[
{"id": 1, "name": "Alice"},
{"id": 2, "name": "Bob"},
{"id": 3, "name": "Charlie"}
]
Paginated Response
{
"data": [
{"id": 11, "name": "Item 11"},
{"id": 12, "name": "Item 12"}
],
"meta": {
"page": 2,
"perPage": 10,
"total": 100,
"totalPages": 10
},
"links": {
"self": "/api/items?page=2",
"first": "/api/items?page=1",
"prev": "/api/items?page=1",
"next": "/api/items?page=3",
"last": "/api/items?page=10"
}
}
Error Response
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": [
{"field": "email", "message": "Invalid email format"},
{"field": "age", "message": "Must be a positive number"}
]
},
"requestId": "req-abc-123"
}
The requestId is especially useful — you can send it to the API provider when reporting bugs.
5. Response Patterns
Different API operations return different response patterns:
graph TD
A[Response Patterns] --> B["GET /items<br/>200 + Array"]
A --> C["GET /items/42<br/>200 + Object"]
A --> D["POST /items<br/>201 + New Object"]
A --> E["PUT /items/42<br/>200 + Updated Object"]
A --> F["DELETE /items/42<br/>204 No Content"]
A --> G["Any error<br/>4xx/5xx + Error Object"]
style A fill:#4f46e5,color:#fff
style B fill:#0891b2,color:#fff
style C fill:#0891b2,color:#fff
style D fill:#059669,color:#fff
style E fill:#d97706,color:#fff
style F fill:#dc2626,color:#fff
style G fill:#6b7280,color:#fff
POST Response: The Location Header
When you create a resource, the server often includes a Location header telling you where to find the new resource:
HTTP/1.1 201 Created
Location: /api/v1/users/43
Content-Type: application/json
{
"id": 43,
"name": "New User",
"createdAt": "2026-02-22T18:30:00Z"
}
6. Comparing Responses with cURL Flags
| cURL Flag | Shows | Use Case |
|---|---|---|
| (none) | Body only | Quick data check |
-i | Headers + Body | See status code and metadata |
-I | Headers only | Check existence, cache info |
-v | Full conversation | Deep debugging |
-s -o /dev/null -w "%{http_code}" | Status code only | Script automation |
# Body only
curl https://jsonplaceholder.typicode.com/posts/1
# Headers + Body
curl -i https://jsonplaceholder.typicode.com/posts/1
# Headers only
curl -I https://jsonplaceholder.typicode.com/posts/1
# Status code only
curl -s -o /dev/null -w "%{http_code}" https://jsonplaceholder.typicode.com/posts/1
Summary and Key Takeaways
- Responses have three parts: status line, headers, body.
- The status code is your first indicator of success or failure.
- Response headers contain metadata about caching, rate limits, and content type.
- Error responses tell you exactly what went wrong — always read them.
- Different operations return different patterns: arrays, objects, or no content.
- Use cURL flags (
-i,-I,-v) to control how much response detail you see.
Lesson Review Quiz
?Knowledge Check
What does the X-RateLimit-Remaining response header tell you?
?Knowledge Check
What status code should a server return when a POST request successfully creates a new resource?
?Knowledge Check
Which cURL flag shows both response headers and body?