Ojasa Mirai

Ojasa Mirai

Python

Loading...

Learning Level

🟢 Beginner🔵 Advanced
REST API BasicsHTTP RequestsStatus CodesJSON SerializationError HandlingAPI AuthenticationRate LimitingBuilding APIsWeb Scraping Basics
Python/Apis Json/Status Codes

📊 HTTP Status Codes — Understanding Server Responses

HTTP status codes are three-digit numbers that tell you the result of your request. They're essential for understanding what went right or wrong when communicating with servers. Learning to read and handle status codes is crucial for building robust applications.


🎯 What Are Status Codes?

Every HTTP response includes a status code that indicates the outcome of the request. These codes are grouped into five categories based on their first digit.

import requests

response = requests.get('https://api.github.com/users/octocat')

# The status code
print(response.status_code)  # 200

# Check if successful (status 200-299)
if response.ok:
    print("Request succeeded!")
else:
    print("Request failed!")

# Get status code with reason phrase
print(f"{response.status_code} {response.reason}")  # 200 OK

✅ 2xx Success Codes

These codes indicate the request succeeded.

200 OK

The request succeeded and the server returned the requested data.

import requests

response = requests.get('https://jsonplaceholder.typicode.com/posts/1')
print(response.status_code)  # 200

if response.status_code == 200:
    data = response.json()
    print(f"Post: {data['title']}")

201 Created

The request succeeded and a new resource was created.

import requests

new_post = {
    'title': 'New Post',
    'body': 'Post content',
    'userId': 1
}

response = requests.post(
    'https://jsonplaceholder.typicode.com/posts',
    json=new_post
)

if response.status_code == 201:
    created = response.json()
    print(f"Created resource with ID: {created['id']}")

204 No Content

The request succeeded but there's no content to return (common for DELETE).

import requests

response = requests.delete('https://api.example.com/users/5')

if response.status_code == 204:
    print("Resource deleted successfully")
    # No response body to parse

🔀 3xx Redirection Codes

These codes indicate the request needs further action to complete.

301 Moved Permanently

The resource has been permanently moved to a new URL.

import requests

# By default, requests follows redirects automatically
response = requests.get('https://example.com')  # Automatically follows redirects

# See final URL after redirects
print(response.url)

# Disable redirect following
response = requests.get('https://example.com', allow_redirects=False)
if response.status_code == 301:
    new_location = response.headers['Location']
    print(f"Moved to: {new_location}")

304 Not Modified

The resource hasn't changed since your last request.

import requests

headers = {
    'If-None-Match': 'abc123def456'  # Validation token from previous response
}

response = requests.get(
    'https://api.example.com/data',
    headers=headers
)

if response.status_code == 304:
    print("Data hasn't changed since last request")
    # Use cached data from previous response

❌ 4xx Client Error Codes

These codes indicate something wrong with the client's request.

400 Bad Request

The request format is invalid.

import requests

# Missing required field
invalid_data = {'title': 'No body!'}  # Missing 'body' field

response = requests.post(
    'https://api.example.com/posts',
    json=invalid_data
)

if response.status_code == 400:
    error = response.json()
    print(f"Bad request: {error}")

401 Unauthorized

Authentication is required or invalid.

import requests

# Missing authentication token
response = requests.get('https://api.example.com/private-data')

if response.status_code == 401:
    print("Authentication required!")
    print("Add your API key or token to the headers")

# Correct way with authentication
headers = {'Authorization': 'Bearer your-token-here'}
response = requests.get(
    'https://api.example.com/private-data',
    headers=headers
)

403 Forbidden

You're authenticated but don't have permission to access this resource.

import requests

# You have a token but lack necessary permissions
response = requests.delete('https://api.example.com/admin/users')

if response.status_code == 403:
    print("You don't have permission to delete users")

404 Not Found

The requested resource doesn't exist.

import requests

response = requests.get('https://api.example.com/users/99999')

if response.status_code == 404:
    print("User not found!")

# Check before assuming data exists
if response.ok:
    user = response.json()
else:
    print(f"Error: {response.status_code}")

409 Conflict

The request conflicts with the current state of the resource.

import requests

# Trying to create duplicate resource
data = {'username': 'existing_user'}

response = requests.post('https://api.example.com/users', json=data)

if response.status_code == 409:
    print("Username already exists!")

429 Too Many Requests

You've sent too many requests too quickly (rate limiting).

import requests
import time

