Public APIs for practising requests
When you press Run, the request goes from your browser straight to the API — our server is not in the middle. Browsers only allow this when the API sends cross-origin (CORS) permission, so these APIs were chosen because they allow it and need no secret key.
Never put private API keys in code that runs in a browser — anyone can read it. Use the APIs below for learning; for keys and private data, use Python on your own computer. New to HTTP? Read the requests lesson first.
JSONPlaceholder Demo GET, POST, PUT, DELETE
Fake REST API with posts, users and todos. Accepts GET, POST, PUT and DELETE (changes are faked, not saved). Best first API: predictable JSON, query parameters like ?userId=1.
Auth: None · Base URL: https://jsonplaceholder.typicode.com/ · Docs ↗
import requests
response = requests.get("https://jsonplaceholder.typicode.com/todos/1", timeout=10)
print("Status:", response.status_code)
data = response.json()
print("Type:", type(data).__name__)
print(str(data)[:300])httpbin Educational GET, POST, PUT, DELETE
Echoes back what you send — great for seeing headers, query parameters, JSON bodies and status codes. Try /status/404 to practise error handling.
Auth: None · Base URL: https://httpbin.org/ · Docs ↗
import requests
response = requests.get("https://httpbin.org/get?lesson=requests", timeout=10)
print("Status:", response.status_code)
data = response.json()
print("Type:", type(data).__name__)
print(str(data)[:300])GitHub REST API Public GET
Public information about users and repositories. No key needed for public data; limited to 60 requests per hour per IP.
Auth: None · Base URL: https://api.github.com/ · Docs ↗
import requests
response = requests.get("https://api.github.com/users/octocat", timeout=10)
print("Status:", response.status_code)
data = response.json()
print("Type:", type(data).__name__)
print(str(data)[:300])Open-Meteo Public GET
Weather forecasts by latitude/longitude, no API key. Good for practising query parameters.
Auth: None · Base URL: https://api.open-meteo.com/ · Docs ↗
import requests
response = requests.get("https://api.open-meteo.com/v1/forecast?latitude=28.61&longitude=77.21¤t=temperature_2m", timeout=10)
print("Status:", response.status_code)
data = response.json()
print("Type:", type(data).__name__)
print(str(data)[:300])PokéAPI Public GET
Data about Pokémon, moves and types — deeply nested JSON to explore.
Auth: None · Base URL: https://pokeapi.co/api/v2/ · Docs ↗
import requests
response = requests.get("https://pokeapi.co/api/v2/pokemon/pikachu", timeout=10)
print("Status:", response.status_code)
data = response.json()
print("Type:", type(data).__name__)
print(str(data)[:300])Dog CEO Public GET
Dog breeds and random dog image URLs.
Auth: None · Base URL: https://dog.ceo/api/ · Docs ↗
import requests
response = requests.get("https://dog.ceo/api/breeds/list/all", timeout=10)
print("Status:", response.status_code)
data = response.json()
print("Type:", type(data).__name__)
print(str(data)[:300])DummyJSON Demo GET, POST, PUT, DELETE
Fake products, carts, users and quotes with search and pagination. Supports ?limit= and ?skip= for pagination practice.
Auth: None · Base URL: https://dummyjson.com/ · Docs ↗
import requests
response = requests.get("https://dummyjson.com/products/1", timeout=10)
print("Status:", response.status_code)
data = response.json()
print("Type:", type(data).__name__)
print(str(data)[:300])REST Countries Public GET
Country names, capitals, populations and flags. Use ?fields= to keep responses small.
Auth: None · Base URL: https://restcountries.com/v3.1/ · Docs ↗
import requests
response = requests.get("https://restcountries.com/v3.1/name/india?fields=name,capital,population", timeout=10)
print("Status:", response.status_code)
data = response.json()
print("Type:", type(data).__name__)
print(str(data)[:300])