š 2.4 Common HTTP Response Codes Associated with REST APIs
What are HTTP Response Codes?
HTTP response codes (also called status codes) are three-digit numbers returned by a server in response to a client's request. They indicate whether the request was successful, failed, or requires additional action.
HTTP response codes are grouped into five categories based on their first digit:
⢠1xx - Informational responses
⢠2xx - Success responses
⢠3xx - Redirection messages
⢠4xx - Client errors
⢠5xx - Server errors
Status Code Categories Overview
Request received, continue"] C --> C1["200 OK
ā Request successful"] C --> C2["201 Created
ā Resource created"] C --> C3["204 No Content
ā Success, no response body"] D --> D1["301 Moved Permanently
āŖļø Resource moved"] D --> D2["302 Found
āŖļø Temporary redirect"] E --> E1["400 Bad Request
ā Invalid syntax"] E --> E2["401 Unauthorized
ā Authentication required"] E --> E3["403 Forbidden
ā No permission"] E --> E4["404 Not Found
ā Resource doesn't exist"] F --> F1["500 Internal Server Error
š„ Server failure"] F --> F2["503 Service Unavailable
š„ Server overloaded"] style A fill:#667eea,stroke:#764ba2,stroke-width:3px,color:#fff style B fill:#64b5f6,stroke:#1976d2,stroke-width:2px,color:#fff style C fill:#66bb6a,stroke:#2e7d32,stroke-width:2px,color:#fff style D fill:#ffa726,stroke:#e65100,stroke-width:2px,color:#fff style E fill:#ef5350,stroke:#c62828,stroke-width:2px,color:#fff style F fill:#ab47bc,stroke:#6a1b9a,stroke-width:2px,color:#fff
1xx - Informational Responses
These codes indicate that the request was received and the process is continuing.
| Code | Message | Description | Common Use Case |
|---|---|---|---|
| 100 | Continue | Server has received request headers; client should proceed to send body | Large file uploads where server checks headers first |
| 101 | Switching Protocols | Server is switching protocols as requested by client | Upgrading HTTP to WebSocket connection |
2xx - Success Responses
These codes indicate that the request was successfully received, understood, and accepted.
| Code | Message | Description | Common Use Case |
|---|---|---|---|
| 200 | OK | Request succeeded; response contains requested data | GET request successfully retrieves data PUT/PATCH successfully updates resource |
| 201 | Created | Request succeeded and new resource was created | POST request creates a new user, device, or record |
| 202 | Accepted | Request accepted for processing, but not completed | Asynchronous operations (e.g., batch processing, job queue) |
| 204 | No Content | Request succeeded but no content to return | DELETE request successfully removes a resource PUT update with no response body needed |
- 200 OK - Default success for GET, PUT, PATCH
- 201 Created - Always use for POST when creating resources
- 204 No Content - Use for DELETE or when no response body is needed
3xx - Redirection Messages
These codes indicate that the client must take additional action to complete the request.
| Code | Message | Description | Common Use Case |
|---|---|---|---|
| 301 | Moved Permanently | Resource has been permanently moved to new URL | API versioning (v1 ā v2), domain changes |
| 302 | Found (Temporary Redirect) | Resource temporarily at different URL | Temporary maintenance, A/B testing |
| 304 | Not Modified | Cached version is still valid; no new data to send | Conditional GET requests with If-Modified-Since header |
| 307 | Temporary Redirect | Like 302 but guarantees HTTP method won't change | Temporary redirects where method must stay POST/PUT/DELETE |
| 308 | Permanent Redirect | Like 301 but guarantees HTTP method won't change | Permanent redirects where method must stay POST/PUT/DELETE |
⢠301/302: May change POST to GET
⢠307/308: Preserve original HTTP method
⢠Clients should follow redirect automatically or provide new location to user
4xx - Client Error Responses
These codes indicate that the request contains bad syntax or cannot be fulfilled due to client error.
| Code | Message | Description | Common Use Case |
|---|---|---|---|
| 400 | Bad Request | Server cannot process request due to invalid syntax | Malformed JSON, missing required fields, invalid data types |
| 401 | Unauthorized | Authentication required or failed | Missing/invalid token, expired credentials, wrong password |
| 403 | Forbidden | Client authenticated but doesn't have permission | Insufficient privileges, accessing admin-only resource |
| 404 | Not Found | Requested resource doesn't exist | Wrong URL/endpoint, resource deleted, invalid ID |
| 405 | Method Not Allowed | HTTP method not supported for this endpoint | Using POST on read-only endpoint, DELETE on protected resource |
| 408 | Request Timeout | Server timed out waiting for request | Slow client connection, large file upload interrupted |
| 409 | Conflict | Request conflicts with current state | Duplicate resource creation, concurrent update conflicts |
| 415 | Unsupported Media Type | Request payload format not supported | Sending XML when API expects JSON, wrong Content-Type header |
| 422 | Unprocessable Entity | Request well-formed but semantically invalid | Validation errors (email format wrong, age negative, etc.) |
| 429 | Too Many Requests | Rate limit exceeded | API quota exceeded, too many requests in time window |
⢠401 Unauthorized: "Who are you?" - Authentication problem (invalid/missing credentials)
⢠403 Forbidden: "I know who you are, but you can't do that" - Authorization problem (insufficient permissions)
5xx - Server Error Responses
These codes indicate that the server failed to fulfill a valid request.
| Code | Message | Description | Common Use Case |
|---|---|---|---|
| 500 | Internal Server Error | Generic server error; something went wrong | Unhandled exceptions, database errors, code bugs |
| 501 | Not Implemented | Server doesn't support functionality required | Feature not yet implemented, unsupported HTTP method |
| 502 | Bad Gateway | Server acting as gateway received invalid response | Reverse proxy can't reach backend, upstream server down |
| 503 | Service Unavailable | Server temporarily unable to handle request | Maintenance mode, server overloaded, temporary outage |
| 504 | Gateway Timeout | Server acting as gateway didn't get timely response | Upstream server too slow, database query timeout |
Python Example: Checking Status Codes
#!/usr/bin/env python3
"""
HTTP Status Code Handling Example
Demonstrates how to handle different response codes in Python
"""
import requests
def make_api_request_with_error_handling(url, method="GET", **kwargs):
"""
Make API request with comprehensive status code handling
Args:
url (str): API endpoint URL
method (str): HTTP method (GET, POST, PUT, DELETE, etc.)
**kwargs: Additional arguments for requests (headers, data, etc.)
"""
try:
# Make the request
response = requests.request(method, url, **kwargs)
status_code = response.status_code
print(f"š” Request: {method} {url}")
print(f"š Status Code: {status_code}")
print(f"š Status Message: {response.reason}")
print("-" * 60)
# Handle different status code ranges
if 200 <= status_code < 300:
# 2xx - Success
print("ā
SUCCESS")
if status_code == 200:
print("Request successful, data returned")
return response.json() if response.content else None
elif status_code == 201:
print("Resource created successfully")
print(f"Location: {response.headers.get('Location', 'N/A')}")
return response.json() if response.content else None
elif status_code == 204:
print("Request successful, no content returned")
return None
else:
print(f"Success with status {status_code}")
return response.json() if response.content else None
elif 300 <= status_code < 400:
# 3xx - Redirection
print("āŖļø REDIRECTION")
new_location = response.headers.get('Location', 'Not specified')
print(f"Redirect to: {new_location}")
if status_code in [301, 308]:
print("Permanent redirect - update bookmarks/links")
elif status_code in [302, 307]:
print("Temporary redirect - original URL still valid")
return None
elif 400 <= status_code < 500:
# 4xx - Client Error
print("ā CLIENT ERROR")
if status_code == 400:
print("Bad Request - check request syntax and data")
elif status_code == 401:
print("Unauthorized - authentication required/failed")
print("Action: Check credentials, token, or API key")
elif status_code == 403:
print("Forbidden - insufficient permissions")
print("Action: Verify account has required privileges")
elif status_code == 404:
print("Not Found - resource doesn't exist")
print("Action: Verify URL/endpoint and resource ID")
elif status_code == 405:
print("Method Not Allowed - HTTP method not supported")
print(f"Allowed methods: {response.headers.get('Allow', 'N/A')}")
elif status_code == 409:
print("Conflict - request conflicts with current state")
elif status_code == 415:
print("Unsupported Media Type - check Content-Type header")
elif status_code == 422:
print("Unprocessable Entity - validation failed")
elif status_code == 429:
print("Too Many Requests - rate limit exceeded")
retry_after = response.headers.get('Retry-After', 'N/A')
print(f"Retry after: {retry_after} seconds")
# Try to get error details from response
try:
error_data = response.json()
print(f"Error details: {error_data}")
except:
print(f"Error message: {response.text}")
return None
elif 500 <= status_code < 600:
# 5xx - Server Error
print("š„ SERVER ERROR")
if status_code == 500:
print("Internal Server Error - server encountered an error")
elif status_code == 502:
print("Bad Gateway - upstream server issue")
elif status_code == 503:
print("Service Unavailable - server temporarily down")
retry_after = response.headers.get('Retry-After', 'N/A')
print(f"Retry after: {retry_after}")
elif status_code == 504:
print("Gateway Timeout - upstream server didn't respond")
print("Action: Contact API provider or try again later")
return None
except requests.exceptions.ConnectionError:
print("ā Connection Error: Cannot reach the server")
print("Action: Check internet connection and server availability")
except requests.exceptions.Timeout:
print("ā Timeout Error: Request took too long")
print("Action: Try again or increase timeout")
except requests.exceptions.RequestException as e:
print(f"ā Request Error: {e}")
return None
# =============================================================================
# USAGE EXAMPLES
# =============================================================================
if __name__ == "__main__":
# Example 1: Successful GET request (200 OK)
print("\n" + "="*60)
print("Example 1: GET Request")
print("="*60)
make_api_request_with_error_handling(
"https://jsonplaceholder.typicode.com/posts/1"
)
# Example 2: Successful POST request (201 Created)
print("\n" + "="*60)
print("Example 2: POST Request")
print("="*60)
make_api_request_with_error_handling(
"https://jsonplaceholder.typicode.com/posts",
method="POST",
headers={"Content-Type": "application/json"},
json={"title": "Test", "body": "Test body", "userId": 1}
)
# Example 3: 404 Not Found
print("\n" + "="*60)
print("Example 3: 404 Not Found")
print("="*60)
make_api_request_with_error_handling(
"https://jsonplaceholder.typicode.com/posts/99999"
)
# Example 4: 401 Unauthorized (simulated)
print("\n" + "="*60)
print("Example 4: 401 Unauthorized")
print("="*60)
# This is a hypothetical example - actual API might differ
make_api_request_with_error_handling(
"https://api.github.com/user",
headers={"Authorization": "Bearer invalid_token"}
)
Quick Reference: Most Common Status Codes
- 200 OK - Standard success response
- 201 Created - Resource created successfully
- 204 No Content - Success with no body
- 400 Bad Request - Invalid request syntax
- 401 Unauthorized - Authentication needed
- 403 Forbidden - No permission
- 404 Not Found - Resource doesn't exist
- 429 Too Many Requests - Rate limited
- 500 Internal Server Error - Server problem
- 503 Service Unavailable - Temporarily down
š§ 2.5 Troubleshoot a Problem Given HTTP Response Code, Request, and API Documentation
The Troubleshooting Process
Troubleshooting API issues requires a systematic approach. When you encounter an error, you need to analyze three key components: the HTTP response code, the request you sent, and the API documentation.
- Gather Information: Collect the HTTP response code, your request details, and API documentation
- Analyze Status Code: Determine if it's a success (2xx), client error (4xx), or server error (5xx)
- Client Errors (4xx): Review your request components and compare with documentation
- Server Errors (5xx): Check API status, implement retry logic, or contact support
- Test and Verify: After fixing issues, retry the request and verify success
Step-by-Step Troubleshooting Guide
Step 1: Identify the Status Code Category
- 4xx: Problem is with YOUR request (client-side)
- 5xx: Problem is with THE SERVER (server-side)
⢠For 5xx errors: Check API status, wait, or contact support
Step 2: Examine the Response Body
- Error message or description
- Error code (API-specific)
- Validation errors with field names
- Suggestions for fixing the issue
Step 3: Verify Request Components
| Component | What to Verify | Common Issues |
|---|---|---|
| URL/Endpoint | ⢠Correct base URL ⢠Proper path ⢠Valid resource ID |
Typos, wrong version (v1 vs v2), missing slashes |
| HTTP Method | ⢠Using correct method ⢠Method is allowed |
Using POST instead of PUT, DELETE not allowed |
| Headers | ⢠Content-Type set ⢠Accept header ⢠Custom headers |
Missing Content-Type, wrong format specified |
| Authentication | ⢠Token present ⢠Token not expired ⢠Correct format |
Missing "Bearer" prefix, expired token, wrong header |
| Request Body | ⢠Valid JSON/XML ⢠All required fields ⢠Correct data types |
Invalid JSON syntax, missing fields, wrong types |
Step 4: Compare with API Documentation
- Verify endpoint path and structure
- Check required vs optional parameters
- Review example requests and responses
- Check authentication requirements
- Look for rate limits and quotas
- Review data format specifications
Common Scenarios & Solutions
š“ Scenario 1: 401 Unauthorized
Error Message: "Authentication failed" or "Invalid credentials"
Possible Causes:- Missing authentication token/API key
- Expired token
- Invalid token format
- Wrong authentication header name
# Step 1: Check if Authorization header exists
headers = {
"Authorization": "Bearer YOUR_TOKEN_HERE" # ā
Correct
# "Authorization": "YOUR_TOKEN_HERE" # ā Missing "Bearer"
}
# Step 2: Verify token hasn't expired
import jwt
import datetime
try:
decoded = jwt.decode(token, options={"verify_signature": False})
exp = decoded.get('exp')
if exp and datetime.datetime.fromtimestamp(exp) < datetime.datetime.now():
print("ā Token expired!")
else:
print("ā
Token is valid")
except:
print("ā Invalid token format")
# Step 3: Check documentation for correct header name
# Some APIs use different header names:
# - "Authorization": "Bearer token"
# - "X-API-Key": "key"
# - "Api-Token": "token"
- Obtain fresh authentication token
- Verify correct authorization header format
- Ensure "Bearer" prefix if using JWT
- Check token hasn't expired
š“ Scenario 2: 400 Bad Request
Error Message: "Invalid request syntax" or "Malformed JSON"
Possible Causes:- Invalid JSON syntax
- Missing required fields
- Wrong data types
- Invalid characters in request
# Step 1: Validate JSON syntax
import json
request_body = '''
{
"name": "John",
"age": 30, # ā Comments not allowed in JSON
"email": "john@example.com"
}
'''
try:
data = json.loads(request_body)
print("ā
Valid JSON")
except json.JSONDecodeError as e:
print(f"ā Invalid JSON: {e}")
# Step 2: Verify all required fields are present
required_fields = ["name", "email", "age"]
data = {"name": "John", "email": "john@example.com"} # Missing "age"
missing = [field for field in required_fields if field not in data]
if missing:
print(f"ā Missing required fields: {missing}")
# Step 3: Check data types match documentation
data = {
"name": "John", # ā
String
"age": "30", # ā Should be int, not string
"active": "true" # ā Should be boolean, not string
}
# Correct version:
data = {
"name": "John",
"age": 30,
"active": True
}
- Use JSON validator to check syntax
- Add all required fields from documentation
- Match data types exactly as specified
- Remove comments and trailing commas
š“ Scenario 3: 404 Not Found
Error Message: "Resource not found" or "Endpoint does not exist"
Possible Causes:- Incorrect URL/endpoint path
- Wrong API version
- Invalid resource ID
- Resource was deleted
- Typo in URL
# Step 1: Verify base URL and endpoint
# Documentation says:
base_url = "https://api.example.com/v2"
endpoint = "/users/123"
# Common mistakes:
wrong_url_1 = "https://api.example.com/v1/users/123" # ā Wrong version
wrong_url_2 = "https://api.example.com/v2/user/123" # ā "user" not "users"
wrong_url_3 = "https://api.example.com/v2/users/123/" # ā Trailing slash
correct_url = "https://api.example.com/v2/users/123" # ā
Correct
# Step 2: Check if resource ID exists
# Try listing all resources first
response = requests.get(f"{base_url}/users")
users = response.json()
print([user['id'] for user in users]) # See valid IDs
# Step 3: Verify URL construction
user_id = 123
url = f"{base_url}/users/{user_id}"
print(f"Requesting: {url}")
# Check for spaces or special characters
if " " in url:
print("ā URL contains spaces!")
- Double-check URL against documentation
- Verify API version is correct
- Confirm resource ID is valid
- Check for typos and trailing slashes
- Test with known working resource ID
š“ Scenario 4: 403 Forbidden
Error Message: "Access denied" or "Insufficient permissions"
Possible Causes:- Insufficient account permissions
- Resource access restricted
- IP address not whitelisted
- Subscription/plan limitation
# Step 1: Verify authentication is working (not 401)
# 403 means you're authenticated but not authorized
# Step 2: Check user permissions/roles
# Review your account settings:
# - Do you have admin/write permissions?
# - Is your subscription active?
# - Are you trying to access someone else's resource?
# Step 3: Check if endpoint requires special permission
# Documentation might specify:
# "DELETE /users/:id - Requires 'admin' role"
# "GET /analytics - Requires 'premium' subscription"
# Step 4: Verify resource ownership
# You might only be allowed to access YOUR resources
user_id = "current_user_123"
other_user_id = "other_user_456"
# ā
Allowed: Access your own data
url = f"{base_url}/users/{user_id}/profile"
# ā Forbidden: Access someone else's data
url = f"{base_url}/users/{other_user_id}/profile"
- Verify account has required permissions/role
- Check subscription plan supports this feature
- Ensure accessing only authorized resources
- Contact API provider to request access
š“ Scenario 5: 429 Too Many Requests
Error Message: "Rate limit exceeded" or "Too many requests"
Possible Causes:- Exceeded requests per second limit
- Exceeded daily/hourly quota
- Too many concurrent requests
# Step 1: Check rate limit headers
response = requests.get(url)
print(f"Rate Limit: {response.headers.get('X-RateLimit-Limit')}")
print(f"Remaining: {response.headers.get('X-RateLimit-Remaining')}")
print(f"Reset: {response.headers.get('X-RateLimit-Reset')}")
print(f"Retry After: {response.headers.get('Retry-After')} seconds")
# Step 2: Implement exponential backoff
import time
def make_request_with_retry(url, max_retries=3):
for attempt in range(max_retries):
response = requests.get(url)
if response.status_code == 429:
retry_after = int(response.headers.get('Retry-After', 60))
print(f"Rate limited. Waiting {retry_after} seconds...")
time.sleep(retry_after)
continue
return response
raise Exception("Max retries exceeded")
# Step 3: Add delays between requests
import time
urls = ["url1", "url2", "url3"]
for url in urls:
response = requests.get(url)
time.sleep(1) # Wait 1 second between requests
# Step 4: Use batch endpoints if available
# Instead of making 100 individual requests:
# for user_id in user_ids:
# requests.get(f"/users/{user_id}")
# Use batch endpoint if available:
# requests.post("/users/batch", json={"ids": user_ids})
- Implement rate limiting in your code
- Add delays between requests
- Use batch endpoints when available
- Cache responses to reduce requests
- Consider upgrading to higher tier
š“ Scenario 6: 500 Internal Server Error
Error Message: "Internal server error" or "Something went wrong"
Possible Causes:- Bug in API server code
- Database connection error
- Unexpected data causing crash
- Server resource exhaustion
# Step 1: Verify it's not your request
# Try a simple, known-working request
response = requests.get(f"{base_url}/health") # Health check endpoint
if response.status_code == 500:
print("ā Server is experiencing issues")
else:
print("ā
Server is healthy, issue is with specific request")
# Step 2: Check if your data triggers the error
# Try with minimal/sample data first
minimal_data = {"name": "Test"} # Minimal valid request
response = requests.post(url, json=minimal_data)
if response.status_code == 200:
print("ā
Minimal data works")
# Your full request might have problematic data
else:
print("ā Even minimal request fails - server issue")
# Step 3: Implement retry logic with exponential backoff
import time
def make_request_with_retry(url, max_retries=3):
for attempt in range(max_retries):
try:
response = requests.get(url, timeout=30)
if response.status_code == 500:
wait_time = 2 ** attempt # Exponential backoff: 1, 2, 4 seconds
print(f"Server error. Retry {attempt + 1}/{max_retries} in {wait_time}s")
time.sleep(wait_time)
continue
return response
except requests.exceptions.Timeout:
print(f"Timeout on attempt {attempt + 1}")
continue
raise Exception("Server error persists after retries")
# Step 4: Check API status page
print("Check: https://status.api-provider.com")
- Check API status/health page
- Wait a few minutes and retry
- Implement retry logic with backoff
- Report issue to API provider with request details
- Use monitoring to track frequency
Debugging Tools and Techniques
- Browser Developer Tools (Network Tab)
- View all request/response details
- See headers, body, timing
- Copy as cURL command
- Postman / Insomnia
- Test API endpoints interactively
- Save and organize requests
- View formatted responses
- cURL
- Command-line API testing
- Easy to share and reproduce issues
- Python Logging
- Log all request/response details
- Track down intermittent issues
- API Monitoring Tools
- Uptime monitors
- Response time tracking
- Error rate alerts
Complete Troubleshooting Example
#!/usr/bin/env python3
"""
Complete API Troubleshooting Example
Demonstrates how to debug and fix common API issues
"""
import requests
import json
import logging
from datetime import datetime
# Configure logging to see all request details
logging.basicConfig(level=logging.DEBUG)
class APITroubleshooter:
"""Helper class for troubleshooting API requests"""
def __init__(self, base_url):
self.base_url = base_url
self.session = requests.Session()
def diagnose_request(self, method, endpoint, **kwargs):
"""
Make request and provide detailed diagnostic information
"""
url = f"{self.base_url}{endpoint}"
print("="*70)
print(f"š DIAGNOSING REQUEST")
print("="*70)
# Display request details
print(f"\nš¤ REQUEST DETAILS:")
print(f" Method: {method}")
print(f" URL: {url}")
print(f" Headers: {json.dumps(kwargs.get('headers', {}), indent=13)}")
if 'json' in kwargs:
print(f" Body: {json.dumps(kwargs['json'], indent=13)}")
try:
# Make the request
response = self.session.request(method, url, **kwargs)
# Display response details
print(f"\nš„ RESPONSE DETAILS:")
print(f" Status: {response.status_code} {response.reason}")
print(f" Headers: {json.dumps(dict(response.headers), indent=13)}")
# Try to parse response body
try:
body = response.json()
print(f" Body: {json.dumps(body, indent=13)}")
except:
print(f" Body: {response.text[:500]}")
# Analyze the response
print(f"\nš ANALYSIS:")
self._analyze_response(response, kwargs)
return response
except requests.exceptions.RequestException as e:
print(f"\nā REQUEST FAILED: {e}")
return None
def _analyze_response(self, response, request_kwargs):
"""Analyze response and provide troubleshooting suggestions"""
status = response.status_code
if 200 <= status < 300:
print(" ā
SUCCESS - Request completed successfully")
elif status == 400:
print(" ā BAD REQUEST - Check request syntax and data")
print("\n Checklist:")
print(" [ ] Is the JSON valid?")
print(" [ ] Are all required fields present?")
print(" [ ] Are data types correct?")
print(" [ ] Is Content-Type header set?")
elif status == 401:
print(" ā UNAUTHORIZED - Authentication failed")
print("\n Checklist:")
print(" [ ] Is Authorization header present?")
print(" [ ] Is token format correct (Bearer )?")
print(" [ ] Has the token expired?")
print(" [ ] Is the token valid for this API?")
headers = request_kwargs.get('headers', {})
if 'Authorization' not in headers:
print("\n ā ļø WARNING: No Authorization header found!")
else:
auth = headers['Authorization']
if not auth.startswith('Bearer '):
print(f"\n ā ļø WARNING: Token might be missing 'Bearer' prefix")
elif status == 403:
print(" ā FORBIDDEN - Insufficient permissions")
print("\n Checklist:")
print(" [ ] Does your account have required permissions?")
print(" [ ] Are you accessing your own resources?")
print(" [ ] Does your plan/subscription support this?")
print(" [ ] Is your IP address whitelisted?")
elif status == 404:
print(" ā NOT FOUND - Resource or endpoint doesn't exist")
print("\n Checklist:")
print(" [ ] Is the URL correct?")
print(" [ ] Is the API version correct?")
print(" [ ] Does the resource ID exist?")
print(" [ ] Are there any typos?")
print(" [ ] Is there a trailing slash issue?")
elif status == 422:
print(" ā UNPROCESSABLE ENTITY - Validation failed")
print("\n Check response body for validation error details")
elif status == 429:
print(" ā TOO MANY REQUESTS - Rate limit exceeded")
retry_after = response.headers.get('Retry-After')
if retry_after:
print(f"\n ā±ļø Retry after: {retry_after} seconds")
print("\n Suggestions:")
print(" ⢠Add delays between requests")
print(" ⢠Implement exponential backoff")
print(" ⢠Use batch endpoints if available")
print(" ⢠Consider caching responses")
elif 500 <= status < 600:
print(" ā SERVER ERROR - Problem with API server")
print("\n Actions:")
print(" ⢠Check API status page")
print(" ⢠Wait and retry with exponential backoff")
print(" ⢠Contact API support if persists")
print(" ⢠Verify with minimal test request")
# =============================================================================
# DEMONSTRATION
# =============================================================================
if __name__ == "__main__":
# Initialize troubleshooter
troubleshooter = APITroubleshooter("https://jsonplaceholder.typicode.com")
# Example 1: Successful request
print("\n" + "š¢ EXAMPLE 1: Successful GET Request")
troubleshooter.diagnose_request(
"GET",
"/posts/1"
)
input("\nPress Enter to continue to next example...")
# Example 2: 404 Not Found
print("\n" + "š“ EXAMPLE 2: 404 Not Found")
troubleshooter.diagnose_request(
"GET",
"/posts/99999" # Non-existent resource
)
input("\nPress Enter to continue to next example...")
# Example 3: Successful POST
print("\n" + "š¢ EXAMPLE 3: Successful POST Request")
troubleshooter.diagnose_request(
"POST",
"/posts",
headers={"Content-Type": "application/json"},
json={
"title": "Test Post",
"body": "This is a test",
"userId": 1
}
)
input("\nPress Enter to continue to next example...")
# Example 4: Bad Request (simulated with GitHub API)
print("\n" + "š“ EXAMPLE 4: 401 Unauthorized")
github_ts = APITroubleshooter("https://api.github.com")
github_ts.diagnose_request(
"GET",
"/user",
headers={"Authorization": "Bearer invalid_token_12345"}
)
Best Practices for API Troubleshooting
- Start with the status code - it tells you WHERE the problem is
- Read the error response body - it often tells you WHAT is wrong
- Compare your request with documentation examples
- Test with a minimal, simplified request first
- Use debugging tools to inspect raw HTTP traffic
- Check authentication and authorization separately
- Verify data types and JSON syntax
- Look for rate limiting and implement backoff
- Check API status page for outages
- Keep detailed logs for intermittent issues
- Use Postman first: Get the request working in Postman before coding
- Copy as cURL: Browser DevTools can copy requests as cURL commands
- Enable verbose logging: See exactly what's being sent and received
- Test authentication separately: Verify auth works before testing complex requests
- Keep a "working request": Use as reference when new requests fail
- Check for updates: API documentation and behavior can change
š Interactive Python Interpreter
- Write Python code in the editor below
- Click "ā¶ Run Code" to execute
- Output appears in the console below
- Use sample codes for quick testing
- Experiment with status code handling and troubleshooting techniques
- No real network requests (use mock data)
- Limited library support
- Perfect for learning and testing logic