Plainwork

Plainwork / Countrydrop: REST Countries v3.1 drop-in API / REST Countries API not working? Fix v3.1 deprecated

REST Countries API not working? Why, and three ways to fix it

If your country list, flag picker or quiz stopped loading, restcountries.com probably answered with "This API version has been deprecated". Here is what changed, how to spot it in your code, and how to get it working again. You can paste your code into the fixer below and it rewrites the URLs for you.

What changed

In mid-2026 REST Countries retired every version before v5. Calls to /v2/ and /v3.1/ now return a 301 redirect to an error file, which itself answers with HTTP 200. We checked on 17 October 2026: curl -L https://restcountries.com/v3.1/name/peru returns:

{"success": false, "data": null,
 "errors": [{"message": "This API version has been deprecated. Please visit
   https://restcountries.com/docs/countries/legacy-api-deprecation to migrate to our new version (v5)."}]}

The new v5 needs an account and an API key, sent as a bearer token. Its free plan allows 1,000 requests a month, and paid plans start at $15 a month for 50,000 (restcountries.com/pricing, read 17 October 2026; REST Countries' README also mentions a free allotment for existing users of the old API). It lives on a new host (api.restcountries.com) with a different response shape.

Three things make this failure confusing:

  • The status can be 200. Code that only checks response.ok carries on, then fails when it reads data[0].name.common from an object with no such field. The country-trivia app showed an endless spinner for exactly this reason.
  • The redirect goes to another host. Code that fetched with mode: "no-cors" or a strict redirect policy can hang or fail without telling you why. web-check's location check timed out this way.
  • Command-line tools see invalid JSON. A shell script that pipes the answer into jq fails with a parse error, as in asn issue #111.

Fix your URLs

Your three options

OptionCode changesKeyGood when
Move to REST Countries v5New host, new response shape: rewrite the parsingYes. Browser use works with a key limited to your site's hostnames, but anyone can copy that key and call it from a server, where no Origin header is sent and the hostname list doesn't apply, so it spends your quota (v5 docs, "Browser usage & CORS")You need live population or the new fields, and have a back end
Vendor a static file (for example mledoze/countries)Replace every URL call with local filteringNoYou only ever load the full list once. Note that mledoze has no population field
Change the host to a v2/v3.1-compatible API (Countrydrop, made by us)One stringNo (free 1,000 requests a day per IP); $4/month key for serversYou want the existing code back today, including searches and fields

Other keyless APIs exist, such as countries.dev. They use their own field names (alpha2Code, flag), so v3.1 code that reads name.common, cca2 or flags.png still has to change. We make Countrydrop, and we say so here; its data is REST Countries' own last v3.1 and v2 release, which is frozen and not updated live. What Countrydrop is and costs · API reference and try-it box.

While you're in there: make it fail loudly

Whatever you choose, check the answer before you use it. Any API can go away, and this outage hid behind a 200:

const r = await fetch(url);
const data = await r.json().catch(() => null);
if (!r.ok || !Array.isArray(data)) {
  throw new Error("Country data unavailable (" + r.status + ")");   // show an error, not a spinner
}

For a single code with ?fields=, v3.1 returns one object rather than an array, so allow for both shapes there.

More from the catalogue

Other small tools

See everything →