HTTP Response

Fundamentals Jan 9, 2026 HTTP
http response server status-codes

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:

  1. Status Line - HTTP version, status code, and reason phrase
  2. Headers - Metadata about the response (content type, caching, authentication)
  3. 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

  1. Use Appropriate Status Codes - 2xx for success, 4xx for client errors, 5xx for server errors
  2. Include Descriptive Headers - Content-Type, Cache-Control, ETag for caching
  3. Provide Error Details - Include helpful error messages in response body
  4. Set Correct Content-Type - Match the body format (application/json, text/html, etc.)
  5. Enable Compression - Use Content-Encoding: gzip for large responses
  6. Include CORS Headers - Set Access-Control-Allow-Origin for cross-origin requests
  7. 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-Control or ETag for cacheable resources
  • Inconsistent Format - Changing response structure between endpoints
  • No Rate Limit Info - Not including X-RateLimit-* headers

Standards & RFCs