HTTP 201: Created - Resource Successfully Created
The success code for creation operations in REST APIs
The HTTP 201 "Created" code indicates that the request succeeded and a new resource was created on the server. It's the appropriate response code for POST (and sometimes PUT) requests that create data. It's more precise than 200 because it explicitly informs the client that something new now exists.
In a well-designed REST API, the 201 is systematically accompanied by information to access the new resource: the Location header containing the resource URL, and often the body containing the complete representation of what was created. This rich response allows the client to continue without additional requests.
For monitoring, endpoints returning 201 are often critical: order creation, user registrations, form submissions. A 201 that stops working means your users can no longer create data. MoniTao allows you to monitor these endpoints with POST requests and verify the 201 code.
Meaning of code 201
Code 201 conveys several important pieces of information to the client:
- Creation confirmed: unlike the generic 200, the 201 explicitly confirms that a resource was created. The server doesn't just "succeed" the request, it created something new and persistent.
- Resource available: the new resource exists and is immediately accessible. If it wasn't yet available (asynchronous processing), a 202 Accepted would be used instead.
- Location header: the Location header SHOULD contain the URI of the new resource. This is an important REST convention that lets the client know where to find what it just created.
- Informative body: the body typically contains the representation of the created resource, including server-generated fields (ID, timestamps, etc.).
Use cases for code 201
Here are typical situations where code 201 is appropriate:
- User creation: POST /api/users with registration data. The 201 confirms the account is created, returns the user ID and profile URL.
- E-commerce cart addition: POST /api/cart/items to add a product. The 201 confirms the addition and returns the item with its ID in the cart.
- Form submission: POST /api/contact-requests to send a message. The 201 indicates the request was recorded in the database.
- File upload: POST /api/files with the file as multipart. The 201 returns the uploaded file metadata (URL, size, type).
Implementation example for code 201
Here's how to properly implement a 201 response in your API:
// PHP - Creating a user
public function createUser(Request $request): Response
{
$data = $request->getJson();
// Validation...
$user = User::create([
"name" => $data["name"],
"email" => $data["email"],
]);
return new Response(
json_encode($user),
201, // Created
[
"Content-Type" => "application/json",
"Location" => "/api/users/" . $user->id
]
);
}
// Node.js / Express
app.post("/api/users", async (req, res) => {
const user = await User.create(req.body);
res.status(201)
.location(`/api/users/${user.id}`)
.json(user);
});
Note the key elements: the 201 code, the Location header pointing to the new resource, and the body containing the complete representation with generated fields (id).
Monitoring 201 endpoints
Monitoring creation endpoints is crucial for your business:
- POST requests with body: MoniTao can send POST requests with a test body to verify the creation endpoint works. Configure test data that will be periodically created.
- Verification of 201 code: configure the monitor to alert if the returned code isn't 201. A 500 or 400 means creations are failing.
- Location header verification: ensure the response includes the Location header with a valid URL to the created resource.
- Test data cleanup: create a dedicated test endpoint that cleans up after itself, or use webhooks to delete test resources created by monitoring.
REST API checklist for 201
- POST returns 201 (not 200) for successful creations
- Location header present and contains the resource URI
- Body contains the representation of the created resource
- Generated fields (id, created_at) are included
- Response time acceptable for write operations
- Duplicate handling with 409 Conflict if appropriate
Frequently asked questions about code 201
What's the difference between 200 and 201?
200 is a generic success. 201 is specific: it indicates a resource was created. For a POST that creates data, 201 is semantically correct and more informative.
Must I always return the body with a 201?
It's not required by the HTTP spec, but it's REST best practice. The client receives the resource with its generated fields (ID, timestamps) without an additional GET request.
How to handle duplicates (e.g., email already used)?
Return a 409 Conflict with a message explaining the conflict. Some APIs use 422 Unprocessable Entity. In any case, no 201 if creation didn't happen.
Can PUT return 201?
Yes, if the PUT creates the resource (upsert). If the resource already existed and was updated, use 200 or 204. 201 is reserved for creations.
How to monitor a POST endpoint without polluting the database?
Create a dedicated /api/health/create-test endpoint for monitoring that creates and immediately deletes, or use MoniTao webhooks to clean up test data.
My framework returns 200 by default. How to force 201?
Most frameworks allow specifying the code: response.status(201) in Express, return response(201) in Laravel, HttpResponse(status=201) in Django.
The 201, signature of a well-designed API
Using code 201 correctly is a sign of API maturity. It provides precise semantic information to the client: "I created something new, here's where to find it". Combined with the Location header and an informative body, it allows the client to work efficiently without additional requests.
MoniTao lets you monitor your creation endpoints with configurable POST requests. Verify that code 201 is returned, that the Location header is present, and that response time remains acceptable. A failing creation endpoint directly impacts acquisition and conversions.
Useful Links
Ready to Sleep Soundly?
Start free, no credit card required.