Skip to main content
Using bare status codes in your responses isn’t recommended. REST framework includes a set of named constants for HTTP status codes that make your code more obvious and readable.

Usage

from rest_framework import status
from rest_framework.response import Response

def my_view(request):
    content = {'message': 'Resource not found'}
    return Response(content, status=status.HTTP_404_NOT_FOUND)

Helper Functions

The status module includes helper functions for testing if a status code is in a given range.

is_informational(code)

Tests if status code is in the 1xx range (100-199).
from rest_framework import status

status.is_informational(100)  # True
status.is_informational(200)  # False

is_success(code)

Tests if status code is in the 2xx range (200-299).
from rest_framework import status

status.is_success(200)  # True
status.is_success(201)  # True
status.is_success(404)  # False

is_redirect(code)

Tests if status code is in the 3xx range (300-399).
from rest_framework import status

status.is_redirect(301)  # True
status.is_redirect(200)  # False

is_client_error(code)

Tests if status code is in the 4xx range (400-499).
from rest_framework import status

status.is_client_error(404)  # True
status.is_client_error(500)  # False

is_server_error(code)

Tests if status code is in the 5xx range (500-599).
from rest_framework import status

status.is_server_error(500)  # True
status.is_server_error(404)  # False

Example: Testing Response Status

from rest_framework import status
from rest_framework.test import APITestCase

class ExampleTestCase(APITestCase):
    def test_create_item(self):
        url = '/api/items/'
        data = {'name': 'Test Item'}
        response = self.client.post(url, data)
        
        # Use helper function to test status
        self.assertTrue(status.is_success(response.status_code))
        
        # Or test specific status
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)

Status Code Constants

Informational - 1xx

Provisional responses indicating the request was received and is being processed.
ConstantValueDescription
HTTP_100_CONTINUE100Continue
HTTP_101_SWITCHING_PROTOCOLS101Switching Protocols
HTTP_102_PROCESSING102Processing
HTTP_103_EARLY_HINTS103Early Hints
from rest_framework import status

status.HTTP_100_CONTINUE
status.HTTP_101_SWITCHING_PROTOCOLS
status.HTTP_102_PROCESSING
status.HTTP_103_EARLY_HINTS

Successful - 2xx

The request was successfully received, understood, and accepted.
ConstantValueDescription
HTTP_200_OK200OK
HTTP_201_CREATED201Created
HTTP_202_ACCEPTED202Accepted
HTTP_203_NON_AUTHORITATIVE_INFORMATION203Non-Authoritative Information
HTTP_204_NO_CONTENT204No Content
HTTP_205_RESET_CONTENT205Reset Content
HTTP_206_PARTIAL_CONTENT206Partial Content
HTTP_207_MULTI_STATUS207Multi-Status
HTTP_208_ALREADY_REPORTED208Already Reported
HTTP_226_IM_USED226IM Used
from rest_framework import status

# Most commonly used
status.HTTP_200_OK              # Generic success
status.HTTP_201_CREATED         # Resource created
status.HTTP_204_NO_CONTENT      # Success with no response body

Redirection - 3xx

Further action needs to be taken to fulfill the request.
ConstantValueDescription
HTTP_300_MULTIPLE_CHOICES300Multiple Choices
HTTP_301_MOVED_PERMANENTLY301Moved Permanently
HTTP_302_FOUND302Found
HTTP_303_SEE_OTHER303See Other
HTTP_304_NOT_MODIFIED304Not Modified
HTTP_305_USE_PROXY305Use Proxy
HTTP_306_RESERVED306Reserved
HTTP_307_TEMPORARY_REDIRECT307Temporary Redirect
HTTP_308_PERMANENT_REDIRECT308Permanent Redirect
from rest_framework import status

status.HTTP_301_MOVED_PERMANENTLY
status.HTTP_302_FOUND
status.HTTP_304_NOT_MODIFIED

Client Error - 4xx

