Definition
An HTTP response is a message sent from a server back to a client after processing an HTTP request. The response indicates whether the request succeeded or failed, and optionally includes the requested data or error details.
The response consists of three main parts:
- Status Line - HTTP version, status code, and reason phrase
- Headers - Metadata about the response (content type, caching, authentication)
- Body (optional) - The actual data (HTML, JSON, XML, files, etc.)
HTTP responses follow the format defined in RFC 7231 and are essential for client-server communication in REST APIs and web applications.
Example
A typical HTTP 200 OK response with JSON data:
HTTP/1.1 200 OK
Date: Thu, 09 Jan 2026 10:30:00 GMT
Content-Type: application/json
Content-Length: 142
Cache-Control: max-age=3600
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
{
"id": 123,
"name": "Alice Smith",
"email": "[email protected]",
"role": "developer",
"createdAt": "2026-01-05T14:22:00Z"
}
A 404 Not Found response:
HTTP/1.1 404 Not Found
Date: Thu, 09 Jan 2026 10:30:00 GMT
Content-Type: application/json
Content-Length: 58
{
"error": "User not found",
"userId": 999
}
Code Example
JavaScript (Fetch API):
const fetchUser = async (userId) => {
try {
const response = await fetch(`https://api.example.com/users/${userId}`, {
headers: {
'Authorization': 'Bearer YOUR_TOKEN',
'Accept': 'application/json'
}
});
// Response object properties
console.log('Status:', response.status); // 200
console.log('Status Text:', response.statusText); // "OK"
console.log('Headers:', response.headers);
// Check if response is OK (status 200-299)
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
// Parse JSON body
const data = await response.json();
// Access response headers
const contentType = response.headers.get('Content-Type');
const etag = response.headers.get('ETag');
console.log('Content-Type:', contentType);
console.log('ETag:', etag);
console.log('User Data:', data);
return data;
} catch (error) {
if (error.name === 'AbortError') {
console.error('Request timeout');
} else {
console.error('Error:', error.message);
}
throw error;
}
};
// Usage
fetchUser(123)
.then(user => console.log('User:', user))
.catch(error => console.error('Failed:', error));
Python (requests library):
import requests
def fetch_user(user_id):
try:
response = requests.get(
f'https://api.example.com/users/{user_id}',
headers={
'Authorization': 'Bearer YOUR_TOKEN',
'Accept': 'application/json'
},
timeout=10
)
# Response object properties
print(f'Status Code: {response.status_code}') # 200
print(f'Reason: {response.reason}') # "OK"
print(f'Headers: {response.headers}')
# Check if response is successful (2xx)
response.raise_for_status()
# Parse JSON body
data = response.json()
# Access response headers
content_type = response.headers.get('Content-Type')
etag = response.headers.get('ETag')
print(f'Content-Type: {content_type}')
print(f'ETag: {etag}')
print(f'User Data: {data}')
return data
except requests.exceptions.HTTPError as e:
print(f'HTTP Error: {e}')
raise
except requests.exceptions.Timeout:
print('Request timeout')
raise
except requests.exceptions.RequestException as e:
print(f'Request failed: {e}')
raise
# Usage
try:
user = fetch_user(123)
print(f'User: {user}')
except Exception as e:
print(f'Failed: {e}')
Diagram
sequenceDiagram
participant Client
participant Server
Note over Client,Server: Request Phase
Client->>Server: HTTP Request
Note right of Server: GET /api/users/123
Note over Server: Processing
Server->>Server: Authenticate
Server->>Server: Authorize
Server->>Server: Fetch Data
Server->>Server: Format Response
Note over Server: Build Response
Server->>Server: Set Status Code
Server->>Server: Add Headers
Server->>Server: Serialize Body
Note over Client,Server: Response Phase
Server->>Client: HTTP Response
Note left of Client: Status: 200 OK
Headers: Content-Type, ETag
Body: JSON data
Note over Client: Handle Response
Client->>Client: Check Status Code
Client->>Client: Parse Headers
Client->>Client: Deserialize Body
Client->>Client: Update UI/State
Analogy
Think of an HTTP response like getting your order at a restaurant:
- Status Line β “Here’s your order” (success) or “Sorry, we’re out” (failure)
- Headers β Nutritional info, temperature, allergen warnings (metadata)
- Body β The actual meal (data you requested)
The waiter (server) brings back your meal (response) with all the details about what you ordered.
Best Practices
- Use Appropriate Status Codes - 2xx for success, 4xx for client errors, 5xx for server errors
- Include Descriptive Headers -
Content-Type,Cache-Control,ETagfor caching - Provide Error Details - Include helpful error messages in response body
- Set Correct Content-Type - Match the body format (application/json, text/html, etc.)
- Enable Compression - Use
Content-Encoding: gzipfor large responses - Include CORS Headers - Set
Access-Control-Allow-Originfor cross-origin requests - Use HTTP/2 - Enable multiplexing and header compression for better performance
Common Mistakes
- Wrong Status Code - Returning 200 OK for errors, or 404 when 401/403 is appropriate
- Missing Content-Type - Not specifying the response body format
- No Error Details - Returning generic errors without useful messages
- Sending Sensitive Data - Including passwords, internal IDs, or stack traces
- No Caching Headers - Not setting
Cache-ControlorETagfor cacheable resources - Inconsistent Format - Changing response structure between endpoints
- No Rate Limit Info - Not including
X-RateLimit-*headers