Skip to content

Intermediate · Async JavaScript, modules and tools · topic 41 of 64 · 35 min

fetch and APIs

Explanation

An API is a URL that gives data, usually as JSON, instead of a web page. fetch(url) asks for it and returns a promise of a response. Always check response.ok before reading response.json(), build query strings with URLSearchParams, and show loading, empty and error states. Never put a secret API key in front-end code.

What is an API?

API means Application Programming Interface: a fixed set of requests one program can make to another. On the web, an API is often a URL (an endpoint) that sends back data instead of a page. Most APIs answer in JSON, the text format for objects and arrays you met with localStorage.

Think of it like this: Think of a railway enquiry counter. You do not walk into the control room. You give the clerk a train number in the right format, and you get a fixed-format answer: departure, arrival, platform. The counter is the API, your train number is the request, and the printed slip is the JSON response.
json
{
  "from": "NDLS",
  "to": "BCT",
  "trains": [
    { "number": "12952", "name": "Rajdhani Express", "departs": "16:55" },
    { "number": "12954", "name": "August Kranti Rajdhani", "departs": "17:15" }
  ]
}
A typical JSON response from GET /api/trains?from=NDLS&to=BCT

GET data with fetch

javascript
fetch('/api/trains?from=NDLS&to=BCT')
  .then((response) => {
    if (!response.ok) throw new Error(`HTTP ${response.status}`);
    return response.json(); // reads the body and parses JSON (also a promise)
  })
  .then((data) => console.log(data.trains.length, 'trains'))
  .catch((error) => console.error('Could not load trains:', error.message));
fetch gives a Response; response.json() gives the data
Careful: fetch rejects (goes to catch) only when the request could not happen at all: no internet, wrong domain, or blocked by CORS. A 404 or 500 answer is still a response, so fetch fulfils. You must check response.ok (true for status 200 to 299) yourself.
StatusMeaningWhat your page should do
200 OKSuccess, data is in the bodyShow the data
201 CreatedA new item was saved (after POST)Show "Saved" and the new item
400 Bad RequestThe data you sent is wrongShow which field to fix
401 UnauthorizedNot logged in, or the login expiredSend the user to log in
404 Not FoundNo such item or URLShow "Not found"
429 Too Many RequestsYou asked too often; slow downWait and try again later
500 Internal Server ErrorThe server brokeShow "Something went wrong, try again"

Query strings with URLSearchParams

A query string is the part after ? in a URL, like ?q=rice&page=2. Do not glue it together by hand: spaces, & and other symbols must be encoded. URLSearchParams does this for you.

javascript
const params = new URLSearchParams({ q: 'basmati rice', page: 2 });
console.log(params.toString()); // q=basmati+rice&page=2
const url = `/api/products?${params}`;

// Reading the query string of the current page:
const current = new URLSearchParams(location.search);
console.log(current.get('q'));
URLSearchParams encodes values safely

Sending data with POST

javascript
const response = await fetch('/api/orders', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ itemId: 'p7', qty: 2, pincode: '560001' }),
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const order = await response.json(); // e.g. { id: 991, status: 'placed' }
POST needs a method, a Content-Type header and a JSON string body

CORS in simple words

An origin is the protocol + domain + port of a page, like https://myshop.in. By default, the browser does not let your page read responses from a different origin. The other server must say "this origin is allowed" with a header called Access-Control-Allow-Origin. This rule is CORS (Cross-Origin Resource Sharing). A CORS error in the Console is fixed on the server (or by calling through your own server), not in your fetch code.

Loading, empty and error states

  • Loading: show a spinner or skeleton, and disable the button.
  • Success with data: draw the list.
  • Empty: a friendly message such as "No trains found for this date".
  • Error: a clear message and a "Try again" button. Do not leave a blank page.
Careful: Everything in front-end code is public: anyone can open DevTools and read your JavaScript and every request. Never put a secret API key (for payments, SMS, AI services and so on) in front-end code. Keep it on your own server, and let the browser call your server.
Tip: Open DevTools > Network and filter by Fetch/XHR to see every API call your page makes: the URL, the status code, the headers you sent and the JSON that came back.

Watch the lesson

fetch and APIs · 1/7

API = URL that gives data

Most apps get their data from APIs. An API is a URL that answers with data, usually JSON.

Prefer a video by a teacher? Find free videos on “javascript fetch api json tutorial for beginners” on YouTube ↗

In real life: A PIN code lookup on a delivery site

When you type a 6-digit PIN code on a delivery site, the page calls an API like /api/pincode?code=560001 with fetch. While it waits, the box shows "Checking...". A 200 response fills in the city and state and says "Delivery in 2 days". A 404 shows "We do not deliver here yet". If the network fails, it shows "Could not check, try again". The secret key for the courier's API stays on the site's own server.

Practice (0/3 done)

Task 1 · Code · Javascript

Write buildUrl(base, params). It returns base followed by ? and a query string made with URLSearchParams. If params has no keys, return base without the ?. Examples: buildUrl("https://api.example.com/trains", { from: "NDLS", to: "BCT" }) gives "https://api.example.com/trains?from=NDLS&to=BCT", and buildUrl("https://api.example.com/search", { q: "rice & dal" }) gives "https://api.example.com/search?q=rice+%26+dal".

Task 2 · Code · Javascript

Write async function getJson(fetchFn, url). It calls fetchFn(url) (in a real page fetchFn is fetch; the tests pass a fake one, so there is no network). If response.ok is false, throw new Error("HTTP " + response.status), for example "HTTP 404". Otherwise return the parsed body from response.json().

Task 3 · Practice

Build a "user list" page that loads data from a free practice API with no key, such as https://jsonplaceholder.typicode.com/users. Show "Loading..." first, then draw one card per user (name, email, city) with textContent. Add a search box that filters by name. Then break things on purpose: change the URL to a wrong path to see your error state, and make the filter match nothing to see your empty state.

Quick quiz

Question 1

1.When is response.ok true?

Question 2

2.The server answers your fetch with 404 Not Found. What does fetch do?

Question 3

3.Which status code means "you sent too many requests, slow down"?

Question 4

4.You POST a JavaScript object to an API. What must you send?

Question 5

5.Where should the secret key for an SMS or payment API be kept?

Read more (free)

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

← Previous: Promises and the event loop