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.
Plain JSON (this site)
Section titled “Plain JSON (this site)”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.
Fetching from your own project (CORS)
Section titled “Fetching from your own project (CORS)”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
GETwith no custom headers is all you need. Adding headers such asContent-TypeorAuthorizationto aGETmakes 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, soresponse.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 thesrcof an<img>. Images load across origins without any CORS setup.
Countries and flags
Section titled “Countries and flags”/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 nameflag— an object with full URLs to the country’s flag, ornullif there is no flag (currently only the former Netherlands Antilles):rect— the flag in a 4:3 rectanglesquare— 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);Flag images
Section titled “Flag images”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}.svghttps://dg-inclass.github.io/api/countries/flags/1x1/{code}.svgFor 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).
Cities by country
Section titled “Cities by country”/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 namecities— an array of city names (strings) for that country; some countries have an empty array
States by country
Section titled “States by country”/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 nameiso2— the country’s two-letter ISO codeiso3— the country’s three-letter ISO codestates— an array of state/province objects, each with:name— the state or province’s namestate_code— a short code for the state or province
Some countries (e.g. Aland Islands) have no subdivisions, so states is an empty array.
Online APIs
Section titled “Online APIs”Deck of Cards API
Section titled “Deck of Cards API”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.