pingrobot

HTTP status codes / 201

201 Created — HTTP Status Code

· 3 min read

Short answer

201 Created means the request worked and created one or more new resources. It is the conventional reply when an API POST adds a record or a PUT creates something at a new URL. The response usually includes a Location header pointing at the new resource, and often a body describing it.

201 Created is a success code with one extra promise: the request did not just work, it brought something new into existence. A new user account, an uploaded file, an order, a database row exposed through an API.

What 201 means

RFC 9110 (Section 15.3.2) defines 201 as a request that has been fulfilled and has resulted in one or more new resources being created. The primary new resource is identified either by the Location header in the response or, if there is no Location, by the target URI of the request itself.

That second rule explains the two common patterns:

  • POST to a collection. POST /api/invoices creates an invoice whose URL the server picks, so the response carries Location: /api/invoices/8841.
  • PUT to a specific URL. PUT /files/report.pdf creates the resource at exactly the URL in the request, so Location is optional; the target URI already names it.

The body of a 201 typically describes and links to what was created. Any validator headers such as ETag describe the new resource's current representation.

When you see it

201 is almost entirely an API code. You will meet it in:

  • REST and JSON APIs after creating records: customers, posts, webhooks, API keys.
  • File and object storage after uploads that create new objects.
  • WebDAV after PUT or MKCOL creates a file or collection.
  • Payment and checkout APIs after a payment intent or session is created.

Browsers submitting HTML forms rarely see 201. A form POST usually ends in a redirect, often 303 See Other, so that refreshing the result page does not submit the form twice.

Getting 201 right in your own API

A few conventions make a 201 response easy for clients to use:

  1. Return 201 only when something was actually created. If the request found an existing record (for example an idempotent "create if missing" call), 200 OK is more accurate.
  2. Include Location with the new resource's URL, even if the body also contains an id.
  3. Return the created object in the body so clients have server-generated fields such as id, timestamps and defaults without a follow-up GET.
  4. Use 202 Accepted for work that is not done yet. 201 means the resource exists now. If creation happens later in a queue, 201 would be a false promise.
  5. Make retries safe. Network failures mean clients will sometimes resend a create request. An idempotency key header, checked on the server, prevents duplicates.

On validation failures, return a 4xx instead: 422 Unprocessable Content or 400 Bad Request for bad input, 409 Conflict when the resource already exists and cannot be created again.

How to check it

curl -I sends HEAD, which does not create anything, so use a real POST and print the headers:

curl -s -D - -o /dev/null -X POST https://api.example.com/v1/notes \
  -H "Content-Type: application/json" \
  -d '{"text":"hello"}'

-D - writes the response headers to the terminal. A typical response:

HTTP/2 201
location: /v1/notes/3107
content-type: application/json

Run this kind of test against a staging environment or a test account, since it creates real data each time.

What it means for uptime monitoring

If a monitor ever saw a 201 as the final response, it would count as up: PingRobot's checker treats any final status from 200 to 399 as up. In practice a monitor rarely sees one, because the checker sends a GET with no body, and reads do not create anything. A well-behaved API answers a GET with 200.

That also means an HTTP monitor cannot confirm that your create endpoint works; checking it would require a POST that creates real records every few minutes. Practical alternatives:

  • Monitor a read endpoint on the same API, such as a health route or a lightweight list call. If it is up, the service and its database connection are usually up too.
  • Run a scheduled job that creates and deletes a test record, and have it report to a heartbeat monitor only when both steps succeed. A missed heartbeat then means the write path is broken.

Start monitoring free — 10 monitors, no credit card.

Frequently asked questions

What is the difference between 200 and 201?

Both are success codes. 201 adds a specific fact, that something new now exists. Use 201 when a resource was created and 200 when an existing one was read or updated.

Is the Location header required on a 201?

No. RFC 9110 says the new resource is identified by the Location header if present, and otherwise by the request's target URI. Sending Location is still the clearest choice for API clients.

Should a 201 response include a body?

It may. The RFC says the content typically describes and links to what was created. Many APIs return the new object as JSON so the client does not need a second request.