10 Free Public APIs for Practice (No Auth Required)
Discover 10 completely free public APIs requiring no authentication — perfect for practicing API calls, building portfolio projects, and learning REST fundamentals.
Get more content like this on Telegram!
Daily AI tips, notes & resources — free
When you're first learning to work with APIs, the authentication layer is often the biggest blocker. You need to create an account, generate a key, set up environment variables, handle token expiry — and all that before you've even written a single fetch call.
These 10 APIs skip all of that. No accounts, no keys, no OAuth flows. Just send a request and get data back. They're perfect for practice projects, coding exercises, tutorials, and building that first portfolio piece that actually does something interesting.
Why Start With No-Auth APIs?
The first time you work with an API, you want to focus on the mechanics: how do you structure a URL, what does JSON look like when it comes back, how do you parse it, how do you handle a 404 or a network error? Authentication is a separate concern that deserves its own focused learning.
Once you're comfortable with the basic request-response cycle, the API authentication guide covers all the auth patterns you'll eventually need. For now, let's keep it simple.
The APIs
1. JSONPlaceholder — Fake REST API for Testing
Base URL: https://jsonplaceholder.typicode.com
JSONPlaceholder is the gold standard for fake data APIs. It simulates a complete REST API with posts, users, comments, todos, albums, and photos — and it accepts writes (POST, PUT, PATCH, DELETE) even though nothing actually gets saved.
// Get all posts
const response = await fetch('https://jsonplaceholder.typicode.com/posts');
const posts = await response.json();
console.log(posts[0]);
// { userId: 1, id: 1, title: "sunt aut facere...", body: "quia et suscipit..." }
// Get a specific user's posts
const userPosts = await fetch('https://jsonplaceholder.typicode.com/posts?userId=1');
// Simulate creating a post
const newPost = await fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ title: 'My Post', body: 'Hello world', userId: 1 })
});
const created = await newPost.json();
console.log(created.id); // 101 (fake but consistent)
Project idea: Build a blog reader app that lists posts, shows individual post detail with comments, and lets you filter by user.
2. Open Trivia Database (OpenTDB)
Base URL: https://opentdb.com/api.php
A database of community-contributed trivia questions across dozens of categories and difficulty levels. Excellent for building quiz apps.
// Get 10 medium difficulty science questions
const res = await fetch(
'https://opentdb.com/api.php?amount=10&category=17&difficulty=medium&type=multiple'
);
const data = await res.json();
data.results.forEach(q => {
console.log(q.question);
console.log('Correct answer:', q.correct_answer);
console.log('Wrong answers:', q.incorrect_answers);
});
Project idea: A timed quiz app with score tracking. Mix difficulties and categories for each round.
3. Open-Meteo — Weather Without API Keys
Base URL: https://api.open-meteo.com/v1/forecast
Most weather APIs require registration and have low free-tier limits. Open-Meteo is genuinely free, open source, and requires no key. It provides accurate hourly and daily forecasts.
// Get weather for New York City
const res = await fetch(
'https://api.open-meteo.com/v1/forecast?latitude=40.71&longitude=-74.01¤t_weather=true&hourly=temperature_2m,precipitation'
);
const weather = await res.json();
console.log(weather.current_weather.temperature); // e.g., 22.4 (Celsius)
console.log(weather.current_weather.windspeed); // km/h
Project idea: A weather dashboard showing current conditions and hourly forecast for any city (you'll need a geocoding API to convert city names to coordinates — also free via Open-Meteo's geocoding endpoint).
4. The Dog API
Base URL: https://dog.ceo/api
Returns random dog images by breed. Sounds trivial but it's genuinely fun to work with and the response shapes are clean and predictable — great for understanding arrays vs objects in responses.
// Random dog image
const res = await fetch('https://dog.ceo/api/breeds/image/random');
const { message: imageUrl, status } = await res.json();
console.log(imageUrl); // "https://images.dog.ceo/breeds/hound-afghan/..."
// All breeds
const breeds = await fetch('https://dog.ceo/api/breeds/list/all');
const { message: breedMap } = await breeds.json();
// breedMap is an object: { "hound": ["afghan", "basset", ...], ... }
// 5 random images of a specific breed
const goldens = await fetch('https://dog.ceo/api/breed/golden/images/random/5');
Project idea: A "dog of the day" app that fetches a random dog on load, lets users filter by breed, and saves favorites to localStorage.
5. REST Countries
Base URL: https://restcountries.com/v3.1
Detailed information about every country in the world — population, currencies, languages, flags, borders, calling codes. One of the most useful no-auth APIs for geographic apps.
// Get all countries
const res = await fetch('https://restcountries.com/v3.1/all?fields=name,capital,population,flags');
const countries = await res.json();
// Search by name
const germany = await fetch('https://restcountries.com/v3.1/name/germany');
// Filter by region
const europe = await fetch('https://restcountries.com/v3.1/region/europe?fields=name,capital,population');
Project idea: A world atlas app where users can search for countries, see key stats, and click on border countries to navigate between them.
6. Chuck Norris Jokes API
Base URL: https://api.chucknorris.io
Lightweight and entertaining. The real value here is the /categories endpoint — it's a good exercise in combining multiple API calls.
// Random joke
const res = await fetch('https://api.chucknorris.io/jokes/random');
const { value: joke } = await res.json();
// Available categories
const cats = await fetch('https://api.chucknorris.io/jokes/categories');
const categories = await cats.json();
// ["animal", "career", "celebrity", "dev", "explicit", ...]
// Joke from specific category
const devJoke = await fetch('https://api.chucknorris.io/jokes/random?category=dev');
// Search jokes
const results = await fetch('https://api.chucknorris.io/jokes/search?query=keyboard');
Project idea: A joke generator where users pick a category from a dropdown (populated from the API) and fetch fresh jokes on demand.
7. The Cat API (No-Auth Tier)
Base URL: https://api.thecatapi.com/v1
The no-auth tier gives access to random cat images and breed information. There is a free API key tier for more features, but the keyless endpoints are enough for practice.
// Random cat image
const res = await fetch('https://api.thecatapi.com/v1/images/search');
const [cat] = await res.json();
console.log(cat.url); // cat image URL
// Random cat with breed info
const withBreed = await fetch('https://api.thecatapi.com/v1/images/search?has_breeds=1');
const [catData] = await withBreed.json();
console.log(catData.breeds[0].name); // "Abyssinian", etc.
// All breeds
const breeds = await fetch('https://api.thecatapi.com/v1/breeds');
Project idea: An animal facts app combining The Cat API and The Dog API. Users pick a species, get a random image and breed information, and can swipe through more.
8. Agify.io — Predict Age from a Name
Base URL: https://api.agify.io
Predicts the most likely age for a name based on statistical data from millions of records. Silly? Yes. But it demonstrates well how query parameters work and how to handle API responses that depend on user input.
// Predict age for a name
const res = await fetch('https://api.agify.io?name=alice');
const data = await res.json();
// { count: 78343, name: "alice", age: 36 }
// With country context (changes predictions)
const byCountry = await fetch('https://api.agify.io?name=alice&country_id=US');
// Batch request (up to 10 names)
const batch = await fetch('https://api.agify.io?name[]=alice&name[]=bob&name[]=charlie');
const results = await batch.json();
// [{ name: "alice", age: 36, ... }, { name: "bob", age: 36, ... }, ...]
Project idea: A "name stats" app that takes a name and country input and displays the statistically predicted age, along with gender (from Genderize.io, also free) and name popularity (from Nationalize.io, also free).
9. icanhazdadjoke
Base URL: https://icanhazdadjoke.com
Dad jokes via API. The interesting thing about this one is that it returns different formats based on the Accept header — JSON, plain text, or HTML. Great for learning content negotiation.
// Get a random joke (JSON)
const res = await fetch('https://icanhazdadjoke.com', {
headers: { 'Accept': 'application/json' }
});
const { joke } = await res.json();
console.log(joke);
// Get as plain text
const textRes = await fetch('https://icanhazdadjoke.com', {
headers: { 'Accept': 'text/plain' }
});
const jokeText = await textRes.text();
// Search jokes
const searchRes = await fetch('https://icanhazdadjoke.com/search?term=dog', {
headers: { 'Accept': 'application/json' }
});
const { results } = await searchRes.json();
Project idea: A daily joke app that stores a new joke per day in localStorage and shows a "new joke" button that fetches from the API only when needed.
10. Open Library — Books Data
Base URL: https://openlibrary.org/api
The Internet Archive's Open Library provides free access to millions of books, authors, and covers. Great for building reading list apps.
// Search for books
const res = await fetch(
'https://openlibrary.org/search.json?q=javascript&limit=5&fields=title,author_name,first_publish_year,isbn'
);
const { docs } = await res.json();
// Get book cover image
// Use ISBN: https://covers.openlibrary.org/b/isbn/0451526538-M.jpg
docs.forEach(book => {
const isbn = book.isbn?.[0];
const cover = isbn ? `https://covers.openlibrary.org/b/isbn/${isbn}-M.jpg` : null;
console.log(book.title, book.author_name?.[0], cover);
});
// Get book details by Open Library key
const details = await fetch('https://openlibrary.org/works/OL82563W.json');
Project idea: A reading list manager where users search for books by title or author, add them to a personal list stored in localStorage, and see cover images and publication years.
Comparison Table
| API | Category | Rate Limit | Response Format | Auth Required | Best For |
|---|---|---|---|---|---|
| JSONPlaceholder | Fake data | None (generous) | JSON | No | REST fundamentals |
| OpenTDB | Trivia | ~5 requests/sec | JSON | No | Quiz apps |
| Open-Meteo | Weather | 10,000/day | JSON | No | Weather apps |
| The Dog API | Animals | 100 images/hr | JSON | No | Image apps |
| REST Countries | Geography | None | JSON | No | Data dashboards |
| Chuck Norris | Jokes | None | JSON | No | Simple fetch practice |
| The Cat API | Animals | 100 images/hr | JSON | No | Image apps |
| Agify.io | Stats | 1,000/day | JSON | No | Form + fetch practice |
| icanhazdadjoke | Jokes | ~100/min | JSON/text | No | Content negotiation |
| Open Library | Books | None | JSON | No | Search apps |
How to Practice Effectively
Fetching data is step one. Here's what to practice beyond that:
Error handling. What happens when the API returns a 404? When the network is down? When the JSON is malformed? Write code that handles all of these gracefully:
async function fetchWithErrorHandling(url) {
try {
const res = await fetch(url);
if (!res.ok) {
throw new Error(`HTTP ${res.status}: ${res.statusText}`);
}
const data = await res.json();
return { data, error: null };
} catch (err) {
return { data: null, error: err.message };
}
}
const { data, error } = await fetchWithErrorHandling('https://dog.ceo/api/breeds/image/random');
if (error) {
console.error('Failed to fetch:', error);
} else {
console.log('Dog image:', data.message);
}
Loading states. Real apps show spinners and skeleton screens while data loads. Practice updating the DOM or React state before and after a fetch call.
Caching. Don't fetch the same data twice if nothing has changed. Store results in a variable or localStorage and only re-fetch after a TTL expires.
Once you've mastered no-auth APIs, the API authentication guide is your natural next step. After that, you might want to look at building your own REST API with Node.js and Express.
The API tutorial for beginners pairs well with this list — it covers the foundational concepts of what an API is and how HTTP requests work before you start coding.
You can also look at MDN's Fetch API documentation for the full reference on how fetch() works and all its options.
Conclusion
No-auth public APIs remove the biggest friction point for beginners: setup. You can go from zero to rendering real data in your browser in under ten minutes with any of these APIs.
My personal recommendation: start with JSONPlaceholder to understand CRUD operations, then move to something more interesting to you — weather, books, animals, geography. Build something you'd actually want to show people, because a project that gets you excited is one you'll finish.
Once you're comfortable making requests, parsing JSON, and handling errors, you're ready for APIs that require authentication — and from there, ready to build your own. The REST API design best practices guide will help you understand how to design clean APIs yourself.
FAQ
Are free public APIs safe to use in production apps?
Most free public APIs are fine for prototypes and personal projects, but you should be careful using them in production. They can change or go offline without notice, often have rate limits that won't scale, and may lack SLAs. If you're building something users depend on, look for paid tiers or self-hosted alternatives. For learning and portfolio projects, they're perfect.
What's the best way to practice calling APIs as a beginner?
Start with Postman or the browser's built-in fetch. Pick one API from this list, read its documentation, and try to get a response. Then write JavaScript or Python code to fetch and display the data. The goal isn't just getting data back — it's understanding request headers, URL structure, query parameters, and how to handle errors in your code.
Do these no-auth APIs have rate limits?
Yes, most do. Even APIs that require no API key have rate limits — they're typically IP-based or based on request frequency. The limits vary from 1 request per second to a few hundred per day. For practice projects this rarely matters, but if you're building something that makes many automated requests, check the docs for the specific limits.
Frequently Asked Questions
AiTechWorlds Team
✓ Verified WriterThe AiTechWorlds team is passionate about AI, technology, and education. We create high-quality, research-backed content to help you learn, grow, and succeed in the modern digital world.
Related Articles
AWS vs Azure vs GCP for Startups: Pricing and Free Tier Guide 2026
AWS, Azure, or GCP for your startup in 2026? Real free tier limits, monthly cost estimates, and honest recommendations based on your actual use case.
How to Use Docker Compose for Local Dev (Node.js + PostgreSQL)
Set up a full local dev environment with Docker Compose, Node.js, PostgreSQL, and pgAdmin. Includes .env config, named volumes, healthchecks, and common error fixes.
5 GraphQL Resolver Best Practices (DataLoader, Error Handling)
Write efficient GraphQL resolvers that don't hammer your database. DataLoader N+1 fix, error handling patterns, auth in context, and resolver performance comparison.
7 Logging Strategies for Microservices (ELK, Loki, Fluentd)
Centralized logging for microservices: compare ELK, Loki, Fluentd, and Datadog with real configs, cost breakdown, and 7 battle-tested strategies.