Copy & paste
Resilient code for 25 free APIs
Each snippet calls a working endpoint with a timeout sized from the 7-day latency we measured, retries on 5xx and 429 with exponential backoff and jitter, and fails fast on client errors. Timeouts update with the data: see how they are computed.
Open-Meteo Forecast Weathertimeout 3.5 s
p95 1047 ms, p99 1371 ms over 7 days. Endpoint: live status · official docs
JavaScript
async function get(url, {timeout = 3500, retries = 2} = {}) {
for (let i = 0; i <= retries; i++) {
try {
const res = await fetch(url, { signal: AbortSignal.timeout(timeout) });
if (res.ok) return await res.json();
if (res.status < 500 && res.status !== 429) throw new Error(res.status);
} catch (e) { if (i === retries) throw e; }
await new Promise(r => setTimeout(r, 500 * 2 ** i + Math.random() * 1000)); // backoff + jitter
}
}
const data = await get("https://api.open-meteo.com/v1/forecast?latitude=52.52&longitude=13.41¤t=temperature_2m");Python
import random, time, requests
def get(url, timeout=3.5, retries=2):
for i in range(retries + 1):
try:
r = requests.get(url, timeout=timeout)
if r.ok:
return r.json()
if r.status_code < 500 and r.status_code != 429:
r.raise_for_status()
except requests.RequestException:
if i == retries:
raise
time.sleep(0.5 * 2 ** i + random.random()) # backoff + jitter
data = get("https://api.open-meteo.com/v1/forecast?latitude=52.52&longitude=13.41¤t=temperature_2m")curl
curl --max-time 3.5 --retry 2 --retry-delay 1 --retry-all-errors "https://api.open-meteo.com/v1/forecast?latitude=52.52&longitude=13.41¤t=temperature_2m"Open-Meteo Geocoding Geocodingtimeout 2 s
p95 446 ms, p99 492 ms over 7 days. Endpoint: live status · official docs
JavaScript
async function get(url, {timeout = 2000, retries = 2} = {}) {
for (let i = 0; i <= retries; i++) {
try {
const res = await fetch(url, { signal: AbortSignal.timeout(timeout) });
if (res.ok) return await res.json();
if (res.status < 500 && res.status !== 429) throw new Error(res.status);
} catch (e) { if (i === retries) throw e; }
await new Promise(r => setTimeout(r, 500 * 2 ** i + Math.random() * 1000)); // backoff + jitter
}
}
const data = await get("https://geocoding-api.open-meteo.com/v1/search?name=Berlin&count=1");Python
import random, time, requests
def get(url, timeout=2.0, retries=2):
for i in range(retries + 1):
try:
r = requests.get(url, timeout=timeout)
if r.ok:
return r.json()
if r.status_code < 500 and r.status_code != 429:
r.raise_for_status()
except requests.RequestException:
if i == retries:
raise
time.sleep(0.5 * 2 ** i + random.random()) # backoff + jitter
data = get("https://geocoding-api.open-meteo.com/v1/search?name=Berlin&count=1")curl
curl --max-time 2 --retry 2 --retry-delay 1 --retry-all-errors "https://geocoding-api.open-meteo.com/v1/search?name=Berlin&count=1"OpenStreetMap Nominatim Geocodingtimeout 2 s
p95 544 ms, p99 628 ms over 7 days. Endpoint: live status · official docs
JavaScript
async function get(url, {timeout = 2000, retries = 2} = {}) {
for (let i = 0; i <= retries; i++) {
try {
const res = await fetch(url, { signal: AbortSignal.timeout(timeout) });
if (res.ok) return await res.json();
if (res.status < 500 && res.status !== 429) throw new Error(res.status);
} catch (e) { if (i === retries) throw e; }
await new Promise(r => setTimeout(r, 500 * 2 ** i + Math.random() * 1000)); // backoff + jitter
}
}
const data = await get("https://nominatim.openstreetmap.org/search?q=Berlin&format=json&limit=1");Python
import random, time, requests
def get(url, timeout=2.0, retries=2):
for i in range(retries + 1):
try:
r = requests.get(url, timeout=timeout)
if r.ok:
return r.json()
if r.status_code < 500 and r.status_code != 429:
r.raise_for_status()
except requests.RequestException:
if i == retries:
raise
time.sleep(0.5 * 2 ** i + random.random()) # backoff + jitter
data = get("https://nominatim.openstreetmap.org/search?q=Berlin&format=json&limit=1")curl
curl --max-time 2 --retry 2 --retry-delay 1 --retry-all-errors "https://nominatim.openstreetmap.org/search?q=Berlin&format=json&limit=1"Zippopotam.us Geocodingtimeout 2 s
p95 373 ms, p99 471 ms over 7 days. Endpoint: live status · official docs
JavaScript
async function get(url, {timeout = 2000, retries = 2} = {}) {
for (let i = 0; i <= retries; i++) {
try {
const res = await fetch(url, { signal: AbortSignal.timeout(timeout) });
if (res.ok) return await res.json();
if (res.status < 500 && res.status !== 429) throw new Error(res.status);
} catch (e) { if (i === retries) throw e; }
await new Promise(r => setTimeout(r, 500 * 2 ** i + Math.random() * 1000)); // backoff + jitter
}
}
const data = await get("https://api.zippopotam.us/us/90210");Python
import random, time, requests
def get(url, timeout=2.0, retries=2):
for i in range(retries + 1):
try:
r = requests.get(url, timeout=timeout)
if r.ok:
return r.json()
if r.status_code < 500 and r.status_code != 429:
r.raise_for_status()
except requests.RequestException:
if i == retries:
raise
time.sleep(0.5 * 2 ** i + random.random()) # backoff + jitter
data = get("https://api.zippopotam.us/us/90210")curl
curl --max-time 2 --retry 2 --retry-delay 1 --retry-all-errors "https://api.zippopotam.us/us/90210"Where the ISS at? Open datatimeout 4.5 s
p95 1463 ms, p99 1514 ms over 7 days. Endpoint: live status · official docs
JavaScript
async function get(url, {timeout = 4500, retries = 2} = {}) {
for (let i = 0; i <= retries; i++) {
try {
const res = await fetch(url, { signal: AbortSignal.timeout(timeout) });
if (res.ok) return await res.json();
if (res.status < 500 && res.status !== 429) throw new Error(res.status);
} catch (e) { if (i === retries) throw e; }
await new Promise(r => setTimeout(r, 500 * 2 ** i + Math.random() * 1000)); // backoff + jitter
}
}
const data = await get("https://api.wheretheiss.at/v1/satellites/25544");Python
import random, time, requests
def get(url, timeout=4.5, retries=2):
for i in range(retries + 1):
try:
r = requests.get(url, timeout=timeout)
if r.ok:
return r.json()
if r.status_code < 500 and r.status_code != 429:
r.raise_for_status()
except requests.RequestException:
if i == retries:
raise
time.sleep(0.5 * 2 ** i + random.random()) # backoff + jitter
data = get("https://api.wheretheiss.at/v1/satellites/25544")curl
curl --max-time 4.5 --retry 2 --retry-delay 1 --retry-all-errors "https://api.wheretheiss.at/v1/satellites/25544"World Bank Indicators Open datatimeout 2 s
p95 304 ms, p99 350 ms over 7 days. Endpoint: live status · official docs
JavaScript
async function get(url, {timeout = 2000, retries = 2} = {}) {
for (let i = 0; i <= retries; i++) {
try {
const res = await fetch(url, { signal: AbortSignal.timeout(timeout) });
if (res.ok) return await res.json();
if (res.status < 500 && res.status !== 429) throw new Error(res.status);
} catch (e) { if (i === retries) throw e; }
await new Promise(r => setTimeout(r, 500 * 2 ** i + Math.random() * 1000)); // backoff + jitter
}
}
const data = await get("https://api.worldbank.org/v2/country/br?format=json");Python
import random, time, requests
def get(url, timeout=2.0, retries=2):
for i in range(retries + 1):
try:
r = requests.get(url, timeout=timeout)
if r.ok:
return r.json()
if r.status_code < 500 and r.status_code != 429:
r.raise_for_status()
except requests.RequestException:
if i == retries:
raise
time.sleep(0.5 * 2 ** i + random.random()) # backoff + jitter
data = get("https://api.worldbank.org/v2/country/br?format=json")curl
curl --max-time 2 --retry 2 --retry-delay 1 --retry-all-errors "https://api.worldbank.org/v2/country/br?format=json"USGS Earthquakes Open datatimeout 2.5 s
p95 404 ms, p99 1074 ms over 7 days. Endpoint: live status · official docs
JavaScript
async function get(url, {timeout = 2500, retries = 2} = {}) {
for (let i = 0; i <= retries; i++) {
try {
const res = await fetch(url, { signal: AbortSignal.timeout(timeout) });
if (res.ok) return await res.json();
if (res.status < 500 && res.status !== 429) throw new Error(res.status);
} catch (e) { if (i === retries) throw e; }
await new Promise(r => setTimeout(r, 500 * 2 ** i + Math.random() * 1000)); // backoff + jitter
}
}
const data = await get("https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.geojson");Python
import random, time, requests
def get(url, timeout=2.5, retries=2):
for i in range(retries + 1):
try:
r = requests.get(url, timeout=timeout)
if r.ok:
return r.json()
if r.status_code < 500 and r.status_code != 429:
r.raise_for_status()
except requests.RequestException:
if i == retries:
raise
time.sleep(0.5 * 2 ** i + random.random()) # backoff + jitter
data = get("https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.geojson")curl
curl --max-time 2.5 --retry 2 --retry-delay 1 --retry-all-errors "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.geojson"Nager.Date Holidays Open datatimeout 2 s
p95 236 ms, p99 320 ms over 7 days. Endpoint: live status · official docs
JavaScript
async function get(url, {timeout = 2000, retries = 2} = {}) {
for (let i = 0; i <= retries; i++) {
try {
const res = await fetch(url, { signal: AbortSignal.timeout(timeout) });
if (res.ok) return await res.json();
if (res.status < 500 && res.status !== 429) throw new Error(res.status);
} catch (e) { if (i === retries) throw e; }
await new Promise(r => setTimeout(r, 500 * 2 ** i + Math.random() * 1000)); // backoff + jitter
}
}
const data = await get("https://date.nager.at/api/v3/PublicHolidays/2026/US");Python
import random, time, requests
def get(url, timeout=2.0, retries=2):
for i in range(retries + 1):
try:
r = requests.get(url, timeout=timeout)
if r.ok:
return r.json()
if r.status_code < 500 and r.status_code != 429:
r.raise_for_status()
except requests.RequestException:
if i == retries:
raise
time.sleep(0.5 * 2 ** i + random.random()) # backoff + jitter
data = get("https://date.nager.at/api/v3/PublicHolidays/2026/US")curl
curl --max-time 2 --retry 2 --retry-delay 1 --retry-all-errors "https://date.nager.at/api/v3/PublicHolidays/2026/US"UK Carbon Intensity Open datatimeout 4.5 s
p95 1064 ms, p99 2015 ms over 7 days. Endpoint: live status · official docs
JavaScript
async function get(url, {timeout = 4500, retries = 2} = {}) {
for (let i = 0; i <= retries; i++) {
try {
const res = await fetch(url, { signal: AbortSignal.timeout(timeout) });
if (res.ok) return await res.json();
if (res.status < 500 && res.status !== 429) throw new Error(res.status);
} catch (e) { if (i === retries) throw e; }
await new Promise(r => setTimeout(r, 500 * 2 ** i + Math.random() * 1000)); // backoff + jitter
}
}
const data = await get("https://api.carbonintensity.org.uk/intensity");Python
import random, time, requests
def get(url, timeout=4.5, retries=2):
for i in range(retries + 1):
try:
r = requests.get(url, timeout=timeout)
if r.ok:
return r.json()
if r.status_code < 500 and r.status_code != 429:
r.raise_for_status()
except requests.RequestException:
if i == retries:
raise
time.sleep(0.5 * 2 ** i + random.random()) # backoff + jitter
data = get("https://api.carbonintensity.org.uk/intensity")curl
curl --max-time 4.5 --retry 2 --retry-delay 1 --retry-all-errors "https://api.carbonintensity.org.uk/intensity"Wikipedia REST Open datatimeout 2 s
p95 355 ms, p99 387 ms over 7 days. Endpoint: live status · official docs
JavaScript
async function get(url, {timeout = 2000, retries = 2} = {}) {
for (let i = 0; i <= retries; i++) {
try {
const res = await fetch(url, { signal: AbortSignal.timeout(timeout) });
if (res.ok) return await res.json();
if (res.status < 500 && res.status !== 429) throw new Error(res.status);
} catch (e) { if (i === retries) throw e; }
await new Promise(r => setTimeout(r, 500 * 2 ** i + Math.random() * 1000)); // backoff + jitter
}
}
const data = await get("https://en.wikipedia.org/api/rest_v1/page/summary/Earth");Python
import random, time, requests
def get(url, timeout=2.0, retries=2):
for i in range(retries + 1):
try:
r = requests.get(url, timeout=timeout)
if r.ok:
return r.json()
if r.status_code < 500 and r.status_code != 429:
r.raise_for_status()
except requests.RequestException:
if i == retries:
raise
time.sleep(0.5 * 2 ** i + random.random()) # backoff + jitter
data = get("https://en.wikipedia.org/api/rest_v1/page/summary/Earth")curl
curl --max-time 2 --retry 2 --retry-delay 1 --retry-all-errors "https://en.wikipedia.org/api/rest_v1/page/summary/Earth"Open Library Search Open datatimeout 16.5 s
p95 3627 ms, p99 8192 ms over 7 days. Endpoint: live status · official docs
JavaScript
async function get(url, {timeout = 16500, retries = 2} = {}) {
for (let i = 0; i <= retries; i++) {
try {
const res = await fetch(url, { signal: AbortSignal.timeout(timeout) });
if (res.ok) return await res.json();
if (res.status < 500 && res.status !== 429) throw new Error(res.status);
} catch (e) { if (i === retries) throw e; }
await new Promise(r => setTimeout(r, 500 * 2 ** i + Math.random() * 1000)); // backoff + jitter
}
}
const data = await get("https://openlibrary.org/search.json?q=dune&limit=1");Python
import random, time, requests
def get(url, timeout=16.5, retries=2):
for i in range(retries + 1):
try:
r = requests.get(url, timeout=timeout)
if r.ok:
return r.json()
if r.status_code < 500 and r.status_code != 429:
r.raise_for_status()
except requests.RequestException:
if i == retries:
raise
time.sleep(0.5 * 2 ** i + random.random()) # backoff + jitter
data = get("https://openlibrary.org/search.json?q=dune&limit=1")curl
curl --max-time 16.5 --retry 2 --retry-delay 1 --retry-all-errors "https://openlibrary.org/search.json?q=dune&limit=1"Coinbase Spot Price Cryptotimeout 2 s
p95 289 ms, p99 318 ms over 7 days. Endpoint: live status · official docs
JavaScript
async function get(url, {timeout = 2000, retries = 2} = {}) {
for (let i = 0; i <= retries; i++) {
try {
const res = await fetch(url, { signal: AbortSignal.timeout(timeout) });
if (res.ok) return await res.json();
if (res.status < 500 && res.status !== 429) throw new Error(res.status);
} catch (e) { if (i === retries) throw e; }
await new Promise(r => setTimeout(r, 500 * 2 ** i + Math.random() * 1000)); // backoff + jitter
}
}
const data = await get("https://api.coinbase.com/v2/prices/BTC-USD/spot");Python
import random, time, requests
def get(url, timeout=2.0, retries=2):
for i in range(retries + 1):
try:
r = requests.get(url, timeout=timeout)
if r.ok:
return r.json()
if r.status_code < 500 and r.status_code != 429:
r.raise_for_status()
except requests.RequestException:
if i == retries:
raise
time.sleep(0.5 * 2 ** i + random.random()) # backoff + jitter
data = get("https://api.coinbase.com/v2/prices/BTC-USD/spot")curl
curl --max-time 2 --retry 2 --retry-delay 1 --retry-all-errors "https://api.coinbase.com/v2/prices/BTC-USD/spot"CoinGecko Cryptotimeout 2 s
p95 219 ms, p99 297 ms over 7 days. Endpoint: live status · official docs
JavaScript
async function get(url, {timeout = 2000, retries = 2} = {}) {
for (let i = 0; i <= retries; i++) {
try {
const res = await fetch(url, { signal: AbortSignal.timeout(timeout) });
if (res.ok) return await res.json();
if (res.status < 500 && res.status !== 429) throw new Error(res.status);
} catch (e) { if (i === retries) throw e; }
await new Promise(r => setTimeout(r, 500 * 2 ** i + Math.random() * 1000)); // backoff + jitter
}
}
const data = await get("https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd");Python
import random, time, requests
def get(url, timeout=2.0, retries=2):
for i in range(retries + 1):
try:
r = requests.get(url, timeout=timeout)
if r.ok:
return r.json()
if r.status_code < 500 and r.status_code != 429:
r.raise_for_status()
except requests.RequestException:
if i == retries:
raise
time.sleep(0.5 * 2 ** i + random.random()) # backoff + jitter
data = get("https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd")curl
curl --max-time 2 --retry 2 --retry-delay 1 --retry-all-errors "https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd"Binance Ticker Cryptotimeout 2.5 s
p95 789 ms, p99 885 ms over 7 days. Endpoint: live status · official docs
JavaScript
async function get(url, {timeout = 2500, retries = 2} = {}) {
for (let i = 0; i <= retries; i++) {
try {
const res = await fetch(url, { signal: AbortSignal.timeout(timeout) });
if (res.ok) return await res.json();
if (res.status < 500 && res.status !== 429) throw new Error(res.status);
} catch (e) { if (i === retries) throw e; }
await new Promise(r => setTimeout(r, 500 * 2 ** i + Math.random() * 1000)); // backoff + jitter
}
}
const data = await get("https://api.binance.com/api/v3/ticker/price?symbol=BTCUSDT");Python
import random, time, requests
def get(url, timeout=2.5, retries=2):
for i in range(retries + 1):
try:
r = requests.get(url, timeout=timeout)
if r.ok:
return r.json()
if r.status_code < 500 and r.status_code != 429:
r.raise_for_status()
except requests.RequestException:
if i == retries:
raise
time.sleep(0.5 * 2 ** i + random.random()) # backoff + jitter
data = get("https://api.binance.com/api/v3/ticker/price?symbol=BTCUSDT")curl
curl --max-time 2.5 --retry 2 --retry-delay 1 --retry-all-errors "https://api.binance.com/api/v3/ticker/price?symbol=BTCUSDT"Frankfurter FX Financetimeout 8 s
p95 224 ms, p99 3804 ms over 7 days. Endpoint: live status · official docs
JavaScript
async function get(url, {timeout = 8000, retries = 2} = {}) {
for (let i = 0; i <= retries; i++) {
try {
const res = await fetch(url, { signal: AbortSignal.timeout(timeout) });
if (res.ok) return await res.json();
if (res.status < 500 && res.status !== 429) throw new Error(res.status);
} catch (e) { if (i === retries) throw e; }
await new Promise(r => setTimeout(r, 500 * 2 ** i + Math.random() * 1000)); // backoff + jitter
}
}
const data = await get("https://api.frankfurter.dev/v1/latest?base=USD&symbols=EUR");Python
import random, time, requests
def get(url, timeout=8.0, retries=2):
for i in range(retries + 1):
try:
r = requests.get(url, timeout=timeout)
if r.ok:
return r.json()
if r.status_code < 500 and r.status_code != 429:
r.raise_for_status()
except requests.RequestException:
if i == retries:
raise
time.sleep(0.5 * 2 ** i + random.random()) # backoff + jitter
data = get("https://api.frankfurter.dev/v1/latest?base=USD&symbols=EUR")curl
curl --max-time 8 --retry 2 --retry-delay 1 --retry-all-errors "https://api.frankfurter.dev/v1/latest?base=USD&symbols=EUR"ExchangeRate-API (open) Financetimeout 2 s
p95 189 ms, p99 267 ms over 7 days. Endpoint: live status · official docs
JavaScript
async function get(url, {timeout = 2000, retries = 2} = {}) {
for (let i = 0; i <= retries; i++) {
try {
const res = await fetch(url, { signal: AbortSignal.timeout(timeout) });
if (res.ok) return await res.json();
if (res.status < 500 && res.status !== 429) throw new Error(res.status);
} catch (e) { if (i === retries) throw e; }
await new Promise(r => setTimeout(r, 500 * 2 ** i + Math.random() * 1000)); // backoff + jitter
}
}
const data = await get("https://open.er-api.com/v6/latest/USD");Python
import random, time, requests
def get(url, timeout=2.0, retries=2):
for i in range(retries + 1):
try:
r = requests.get(url, timeout=timeout)
if r.ok:
return r.json()
if r.status_code < 500 and r.status_code != 429:
r.raise_for_status()
except requests.RequestException:
if i == retries:
raise
time.sleep(0.5 * 2 ** i + random.random()) # backoff + jitter
data = get("https://open.er-api.com/v6/latest/USD")curl
curl --max-time 2 --retry 2 --retry-delay 1 --retry-all-errors "https://open.er-api.com/v6/latest/USD"GitHub REST Dev toolstimeout 2 s
p95 463 ms, p99 535 ms over 7 days. Endpoint: live status · official docs
JavaScript
async function get(url, {timeout = 2000, retries = 2} = {}) {
for (let i = 0; i <= retries; i++) {
try {
const res = await fetch(url, { signal: AbortSignal.timeout(timeout) });
if (res.ok) return await res.json();
if (res.status < 500 && res.status !== 429) throw new Error(res.status);
} catch (e) { if (i === retries) throw e; }
await new Promise(r => setTimeout(r, 500 * 2 ** i + Math.random() * 1000)); // backoff + jitter
}
}
const data = await get("https://api.github.com/repos/torvalds/linux");Python
import random, time, requests
def get(url, timeout=2.0, retries=2):
for i in range(retries + 1):
try:
r = requests.get(url, timeout=timeout)
if r.ok:
return r.json()
if r.status_code < 500 and r.status_code != 429:
r.raise_for_status()
except requests.RequestException:
if i == retries:
raise
time.sleep(0.5 * 2 ** i + random.random()) # backoff + jitter
data = get("https://api.github.com/repos/torvalds/linux")curl
curl --max-time 2 --retry 2 --retry-delay 1 --retry-all-errors "https://api.github.com/repos/torvalds/linux"npm Registry Dev toolstimeout 5.5 s
p95 479 ms, p99 2614 ms over 7 days. Endpoint: live status · official docs
JavaScript
async function get(url, {timeout = 5500, retries = 2} = {}) {
for (let i = 0; i <= retries; i++) {
try {
const res = await fetch(url, { signal: AbortSignal.timeout(timeout) });
if (res.ok) return await res.json();
if (res.status < 500 && res.status !== 429) throw new Error(res.status);
} catch (e) { if (i === retries) throw e; }
await new Promise(r => setTimeout(r, 500 * 2 ** i + Math.random() * 1000)); // backoff + jitter
}
}
const data = await get("https://registry.npmjs.org/react/latest");Python
import random, time, requests
def get(url, timeout=5.5, retries=2):
for i in range(retries + 1):
try:
r = requests.get(url, timeout=timeout)
if r.ok:
return r.json()
if r.status_code < 500 and r.status_code != 429:
r.raise_for_status()
except requests.RequestException:
if i == retries:
raise
time.sleep(0.5 * 2 ** i + random.random()) # backoff + jitter
data = get("https://registry.npmjs.org/react/latest")curl
curl --max-time 5.5 --retry 2 --retry-delay 1 --retry-all-errors "https://registry.npmjs.org/react/latest"PyPI JSON Dev toolstimeout 2 s
p95 172 ms, p99 243 ms over 7 days. Endpoint: live status · official docs
JavaScript
async function get(url, {timeout = 2000, retries = 2} = {}) {
for (let i = 0; i <= retries; i++) {
try {
const res = await fetch(url, { signal: AbortSignal.timeout(timeout) });
if (res.ok) return await res.json();
if (res.status < 500 && res.status !== 429) throw new Error(res.status);
} catch (e) { if (i === retries) throw e; }
await new Promise(r => setTimeout(r, 500 * 2 ** i + Math.random() * 1000)); // backoff + jitter
}
}
const data = await get("https://pypi.org/pypi/requests/json");Python
import random, time, requests
def get(url, timeout=2.0, retries=2):
for i in range(retries + 1):
try:
r = requests.get(url, timeout=timeout)
if r.ok:
return r.json()
if r.status_code < 500 and r.status_code != 429:
r.raise_for_status()
except requests.RequestException:
if i == retries:
raise
time.sleep(0.5 * 2 ** i + random.random()) # backoff + jitter
data = get("https://pypi.org/pypi/requests/json")curl
curl --max-time 2 --retry 2 --retry-delay 1 --retry-all-errors "https://pypi.org/pypi/requests/json"httpbin Dev toolstimeout 8.5 s
p95 2733 ms, p99 3790 ms over 7 days. Endpoint: live status · official docs
JavaScript
async function get(url, {timeout = 8500, retries = 2} = {}) {
for (let i = 0; i <= retries; i++) {
try {
const res = await fetch(url, { signal: AbortSignal.timeout(timeout) });
if (res.ok) return await res.json();
if (res.status < 500 && res.status !== 429) throw new Error(res.status);
} catch (e) { if (i === retries) throw e; }
await new Promise(r => setTimeout(r, 500 * 2 ** i + Math.random() * 1000)); // backoff + jitter
}
}
const data = await get("https://httpbin.org/get");Python
import random, time, requests
def get(url, timeout=8.5, retries=2):
for i in range(retries + 1):
try:
r = requests.get(url, timeout=timeout)
if r.ok:
return r.json()
if r.status_code < 500 and r.status_code != 429:
r.raise_for_status()
except requests.RequestException:
if i == retries:
raise
time.sleep(0.5 * 2 ** i + random.random()) # backoff + jitter
data = get("https://httpbin.org/get")curl
curl --max-time 8.5 --retry 2 --retry-delay 1 --retry-all-errors "https://httpbin.org/get"JSONPlaceholder Dev toolstimeout 2 s
p95 182 ms, p99 260 ms over 7 days. Endpoint: live status · official docs
JavaScript
async function get(url, {timeout = 2000, retries = 2} = {}) {
for (let i = 0; i <= retries; i++) {
try {
const res = await fetch(url, { signal: AbortSignal.timeout(timeout) });
if (res.ok) return await res.json();
if (res.status < 500 && res.status !== 429) throw new Error(res.status);
} catch (e) { if (i === retries) throw e; }
await new Promise(r => setTimeout(r, 500 * 2 ** i + Math.random() * 1000)); // backoff + jitter
}
}
const data = await get("https://jsonplaceholder.typicode.com/todos/1");Python
import random, time, requests
def get(url, timeout=2.0, retries=2):
for i in range(retries + 1):
try:
r = requests.get(url, timeout=timeout)
if r.ok:
return r.json()
if r.status_code < 500 and r.status_code != 429:
r.raise_for_status()
except requests.RequestException:
if i == retries:
raise
time.sleep(0.5 * 2 ** i + random.random()) # backoff + jitter
data = get("https://jsonplaceholder.typicode.com/todos/1")curl
curl --max-time 2 --retry 2 --retry-delay 1 --retry-all-errors "https://jsonplaceholder.typicode.com/todos/1"Hacker News (Firebase) Dev toolstimeout 2 s
p95 507 ms, p99 557 ms over 7 days. Endpoint: live status · official docs
JavaScript
async function get(url, {timeout = 2000, retries = 2} = {}) {
for (let i = 0; i <= retries; i++) {
try {
const res = await fetch(url, { signal: AbortSignal.timeout(timeout) });
if (res.ok) return await res.json();
if (res.status < 500 && res.status !== 429) throw new Error(res.status);
} catch (e) { if (i === retries) throw e; }
await new Promise(r => setTimeout(r, 500 * 2 ** i + Math.random() * 1000)); // backoff + jitter
}
}
const data = await get("https://hacker-news.firebaseio.com/v0/topstories.json");Python
import random, time, requests
def get(url, timeout=2.0, retries=2):
for i in range(retries + 1):
try:
r = requests.get(url, timeout=timeout)
if r.ok:
return r.json()
if r.status_code < 500 and r.status_code != 429:
r.raise_for_status()
except requests.RequestException:
if i == retries:
raise
time.sleep(0.5 * 2 ** i + random.random()) # backoff + jitter
data = get("https://hacker-news.firebaseio.com/v0/topstories.json")curl
curl --max-time 2 --retry 2 --retry-delay 1 --retry-all-errors "https://hacker-news.firebaseio.com/v0/topstories.json"PokéAPI Fun & mediatimeout 2 s
p95 219 ms, p99 242 ms over 7 days. Endpoint: live status · official docs
JavaScript
async function get(url, {timeout = 2000, retries = 2} = {}) {
for (let i = 0; i <= retries; i++) {
try {
const res = await fetch(url, { signal: AbortSignal.timeout(timeout) });
if (res.ok) return await res.json();
if (res.status < 500 && res.status !== 429) throw new Error(res.status);
} catch (e) { if (i === retries) throw e; }
await new Promise(r => setTimeout(r, 500 * 2 ** i + Math.random() * 1000)); // backoff + jitter
}
}
const data = await get("https://pokeapi.co/api/v2/pokemon/ditto");Python
import random, time, requests
def get(url, timeout=2.0, retries=2):
for i in range(retries + 1):
try:
r = requests.get(url, timeout=timeout)
if r.ok:
return r.json()
if r.status_code < 500 and r.status_code != 429:
r.raise_for_status()
except requests.RequestException:
if i == retries:
raise
time.sleep(0.5 * 2 ** i + random.random()) # backoff + jitter
data = get("https://pokeapi.co/api/v2/pokemon/ditto")curl
curl --max-time 2 --retry 2 --retry-delay 1 --retry-all-errors "https://pokeapi.co/api/v2/pokemon/ditto"Dog CEO Fun & mediatimeout 2 s
p95 225 ms, p99 262 ms over 7 days. Endpoint: live status · official docs
JavaScript
async function get(url, {timeout = 2000, retries = 2} = {}) {
for (let i = 0; i <= retries; i++) {
try {
const res = await fetch(url, { signal: AbortSignal.timeout(timeout) });
if (res.ok) return await res.json();
if (res.status < 500 && res.status !== 429) throw new Error(res.status);
} catch (e) { if (i === retries) throw e; }
await new Promise(r => setTimeout(r, 500 * 2 ** i + Math.random() * 1000)); // backoff + jitter
}
}
const data = await get("https://dog.ceo/api/breeds/image/random");Python
import random, time, requests
def get(url, timeout=2.0, retries=2):
for i in range(retries + 1):
try:
r = requests.get(url, timeout=timeout)
if r.ok:
return r.json()
if r.status_code < 500 and r.status_code != 429:
r.raise_for_status()
except requests.RequestException:
if i == retries:
raise
time.sleep(0.5 * 2 ** i + random.random()) # backoff + jitter
data = get("https://dog.ceo/api/breeds/image/random")curl
curl --max-time 2 --retry 2 --retry-delay 1 --retry-all-errors "https://dog.ceo/api/breeds/image/random"Datamuse Words Fun & mediatimeout 2 s
p95 386 ms, p99 933 ms over 7 days. Endpoint: live status · official docs
JavaScript
async function get(url, {timeout = 2000, retries = 2} = {}) {
for (let i = 0; i <= retries; i++) {
try {
const res = await fetch(url, { signal: AbortSignal.timeout(timeout) });
if (res.ok) return await res.json();
if (res.status < 500 && res.status !== 429) throw new Error(res.status);
} catch (e) { if (i === retries) throw e; }
await new Promise(r => setTimeout(r, 500 * 2 ** i + Math.random() * 1000)); // backoff + jitter
}
}
const data = await get("https://api.datamuse.com/words?ml=ringing&max=3");Python
import random, time, requests
def get(url, timeout=2.0, retries=2):
for i in range(retries + 1):
try:
r = requests.get(url, timeout=timeout)
if r.ok:
return r.json()
if r.status_code < 500 and r.status_code != 429:
r.raise_for_status()
except requests.RequestException:
if i == retries:
raise
time.sleep(0.5 * 2 ** i + random.random()) # backoff + jitter
data = get("https://api.datamuse.com/words?ml=ringing&max=3")curl
curl --max-time 2 --retry 2 --retry-delay 1 --retry-all-errors "https://api.datamuse.com/words?ml=ringing&max=3"