The request contains bad syntax or cannot be fulfilled due to a client error.
ConstantValueDescription
HTTP_400_BAD_REQUEST400Bad Request
HTTP_401_UNAUTHORIZED401Unauthorized
HTTP_402_PAYMENT_REQUIRED402Payment Required
HTTP_403_FORBIDDEN403Forbidden
HTTP_404_NOT_FOUND404Not Found
HTTP_405_METHOD_NOT_ALLOWED405Method Not Allowed
HTTP_406_NOT_ACCEPTABLE406Not Acceptable
HTTP_407_PROXY_AUTHENTICATION_REQUIRED407Proxy Authentication Required
HTTP_408_REQUEST_TIMEOUT408Request Timeout
HTTP_409_CONFLICT409Conflict
HTTP_410_GONE410Gone
HTTP_411_LENGTH_REQUIRED411Length Required
HTTP_412_PRECONDITION_FAILED412Precondition Failed
HTTP_413_REQUEST_ENTITY_TOO_LARGE413Request Entity Too Large
HTTP_414_REQUEST_URI_TOO_LONG414Request-URI Too Long
HTTP_415_UNSUPPORTED_MEDIA_TYPE415Unsupported Media Type
HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE416Requested Range Not Satisfiable
HTTP_417_EXPECTATION_FAILED417Expectation Failed
HTTP_418_IM_A_TEAPOT418I’m a teapot
HTTP_421_MISDIRECTED_REQUEST421Misdirected Request
HTTP_422_UNPROCESSABLE_ENTITY422Unprocessable Entity
HTTP_423_LOCKED423Locked
HTTP_424_FAILED_DEPENDENCY424Failed Dependency
HTTP_425_TOO_EARLY425Too Early
HTTP_426_UPGRADE_REQUIRED426Upgrade Required
HTTP_428_PRECONDITION_REQUIRED428Precondition Required
HTTP_429_TOO_MANY_REQUESTS429Too Many Requests
HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE431Request Header Fields Too Large
HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS451Unavailable For Legal Reasons
from rest_framework import status

# Most commonly used
status.HTTP_400_BAD_REQUEST     # Invalid request data
status.HTTP_401_UNAUTHORIZED    # Authentication required
status.HTTP_403_FORBIDDEN       # Permission denied
status.HTTP_404_NOT_FOUND       # Resource not found
status.HTTP_422_UNPROCESSABLE_ENTITY  # Validation error
status.HTTP_429_TOO_MANY_REQUESTS     # Rate limit exceeded

Server Error - 5xx

The server failed to fulfill an apparently valid request.
ConstantValueDescription
HTTP_500_INTERNAL_SERVER_ERROR500Internal Server Error
HTTP_501_NOT_IMPLEMENTED501Not Implemented
HTTP_502_BAD_GATEWAY502Bad Gateway
HTTP_503_SERVICE_UNAVAILABLE503Service Unavailable
HTTP_504_GATEWAY_TIMEOUT504Gateway Timeout
HTTP_505_HTTP_VERSION_NOT_SUPPORTED505HTTP Version Not Supported
HTTP_506_VARIANT_ALSO_NEGOTIATES506Variant Also Negotiates
HTTP_507_INSUFFICIENT_STORAGE507Insufficient Storage
HTTP_508_LOOP_DETECTED508Loop Detected
HTTP_509_BANDWIDTH_LIMIT_EXCEEDED509Bandwidth Limit Exceeded
HTTP_510_NOT_EXTENDED510Not Extended
HTTP_511_NETWORK_AUTHENTICATION_REQUIRED511Network Authentication Required
from rest_framework import status

status.HTTP_500_INTERNAL_SERVER_ERROR
status.HTTP_503_SERVICE_UNAVAILABLE

Common Usage Patterns

Successful Operations

from rest_framework import status
from rest_framework.response import Response

# List/Retrieve - return existing data
return Response(data, status=status.HTTP_200_OK)

# Create - return newly created resource
return Response(serializer.data, status=status.HTTP_201_CREATED)

# Update - return updated resource
return Response(serializer.data, status=status.HTTP_200_OK)

# Delete - no content to return
return Response(status=status.HTTP_204_NO_CONTENT)

Client Errors

from rest_framework import status
from rest_framework.response import Response

# Validation failed
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

# Authentication required
return Response(
    {'detail': 'Authentication required'},
    status=status.HTTP_401_UNAUTHORIZED
)

# Permission denied
return Response(
    {'detail': 'Permission denied'},
    status=status.HTTP_403_FORBIDDEN
)

# Resource not found
return Response(
    {'detail': 'Not found'},
    status=status.HTTP_404_NOT_FOUND
)

References

  • RFC 2616 - HTTP/1.1 Status Code Definitions
  • RFC 6585 - Additional HTTP Status Codes
  • RFC 4918 - HTTP Extensions for WebDAV

See Also

Build docs developers (and LLMs) love