A basic GET request

async function getUser() {
  const res = await fetch("https://api.example.com/user");
  const data = await res.json();
  console.log(data);
}
getUser();

The first await waits for the network response; the second waits for the body to be parsed from JSON into a usable object.

Check for errors properly

const res = await fetch(url);
if (!res.ok) {
  throw new Error("Request failed: " + res.status);
}
const data = await res.json();

Important: fetch only rejects on network failure, not on a 404 or 500. You must check res.ok yourself.

Wrap it in try/catch

try {
  const res = await fetch(url);
  const data = await res.json();
} catch (err) {
  console.error("Could not load data", err);
}

Send data with a POST request

await fetch(url, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ name: "Ada" })
});

Common mistakes

  • Forgetting await res.json(). The response body is itself a promise.
  • Assuming fetch throws on a 404. Check res.ok for HTTP errors.
  • Forgetting JSON.stringify on the POST body.

Frequently asked questions

Why does fetch not catch a 404?

fetch treats any completed HTTP response as a success, even error codes. Only a network failure rejects the promise, so check res.ok for status errors.

Do I need axios instead of fetch?

No. fetch is built into every modern browser and Node, and it covers the vast majority of requests without an extra library.

Build real projects with our free JavaScript course.