Skip to content

API Data

Every programmer seeking to explore the fetch() API needs samples to code against. Here are some free samples worth exploring that don’t need an API key to get started.

This site serves a few static JSON files (and some images) under /api/ that you can fetch from a course project when you need sample data but don’t want to depend on a live third-party API.

Your project runs on a different origin than this site (e.g. http://localhost:5173 versus https://dg-inclass.github.io), so every request you make to these endpoints is a cross-origin request. Browsers block cross-origin responses unless the server allows them through Cross-Origin Resource Sharing (CORS).

The good news: this site is hosted on GitHub Pages, which sends Access-Control-Allow-Origin: * with every file. That means any page, on any origin, can fetch() these endpoints without an API key, a proxy, or any special options. This applies to every endpoint listed on this page, including any added in the future.

The one thing you must do is use the full URL, not the root-relative path shown in the headings below:

const API_BASE = 'https://dg-inclass.github.io/api';
async function getStates() {
const response = await fetch(`${API_BASE}/countries/states.json`);
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
const json = await response.json();
return json.data; // the array of countries
}

A few more tips:

  • Keep the request simple. A plain GET with no custom headers is all you need. Adding headers such as Content-Type or Authorization to a GET makes the browser send an extra “preflight” request first, and that isn’t needed here.
  • Don’t use mode: 'no-cors'. It hides the response body from your code, so response.json() will fail. The default mode ('cors') is correct.
  • Responses are cached briefly. GitHub Pages lets browsers cache these files for about 10 minutes, so an updated file may take a few minutes to show up.
  • Images don’t need fetch(). To show an image, such as a flag, set it as the src of an <img>. Images load across origins without any CORS setup.

/api/countries/countries.json lists every country along with links to an SVG image of its flag.

It uses the same error / msg / data envelope as the other files. Each entry in data looks like this:

{
"error": false,
"msg": "countries retrieved",
"data": [
{
"iso2": "CA",
"iso3": "CAN",
"name": "Canada",
"flag": {
"rect": "https://dg-inclass.github.io/api/countries/flags/4x3/ca.svg",
"square": "https://dg-inclass.github.io/api/countries/flags/1x1/ca.svg"
}
}
]
}

Each object in data has:

  • iso2 — the country’s two-letter ISO code (e.g. "CA")
  • iso3 — the country’s three-letter ISO code (e.g. "CAN")
  • name — the country’s full name
  • flag — an object with full URLs to the country’s flag, or null if there is no flag (currently only the former Netherlands Antilles):
    • rect — the flag in a 4:3 rectangle
    • square — the flag in a 1:1 square

The iso2 and iso3 codes match the ones in cities.json and states.json, so you can use them to combine data from all three files.

To display a flag, put its URL in an <img>:

const API_BASE = 'https://dg-inclass.github.io/api';
const response = await fetch(`${API_BASE}/countries/countries.json`);
const { data: countries } = await response.json();
const canada = countries.find(c => c.iso2 === 'CA');
const img = document.createElement('img');
img.src = canada.flag.rect;
img.alt = `Flag of ${canada.name}`;
img.width = 64;
document.body.append(img);

The flags are standalone SVG files, so you can link to them directly without the JSON file. The URL pattern uses the lowercase two-letter code:

https://dg-inclass.github.io/api/countries/flags/4x3/{code}.svg
https://dg-inclass.github.io/api/countries/flags/1x1/{code}.svg

For example, flags/4x3/ca.svg is Canada’s flag. If your code is uppercase, call .toLowerCase() on it before you build the URL.

Besides the countries, there are also flags for a few regions and organizations that aren’t in countries.json, such as eu (European Union), un (United Nations), gb-eng (England), gb-sct (Scotland), gb-wls (Wales), and es-ct (Catalonia).

/api/countries/cities.json lists every city known for each country.

The file is a single JSON object with an error flag, a msg string, and a data array — one entry per country:

{
"error": false,
"msg": "countries and cities retrieved",
"data": [
{
"iso2": "AF",
"iso3": "AFG",
"country": "Afghanistan",
"cities": [
"Herat",
"Kabul",
"Kandahar"
]
}
]
}

Each object in data has:

  • iso2 — the country’s two-letter ISO code (e.g. "AF")
  • iso3 — the country’s three-letter ISO code (e.g. "AFG")
  • country — the country’s full name
  • cities — an array of city names (strings) for that country; some countries have an empty array

/api/countries/states.json lists every state or province known for each country.

It follows the same error / msg / data envelope as cities.json, but each entry in data describes states instead of cities:

{
"error": false,
"msg": "countries and states retrieved",
"data": [
{
"name": "Afghanistan",
"iso3": "AFG",
"iso2": "AF",
"states": [
{
"name": "Badakhshan",
"state_code": "BDS"
},
{
"name": "Kabul",
"state_code": "KAB"
}
]
}
]
}

Each object in data has:

  • name — the country’s full name
  • iso2 — the country’s two-letter ISO code
  • iso3 — the country’s three-letter ISO code
  • states — an array of state/province objects, each with:
    • name — the state or province’s name
    • state_code — a short code for the state or province

Some countries (e.g. Aland Islands) have no subdivisions, so states is an empty array.


The Deck of Cards API is a free API that you can use to generate decks of cards along with as many associated piles of cards that you might want for your game.