How to Send a JSON POST Request (With a Live Example)
POST is the method you reach for when you’re sending data to an API rather than just asking for it back — creating a user, submitting a form, kicking off an action. JSON is the most common shape for that data on modern APIs: readable as plain text, and native to both browsers and virtually every backend language.
Getting it right comes down to two things matching what the endpoint expects: the Content-Type header, which tells the server how to parse what follows, and the body itself, which has to be valid JSON in the shape the API actually wants. This guide walks through a real JSON POST request piece by piece, with a live example you can open and send yourself.
The request
Here’s the exact request this guide walks through — a POST to httpbin.org’s /anything endpoint, which accepts any method and body and echoes back exactly what it received. That makes it safe to send for real: no account, no side effects, nothing stored anywhere.
- POST https://httpbin.org/anything
- Content-Type: application/json
- {
- "name": "John Doe",
- "email": "john@example.com"
- }
Example request
Send a JSON POST request
A POST request with a JSON body, sent to httpbin.org’s test endpoint — safe to open and actually send.
POST https://httpbin.org/anythingContent-Type: application/jsonOpen in API Request BuilderWhat each part of the request does
Four things have to line up for this request to work: the method, the URL, the header, and the body.
- POST — tells the endpoint you’re submitting data, not just retrieving it. Most APIs use POST specifically for creating a new resource.
- URL (https://httpbin.org/anything) — the endpoint receiving the request. It echoes back anything sent to it, any method or body, which is what makes it useful for a guide like this one rather than a real API you’d need credentials for.
- Content-Type: application/json — tells the server the body is JSON rather than a query string or form fields, so it parses it correctly instead of guessing or rejecting it outright.
- Request body — the actual data being sent, as a JSON object. What keys and structure it needs to contain depends entirely on the API you’re calling; httpbin.org accepts anything.
How to test a JSON POST request
This is the same request, built step by step in the API Request Builder:
- Open the API Request Builder.
- Select POST as the method.
- Enter https://httpbin.org/anything as the URL.
- Add a header: Content-Type set to application/json.
- Open the Body section.
- Select JSON as the body type.
- Enter the payload.
- Send the request.
- Inspect the response — status code, body, headers, and response time all appear once it comes back.
As a cURL command
Once a request works, the same call can be copied straight out of the request’s code panel — no retyping it by hand:
- curl -X POST 'https://httpbin.org/anything' \
- --max-time 30 \
- -H 'Content-Type: application/json' \
- -d '{
- "name": "John Doe",
- "email": "john@example.com"
- }'
As a JavaScript (Fetch) call
The same request as a fetch() call, ready to paste into frontend code:
- const controller = new AbortController();
- const timeoutId = setTimeout(() => controller.abort(), 30000);
- try {
- const response = await fetch("https://httpbin.org/anything", {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- },
- body: JSON.stringify({
- "name": "John Doe",
- "email": "john@example.com"
- }),
- credentials: "same-origin",
- signal: controller.signal,
- });
- const data = await response.text();
- console.log(data);
- } finally {
- clearTimeout(timeoutId);
- }
As a Python request
And the same request using the requests library:
- import requests
- json_body = {
- "name": "John Doe",
- "email": "john@example.com",
- }
- response = requests.post(
- "https://httpbin.org/anything",
- json=json_body,
- headers={
- "Content-Type": "application/json",
- },
- timeout=30,
- )
- print(response.status_code)
- print(response.text)
Common mistakes
A handful of specific issues account for most "why isn’t my JSON POST working" reports.
- Missing Content-Type — send JSON without this header (or with the wrong value, like text/plain) and many servers won’t parse the body as JSON at all, even though the JSON itself is perfectly valid. The parsing fails before your data is ever looked at.
- Invalid JSON — a trailing comma, an unquoted key, or a stray quote breaks the whole body. {"name": "John Doe",} — a comma after the last field — is invalid JSON and will fail to parse, even though it looks almost right.
- Sending form data instead of JSON — application/x-www-form-urlencoded (key=value pairs joined with &) and application/json are different formats entirely. Setting the header to one while shaping the body like the other is a common way to get a confusing parse error.
- Wrong endpoint — a perfectly valid JSON POST to the wrong URL or path still fails; a 404 or routing error can look similar to a body-parsing error until you check the status code and response body.
- API expects a different schema — valid JSON only means the syntax is correct, not that the server accepts that particular shape. A missing required field or an unexpected key can still get rejected, even though nothing about the JSON itself is malformed.
JSON vs. form data
JSON and form data are both common ways to send a body with POST, but they’re shaped differently and used for different things.
- JSON (Content-Type: application/json) — a structured payload of nested objects, arrays, numbers, and booleans. The default for most modern REST APIs.
- Form data (Content-Type: multipart/form-data) — flat key/value fields, and the only real option once a file is part of the payload; JSON has no native way to carry binary data.
Reading the response
Once the request is sent, four things are worth checking before assuming it worked: the status code first, then the body, the headers, and how long it took.
The status code alone tells you the outcome before you even read the body. 2xx generally means the request succeeded. 4xx means the problem is on the request side — bad input, invalid JSON, missing auth, a wrong URL. 5xx means the request reached the server fine but something failed while handling it.
The response body is worth checking too — httpbin.org echoes back exactly what it received, which is a fast way to confirm the server saw the same body you thought you sent. Response headers and response time round out the picture: Content-Type on the way back tells you how to parse the response, and response time is useful for spotting a slow endpoint before it becomes a production problem.
Browser requests and CORS
A request sent from a tool like this one, or from curl, isn’t subject to CORS — that restriction only applies to JavaScript running in a browser trying to read a cross-origin response. If this exact request works fine here but fails when called from your own frontend’s JavaScript, CORS is the most likely reason, not a problem with the JSON itself.
FAQ
Do I need to set Content-Type manually, or does POST send it automatically?
You need to set it. POST doesn’t imply any particular body format on its own — the method and the body format are independent choices, and the server has no way to know your body is JSON unless the Content-Type header says so.
Why does httpbin.org accept anything I send it?
httpbin.org is a public testing service built specifically for this — its /anything endpoint accepts any method, headers, and body, and echoes them back in the response instead of doing anything with them. It’s useful for confirming a request is shaped the way you think it is, without needing a real backend or credentials.
Can I send a JSON body with a GET request instead of POST?
Technically some tools will let you attach one, but GET requests conventionally don’t carry a body, and many servers, proxies, and caches will ignore or strip it. If you need to send structured data, POST (or PUT/PATCH for updates) is the reliable choice.
What happens if the JSON I send doesn’t match what the API expects?
Valid JSON syntax doesn’t guarantee the API accepts it — the server still validates the JSON against whatever schema it expects. A missing required field or an unexpected shape typically comes back as a 400-range error with a message describing what was wrong, not a parsing failure.
Test this exact request yourself.
Try the free API Request BuilderRelated Guides
- How to Test an API: A Beginner’s Guide to HTTP Requests
What "testing an API" actually means — HTTP methods, headers, query params, request bodies, and auth — with a practical walkthrough of building and reading a request.
- What Is a CORS Error, and How Do You Fix It?
Why "blocked by CORS policy" shows up in your console, what’s actually enforcing it, and the real ways to fix it depending on whether you control the API.
- How to Test an API with Bearer Tokens, API Keys, and Basic Auth
How to test API authentication — Bearer tokens, API keys, and Basic Auth — with live request examples you can open and send in the browser.