POST
When a client needs to submit data for server-side processing, it sends an HTTP POST request.
Usage
A POST request submits an entity to the specified resource. The server determines how to handle the enclosed representation based on the resource's own semantics. Unlike PUT, which targets a specific resource URI, POST delegates processing to the resource identified by the target URI.
The Content-Type header indicates the format of the request body. Three encodings are common in HTML forms and APIs.
application/x-www-form-urlencoded
The default encoding for HTML forms. Data is structured
as key-value pairs separated by ampersands (&), with
keys and values joined by equals signs (=).
Non-alphanumeric characters use
Percent-Encoding.
name=Alice&role=admin
multipart/form-data
Each field occupies a separate part delimited by a boundary string declared in the Content-Type header. This encoding supports binary data such as file uploads. The Content-Disposition header within each part names the field.
text/plain
No prescribed structure. The server processes the raw body according to its own logic.
Repeated POST requests are not idempotent. Submitting the same form twice creates two resources or triggers processing twice, unlike PUT where a repeated request produces the same server state.
POST responses are cacheable only when the response includes explicit freshness information and a matching Content-Location header.
Properties
| Property | Value |
|---|---|
| Safe | No |
| Idempotent | No |
| Cacheable | Conditional |
Example
Form submission
A client submits form data using URL-encoded format. The server creates a job and responds with 201 Created.
Request
POST /jobs HTTP/1.1
Host: api.example.re
Content-Type: application/x-www-form-urlencoded
Content-Length: 17
name=backup&pri=2
Response
HTTP/1.1 201 Created
Location: /jobs/47
Content-Type: application/json
Content-Length: 38
{"id":47,"name":"backup","priority":2}
Multipart file upload
A client uploads a file using multipart encoding. The
boundary string ----Boundary separates each part. The
server accepts the upload and returns
202 Accepted.
Request
POST /uploads HTTP/1.1
Host: api.example.re
Content-Type: multipart/form-data; boundary=----Boundary
Content-Length: 196
------Boundary
Content-Disposition: form-data; name="title"
Q4 Report
------Boundary
Content-Disposition: form-data; name="file"; filename="report.pdf"
Content-Type: application/pdf
<binary data>
------Boundary--
Response
HTTP/1.1 202 Accepted
Location: /uploads/91
Content-Length: 0
JSON API
A client sends a JSON payload to create a new user. The
server returns the created resource with an id field.
Request
POST /users HTTP/1.1
Host: api.example.re
Content-Type: application/json
Content-Length: 41
{"email":"alice@example.re","role":"ops"}
Response
HTTP/1.1 201 Created
Content-Type: application/json
Content-Length: 50
{"id":112,"email":"alice@example.re","role":"ops"}
CORS
POST is a CORS-safelisted method,
but only when the Content-Type is
application/x-www-form-urlencoded,
multipart/form-data, or text/plain. A POST with
application/json or any other content type
triggers a preflight OPTIONS request.
POST vs GET
POST carries data in the request body rather than the URL. This keeps parameters out of browser history, server logs, and Referer headers, making POST better suited for sensitive data.
POST responses are not cached by default and are not bookmarkable. POST is neither safe nor idempotent, so repeated submissions create duplicate resources or trigger processing multiple times.
POST has no practical body size limit, while GET is constrained by URL length limits around 2048 characters.
Cookies with SameSite=Lax block cross-site POST
requests but allow cross-site GET. This gives POST
a degree of built-in CSRF protection that
GET lacks.
Security
POST data does not appear in URLs, browser history, or Referer headers. This reduces the risk of accidental data exposure compared to GET.
POST is still vulnerable to CSRF attacks
without proper tokens. Forms on malicious pages
submit POST requests to other origins
automatically. SameSite=Lax cookies provide
partial protection by blocking cross-site POST
cookie transmission, but dedicated CSRF tokens
remain necessary.
POST over plain HTTP transmits data as cleartext. HTTPS is required to protect the request body in transit.
POST vs PATCH
POST creates new resources at server-chosen URIs. PATCH modifies existing resources at known URIs.
POST delegates processing semantics entirely to the server. PATCH has defined patch formats such as JSON Patch and JSON Merge Patch that describe specific modifications to apply.
When a client needs to update specific fields on an existing resource, PATCH is the appropriate method. POST is for creating new resources or triggering server-side processing.
See also
- RFC 9110: HTTP Semantics - POST
- RFC 2046: MIME Part Two - Multipart
- PUT
- PATCH
- GET
- Content-Type
- HTTP methods