Handling JSON API Responses in JavaScript
Learn how to handle JSON API responses in JavaScript using fetch and .json(). Practical examples of GET, POST, error handling, and parsing response data.
When JavaScript talks to a server, the most common data format is JSON. The browser's fetch function sends the request, and the response object's .json() method reads the body and parses the JSON into a JavaScript object in one step.
async function getUser(id) {
const response = await fetch(`https://api.example.com/users/${id}`);
const user = await response.json();
console.log(user.name);
}The first await waits for the server to respond. The second await reads the response body and parses it as JSON. After both, user is a plain JavaScript object ready to use.
For the fundamentals of converting between JSON strings and objects, see the guide to JSON parse and stringify.
Fetching JSON with GET
A GET request is the most common operation. The pattern has three steps: fetch the URL, check the status, then parse the JSON.
async function fetchPosts() {
const response = await fetch("https://jsonplaceholder.typicode.com/posts");
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return response.json();
}response.ok is true for status codes 200 through 299 and false for errors like 404 or 500. fetch does not throw on error statuses, so checking ok yourself is mandatory. Once you confirm the response is valid, a single call to .json() gives you the parsed data.
The parsed data is a normal JavaScript value. If the API returns an array, you get an array with all the standard methods available. If it returns an object, you can access properties directly.
Sending JSON with POST
To send data to a server, change the method to POST, add the Content-Type header, and stringify your data as the body.
async function createUser(name, email) {
const response = await fetch("https://api.example.com/users", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name, email })
});
if (!response.ok) throw new Error(`Failed: ${response.status}`);
return response.json();
}The Content-Type header tells the server to expect JSON in the request body. The body is the result of JSON.stringify, which converts the JavaScript object into a JSON string. The server typically returns the created resource, which you parse with .json() on the response.
Handling both network and HTTP errors
There are two kinds of errors with APIs. Network errors happen when the request cannot reach the server at all. HTTP errors happen when the server responds but with a failure status code.
async function safeFetch(url) {
try {
const response = await fetch(url);
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return await response.json();
} catch (error) {
console.error("Fetch failed:", error.message);
return null;
}
}The outer try-catch catches network errors like DNS failures or CORS blocks. The inner ok check catches HTTP errors like 404 or 500. The function returns null on any failure instead of crashing, which lets the caller handle the absence of data gracefully.
Checking response content type
Some APIs return HTML error pages instead of JSON when something goes wrong. Checking the Content-Type header before calling .json() prevents unexpected parse errors.
async function parseIfJson(response) {
const contentType = response.headers.get("content-type");
if (contentType && contentType.includes("application/json")) {
return await response.json();
}
console.error("Unexpected response format");
return null;
}This defensive pattern is useful when consuming third-party APIs where you cannot control the error response format. For date formatting within the parsed data, see the guide to formatting dates.
Common mistakes
Forgetting to call .json() on the response and trying to use the response object directly is the most frequent error. The response object is not the data. You must await response.json() to get the parsed body.
Not checking response.ok before parsing assumes the request succeeded. Calling .json() on a 404 response that contains an HTML error page throws a parsing error with a confusing message.
Using .json() twice on the same response throws because the body stream can only be read once. If you need to both log and parse the response, call response.clone().json() for the second read.
Forgetting the Content-Type header on POST requests means the server may not parse your JSON body correctly. Always include "Content-Type": "application/json" when sending JSON data.
Rune AI
Key Insights
- Use fetch(url) for GET and response.json() to parse the JSON body.
- fetch does not throw on 404 or 500. Check response.ok before parsing.
- For POST, set method, headers, and JSON.stringify the body.
- Wrap fetch in try-catch for network errors. Handle HTTP errors separately.
- Use async/await for readable code when processing API responses.
Frequently Asked Questions
Do I need to call JSON.parse on a fetch response?
What happens if the API returns a 404 error?
How do I send JSON in a POST request body?
Conclusion
Handling JSON API responses follows a consistent pattern: call fetch, check if the response is OK, then call response.json() to parse the body. For POST requests, stringify your data and set the Content-Type header. Always handle error statuses explicitly because fetch does not throw on them.
More in this topic
Is JavaScript Frontend or Backend? Full Guide
JavaScript is both a frontend and backend language. Learn the difference between browser JavaScript and Node.js, what each is used for, and which one you should learn first.
Learn JavaScript Step by Step Tutorial with Real Examples
Follow a hands-on tutorial that teaches JavaScript by building a real interactive page. Write your first variables, functions, and event listeners with examples you can run.
JavaScript Tutorial: Complete Beginner's Guide to Programming in 2025
A structured learning path for absolute beginners. Learn what to study first, how to practice, and which JavaScript concepts matter most when you are starting from zero.