201
Created
2xx Success
What Does HTTP 201 Created Mean?
HTTP 201 Created indicates that the request has been fulfilled and has resulted in one or more new resources being created. This is the standard response for a successful POST request that creates a new entity — whether it is a new user account, a database record, a file upload, or any other resource.
The 201 response should include a Location header that provides the URI of the primary resource created. The response body typically contains a representation of the newly created resource, including any server-generated fields such as an ID, creation timestamp, or default values.
Unlike 200 OK which is a generic success code, 201 carries specific semantic meaning: something new exists on the server that did not exist before this request.
Common Causes
- POST request creating a new resource: The most common scenario. A client submits data (e.g., a user registration form or an API call to create a record), and the server stores it and returns 201.
- PUT to a non-existing resource (upsert): If your API supports creating resources via PUT when the target URI does not yet exist, the server should return 201 (not 200) to indicate creation rather than update.
- File upload completed: When a file is uploaded and stored on the server, 201 is returned along with the URL where the file can be accessed.
- Batch or nested creation: Some APIs create multiple related resources in a single request (e.g., an order with line items). A 201 indicates the primary resource and its children were all created.
Best Practices for Returning 201
- Always include a Location header: This tells the client exactly where to find the newly created resource. Example:
Location: /api/users/42. - Return the created resource in the body: This avoids forcing the client to make a follow-up GET request. Include all fields, especially server-generated ones like
id,created_at, and computed defaults. - Use 201 only when creation happens synchronously: If creation is queued for later processing, use 202 Accepted instead. 201 means the resource exists right now.
- Validate idempotency for retries: If a client retries a POST and the resource already exists, consider returning 200 or 409 Conflict instead of creating a duplicate.
Code Examples
Curl Request/Response
$ curl -i -X POST https://api.example.com/users \
-H "Content-Type: application/json" \
-d '{"name": "Jane Doe", "email": "jane@example.com"}'
HTTP/1.1 201 Created
Location: /api/users/42
Content-Type: application/json
{"id": 42, "name": "Jane Doe", "email": "jane@example.com", "created_at": "2025-01-15T10:30:00Z"}
Express.js (Node.js)
app.post('/api/users', async (req, res) => {
const user = await User.create(req.body);
res.status(201)
.location(`/api/users/${user.id}`)
.json(user);
});
Django REST Framework (Python)
from rest_framework import status
from rest_framework.response import Response
class UserViewSet(viewsets.ModelViewSet):
def create(self, request):
serializer = UserSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = serializer.save()
headers = {'Location': f'/api/users/{user.pk}'}
return Response(
serializer.data,
status=status.HTTP_201_CREATED,
headers=headers
)
Frequently Asked Questions
When should I return HTTP 201 instead of 200?
Return 201 Created whenever a request results in a new resource being stored on the server. This is most commonly used for POST requests that insert new records. Use 200 OK for general success, such as GET requests that fetch data or PUT/PATCH requests that update existing resources. The distinction helps API consumers understand exactly what happened.
Should HTTP 201 include a response body?
Yes, best practice is to include the created resource in the response body. This saves the client from making a separate GET request to retrieve the new resource. Include all fields, especially server-generated values like the ID, creation timestamp, and any computed defaults. Also include a
Location header pointing to the canonical URL.Can PUT requests return 201?
Yes. When a PUT targets a resource that does not exist yet and the server creates it (upsert), 201 is the correct response. If the PUT updates an existing resource, use 200 OK or 204 No Content. This is defined in RFC 9110, Section 9.3.4.