POST Requests
Table of Contents
Understanding POST Requests
POST requests are used to send data to the server to create or submit something new. In REST APIs, POST is one of the most common methods you will use.
This chapter focuses only on what is specific to POST in REST APIs. Concepts like general HTTP methods, status codes, and validation are covered in their own chapters, so we will only touch them when needed for context.
What POST Is Used For
In REST-style APIs, the usual meaning of a POST request is:
- Create a new resource under a collection
- Submit data for processing (for example, login, search, form submission)
- Trigger an action that does not fit well into other methods
Typical examples:
POST /usersto create a new userPOST /ordersto create a new orderPOST /loginto authenticate a userPOST /uploadto upload a file
Rule: In a REST API, POST is usually used on a collection URL (like /users) to create a new resource inside that collection.
Structure of a POST Request
A POST request has:
- A URL that identifies where you send data
- A method:
POST - Optional query parameters in the URL
- A body (the main content you send, often JSON)
- Headers that describe the body (for example,
Content-Type)
Example of a raw HTTP POST request:
POST /users HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer <token>
{
"email": "alice@example.com",
"password": "Secret123!",
"name": "Alice"
}Key parts here:
| Part | Example | Meaning |
|---|---|---|
| Method | POST | We are sending data to the server |
| URL path | /users | Endpoint that receives new user data |
| Header | Content-Type: application/json | Body format is JSON |
| Header (optional) | Authorization: Bearer <token> | Who is making the request |
| Body | JSON object with user information | Data to create a new user |
Common Uses of POST in REST APIs
1. Creating Resources
Most commonly, POST is used to create a new item in a collection.
Example: Creating a blog post
- Request
POST /posts HTTP/1.1
Host: api.example.com
Content-Type: application/json
{
"title": "My first post",
"content": "Hello backend world!",
"tags": ["intro", "backend"]
}- Typical response
HTTP/1.1 201 Created
Location: /posts/123
Content-Type: application/json
{
"id": 123,
"title": "My first post",
"content": "Hello backend world!",
"tags": ["intro", "backend"],
"created_at": "2026-08-26T12:34:56Z"
}Points to notice:
- Status code
201 Createdindicates a new resource was created Locationheader tells where the new resource lives- Response body usually returns the full created resource, including the generated
id
Rule: When a POST successfully creates a resource, prefer status code 201 Created and include the new resource or at least its URI.
2. Submitting Forms
Some actions only submit data for processing and do not create a resource that you later fetch.
Example: Contact form
- Request
POST /contact HTTP/1.1
Content-Type: application/json
{
"name": "Alice",
"email": "alice@example.com",
"message": "Please contact me back."
}- Response
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "received",
"ticket_id": "T-9982"
}
Although this could be considered "creating a ticket", sometimes the client never needs a separate /tickets resource. The key idea is that POST is used to submit data, and the response can be anything meaningful.
3. Login and Other Actions
Example: User login
- Request
POST /login HTTP/1.1
Content-Type: application/json
{
"email": "alice@example.com",
"password": "Secret123!"
}- Response
HTTP/1.1 200 OK
Content-Type: application/json
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "bearer"
}This POST is not creating a user. It is creating a token or a session, or simply performing an authentication action.
POST vs GET, PUT, and PATCH
You will see POST mentioned a lot together with other HTTP methods. Here we only compare how POST is different, not fully define everything.
POST vs GET
| Aspect | GET | POST |
|---|---|---|
| Purpose | Retrieve data | Send data, usually to create or submit |
| Has a body? | Usually no body | Usually has a body |
| Side effects | Should not change state | Often changes state (creates or triggers) |
| Caching | Often cached | Usually not cached |
Rule: Do not use GET to change data. Use POST (or PUT/PATCH/DELETE) for actions that modify server state.
POST vs PUT
A very simple way to remember:
- POST: "Create something new under this URL"
- PUT: "Replace the resource at this URL"
For example:
POST /usersto create a new user with a new IDPUT /users/123to fully replace user 123
POST vs PATCH
- POST: usually for creating or triggering actions
- PATCH: for partially updating an existing resource
For example:
POST /poststo create a new postPATCH /posts/123to change just the title or tags of post 123
Idempotency and POST
An operation is idempotent if running it many times with the same input has the same effect as running it once.
- GET should be idempotent
- PUT and DELETE are defined to be idempotent
- POST is not required to be idempotent
Example of a non idempotent POST:
POST /orders
{
"product_id": 42,
"quantity": 1
}If the client accidentally sends this same request 3 times, you might create 3 identical orders.
Sometimes you want idempotent behavior with POST, for example when creating payments. One common solution is to use an idempotency key:
POST /payments
Idempotency-Key: 43e55b3f-9e7d-4bc8-9c48-7ac4c4a436ca
Content-Type: application/json
{
"amount": 1000,
"currency": "USD",
"customer_id": 7
}
If the server sees the same Idempotency-Key again, it returns the previous result instead of creating a new payment. Idempotency keys are covered more in the advanced idempotency chapter, but you should know that they are often used with POST.
Request Bodies in POST
The most important part of a POST is usually the request body.
Common Body Types
| Content-Type | Description | Example usage |
|---|---|---|
application/json | JSON object or array | Most modern APIs |
application/x-www-form-urlencoded | Key value fields, URL encoded | HTML forms |
multipart/form-data | Mixed data, for example text and files | File uploads |
text/plain | Plain text | Very simple webhooks |
A POST that creates a resource in a JSON API usually uses application/json.
Example: Create a comment
POST /posts/123/comments HTTP/1.1
Content-Type: application/json
{
"author": "Bob",
"text": "Nice article!"
}The server will parse that JSON body, validate it, and store it.
Validation and Error Responses with POST
When you accept data from clients, validation is critical. The details are in the validation and error response chapters, but we will look at how this typically appears with POST.
Example: Validation Failure
Request:
POST /users HTTP/1.1
Content-Type: application/json
{
"email": "not-an-email",
"password": "123",
"name": ""
}The server checks:
emailmust be a valid emailpasswordmust be at least 8 charactersnamecannot be empty
The response could look like this:
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"error": "Validation failed",
"details": {
"email": ["Invalid email address"],
"password": ["Password must be at least 8 characters"],
"name": ["Name is required"]
}
}Common status codes for POST errors:
| Status code | Meaning |
|---|---|
| 400 | Invalid data or malformed request |
| 401 | Not authenticated |
| 403 | Authenticated but not allowed |
| 404 | Parent resource not found (for example /posts/999/comments) |
| 409 | Conflict, for example duplicate email |
| 422 | Unprocessable Entity, often used for validation |
| 500 | Internal server error |
Typical Responses for POST
Different success scenarios usually use different status codes.
201 Created
Most common when a resource is created.
HTTP/1.1 201 Created
Location: /users/42
Content-Type: application/json
{
"id": 42,
"email": "alice@example.com",
"name": "Alice"
}200 OK
Used when the server returns some useful information, but not necessarily a new resource that fits a collection.
Examples:
- Login
- Contact form with confirmation
- Search result from a POST (less common, but possible)
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "success",
"message": "Your message was sent"
}204 No Content
Used when the server successfully processed the request but does not need to return a body.
Example: A POST that triggers an asynchronous job
POST /jobs/rebuild-search-index HTTP/1.1Response:
HTTP/1.1 204 No ContentExamples of POST Endpoints in a Simple API
Imagine a simple task management REST API.
1. Create a Task
Request
POST /tasks HTTP/1.1
Content-Type: application/json
{
"title": "Write chapter about POST",
"description": "Explain POST requests for beginners",
"due_date": "2026-08-30"
}Successful response
HTTP/1.1 201 Created
Location: /tasks/101
Content-Type: application/json
{
"id": 101,
"title": "Write chapter about POST",
"description": "Explain POST requests for beginners",
"due_date": "2026-08-30",
"completed": false,
"created_at": "2026-08-27T09:00:00Z"
}2. Mark a Task as Completed with a POST Action
Sometimes there is debate about whether to use POST or PATCH for actions like "complete task". One common pattern is to use a subresource or action URL with POST.
Request
POST /tasks/101/complete HTTP/1.1Response
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": 101,
"title": "Write chapter about POST",
"completed": true
}Here POST is used to trigger an action: "complete this task".
3. Bulk Create with POST
You can also accept arrays in POST bodies.
Request
POST /tasks/bulk HTTP/1.1
Content-Type: application/json
[
{ "title": "Read REST chapter" },
{ "title": "Practice POST requests" },
{ "title": "Implement /tasks endpoint" }
]Response
HTTP/1.1 201 Created
Content-Type: application/json
[
{
"id": 201,
"title": "Read REST chapter",
"completed": false
},
{
"id": 202,
"title": "Practice POST requests",
"completed": false
},
{
"id": 203,
"title": "Implement /tasks endpoint",
"completed": false
}
]Security Considerations for POST
Even in a basic introduction, you should be aware of some security aspects:
- Never trust client input
- Always validate and sanitize POST bodies
- Check for required fields and correct formats
- Use HTTPS
- POST bodies often contain sensitive data like passwords or personal info
- Without HTTPS, this can be intercepted
- Limit request size
- Attackers can send huge request bodies to exhaust memory
- Most frameworks and servers let you set a maximum body size
- Authentication and authorization
- Some POST endpoints must be accessible only by logged in users
- For example,
POST /admin/usersshould be protected
You will see these topics in more detail in the security and authentication chapters, but they are heavily involved with POST requests since POST is used to change things.
Putting It All Together: A Full Example
Imagine we create a small REST API for notes.
Create a Note
Request
POST /notes HTTP/1.1
Content-Type: application/json
Authorization: Bearer <token>
{
"title": "Shopping list",
"content": "Milk, bread, eggs"
}Response success
HTTP/1.1 201 Created
Location: /notes/10
Content-Type: application/json
{
"id": 10,
"title": "Shopping list",
"content": "Milk, bread, eggs",
"owner_id": 3,
"created_at": "2026-08-27T10:00:00Z"
}Response validation error
HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json
{
"error": "Validation failed",
"details": {
"title": ["Title is required"]
}
}Response unauthorized
HTTP/1.1 401 Unauthorized
Content-Type: application/json
{
"error": "Not authenticated"
}From this one endpoint you can see:
- POST is used to create
/notes/10 - Body is JSON, declared with
Content-Type - Status codes and error structures communicate the result
- Authentication is done with a header, not POST body
Summary
- Use POST to send data to the server, usually to create resources or trigger actions.
- Typical pattern:
POST /collectionto create a new item in that collection. - POST requests usually have a body, often JSON, described by the
Content-Typeheader. - Successful POST that creates something should usually return 201 Created, sometimes with a
Locationheader pointing to the new resource. - POST is not idempotent by default, so repeated POSTs can create multiple resources or trigger actions multiple times.
- Validation, error handling, and security are critical with POST, because POST accepts data that can affect your system.
You will use POST requests constantly when building real REST APIs, especially for creation and submission endpoints.
Views: 8
KAHIBARO