for i in range(100):
    response = requests.get('https://api.example.com/data')

    if response.status_code == 429:
        # Rate limited - wait before retrying
        retry_after = int(response.headers.get('Retry-After', 60))
        print(f"Rate limited. Waiting {retry_after} seconds...")
        time.sleep(retry_after)
        # Retry the request
        response = requests.get('https://api.example.com/data')

💥 5xx Server Error Codes

These codes indicate something wrong with the server.

500 Internal Server Error

The server encountered an unexpected error.

import requests

response = requests.get('https://api.example.com/data')

if response.status_code == 500:
    print("Server error! Try again later.")

502 Bad Gateway

Invalid response from upstream server.

import requests
import time

response = requests.get('https://api.example.com/data')

if response.status_code == 502:
    print("Bad gateway error. Retrying in 5 seconds...")
    time.sleep(5)
    response = requests.get('https://api.example.com/data')

503 Service Unavailable

The server is temporarily down for maintenance.

import requests

response = requests.get('https://api.example.com/data')

if response.status_code == 503:
    print("Service temporarily unavailable")
    print("Check response headers for maintenance information")
    print(response.headers.get('Retry-After'))

🛡️ Handling Status Codes Properly

import requests
from requests.exceptions import RequestException
import time

def make_request_with_retry(url, max_retries=3):
    """Make request with proper error handling and retries"""

    for attempt in range(max_retries):
        try:
            response = requests.get(url, timeout=5)

            # Check for specific status codes
            if response.status_code == 200:
                return response.json()

            elif response.status_code == 401:
                print("Authentication failed")
                return None

            elif response.status_code == 404:
                print("Resource not found")
                return None

            elif response.status_code in [500, 502, 503]:
                # Server error - retry
                if attempt < max_retries - 1:
                    wait_time = 2 ** attempt  # Exponential backoff
                    print(f"Server error. Retrying in {wait_time}s...")
                    time.sleep(wait_time)
                    continue
                else:
                    print("Server error persists after retries")
                    return None

            elif response.status_code == 429:
                # Rate limited
                retry_after = int(response.headers.get('Retry-After', 60))
                print(f"Rate limited. Waiting {retry_after}s...")
                time.sleep(retry_after)
                continue

            else:
                # Unexpected status
                print(f"Unexpected status: {response.status_code}")
                return None

        except requests.exceptions.Timeout:
            print("Request timed out")
            if attempt < max_retries - 1:
                print("Retrying...")
                time.sleep(1)
                continue

        except RequestException as e:
            print(f"Request error: {e}")
            return None

    return None

# Using the function
data = make_request_with_retry('https://api.example.com/data')
if data:
    print(f"Got data: {data}")

📊 Status Code Reference Table

# Quick reference
STATUS_CODES = {
    # 2xx Success
    200: 'OK - Request succeeded',
    201: 'Created - New resource created',
    204: 'No Content - Success with no body',

    # 3xx Redirection
    301: 'Moved Permanently',
    304: 'Not Modified - Use cached version',

    # 4xx Client Error
    400: 'Bad Request - Invalid format',
    401: 'Unauthorized - Auth required',
    403: 'Forbidden - No permission',
    404: 'Not Found - Resource missing',
    409: 'Conflict - Duplicate or state conflict',
    429: 'Too Many Requests - Rate limited',

    # 5xx Server Error
    500: 'Internal Server Error',
    502: 'Bad Gateway',
    503: 'Service Unavailable'
}

# Use in your code
def explain_status(code):
    return STATUS_CODES.get(code, f'Unknown status {code}')

print(explain_status(404))  # Not Found - Resource missing

✅ Key Takeaways

Code RangeMeaningAction
2xxSuccessUse the data, continue
3xxRedirectionFollow the new URL
4xxClient ErrorFix the request
5xxServer ErrorRetry later
200OKRequest succeeded perfectly
201CreatedNew resource successfully made
204No ContentSuccess, no body to parse
400Bad RequestCheck your data format
401UnauthorizedAdd authentication
403ForbiddenYou lack permission
404Not FoundResource doesn't exist
429Rate LimitedWait before retrying
500Server ErrorServer problem, not yours

🔗 What's Next?

Learn how to serialize and work with JSON data in your Python applications.

Next: JSON Serialization →


Ready to practice? Try challenges or explore resources


Resources

Python Docs

Ojasa Mirai

Master AI-powered development skills through structured learning, real projects, and verified credentials. Whether you're upskilling your team or launching your career, we deliver the skills companies actually need.

Learn Deep • Build Real • Verify Skills • Launch Forward

Courses

PythonFastapiReactJSCloud

© 2026 Ojasa Mirai. All rights reserved.

TwitterGitHubLinkedIn