Ojasa Mirai

Ojasa Mirai

FastAPI

Loading...

Learning Level

🟢 Beginner🔵 Advanced
🚀 HTTP Status Codes📚 2xx Success Codes📚 4xx Client Errors📚 5xx Server Errors📚 Returning Status Codes📚 Custom Status Codes📚 Status Code Best Practices
Fastapi/Status Codes/Status Codes Overview

HTTP Status Codes — Advanced Semantics 🏗️

Understanding status codes deeply enables you to design better APIs and handle edge cases gracefully.

Status Code Selection Strategy

Success Scenarios

from fastapi import status

# 200 OK - Request succeeded, returning data
@app.get("/items/{item_id}")
async def get_item(item_id: int):
    return {"id": item_id}

# 201 Created - New resource created
@app.post("/items", status_code=status.HTTP_201_CREATED)
async def create_item(item: Item):
    new_item = db.create(item)
    return new_item

# 202 Accepted - Request accepted but not complete
@app.post("/process", status_code=status.HTTP_202_ACCEPTED)
async def process_async(data: dict):
    # Queue for background processing
    queue.enqueue(process_task, data)
    return {"status": "processing"}

# 204 No Content - Success but no data
@app.delete("/items/{item_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_item(item_id: int):
    db.delete(item_id)
    return None

Error Scenarios

from fastapi import HTTPException, status

# 400 Bad Request - Malformed request
@app.post("/validate")
async def validate_data(data: dict):
    if not data.get("required_field"):
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="required_field is missing"
        )
    return {"status": "valid"}

# 401 Unauthorized - Authentication missing
@app.get("/protected", dependencies=[Depends(get_current_user)])
async def protected_route():
    return {"data": "secret"}

# 403 Forbidden - Authenticated but not authorized
@app.delete("/admin/users/{user_id}")
async def admin_delete(user_id: int, current_user = Depends(get_current_user)):
    if current_user.role != "admin":
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Only admins can delete"
        )
    db.delete_user(user_id)
    return {"deleted": True}

# 404 Not Found - Resource doesn't exist
@app.get("/items/{item_id}")
async def get_item(item_id: int):
    item = db.get(item_id)
    if not item:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Item not found"
        )
    return item

# 409 Conflict - Request conflicts with current state
@app.post("/users")
async def create_user(user: User):
    if db.user_exists(user.email):
        raise HTTPException(
            status_code=status.HTTP_409_CONFLICT,
            detail="User already exists"
        )
    return db.create_user(user)

# 422 Unprocessable Entity - Validation error
@app.post("/items")
async def create_item(item: Item):
    # FastAPI automatically returns 422 for validation errors
    return db.create(item)

# 429 Too Many Requests - Rate limiting
@app.get("/api/data")
async def get_data(client: str = Header(...)):
    if rate_limit_exceeded(client):
        raise HTTPException(
            status_code=status.HTTP_429_TOO_MANY_REQUESTS,
            detail="Too many requests, please try later"
        )
    return {"data": []}

Error Handling Pattern

from typing import Union

@app.get("/items/{item_id}")
async def get_item(item_id: int):
    try:
        # Try to get item
        item = db.get(item_id)

        # Item doesn't exist
        if not item:
            raise HTTPException(status_code=404, detail="Not found")

        # Success
        return item

    except DatabaseError:
        # Server error
        raise HTTPException(
            status_code=500,
            detail="Database error"
        )
    except Exception as e:
        # Unexpected error
        logger.error(f"Unexpected error: {e}")
        raise HTTPException(
            status_code=500,
            detail="Internal server error"
        )

Choosing the Right Status Code

ScenarioCodeReason
GET succeeds200Standard success
POST creates201Created new resource
PUT/PATCH succeeds200Resource updated
DELETE succeeds204Success, no body
Missing auth401Not authenticated
No permission403Authenticated but denied
Resource missing404Not found
Invalid input400 or 422Bad/unparseable request
Async processing202Accepted, still processing
Rate limited429Too many requests
Server error500+Server problem

🔑 Key Takeaways

  • ✅ Choose status codes based on semantics
  • ✅ 2xx for success with different variants
  • ✅ 4xx for client errors
  • ✅ 5xx for server errors
  • ✅ Use HTTPException to return specific codes
  • ✅ Log unexpected errors
  • ✅ Design for client expectations

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