Building a random quotes generator app is one of those projects that sounds simple but teaches you a ton about working with APIs. You get to fetch real data, display it dynamically, and actually build something you'd want to show off. Whether you're brand new to APIs or just looking for a fun weekend project, this free quotes API tutorial walks you through everything step by step.
Here's the thing — most beginners struggle to find a starting project that's practical but not overwhelming. A quote generator hits that sweet spot perfectly. It's small enough to finish in an afternoon, but complex enough to teach you HTTP requests, JSON parsing, and basic error handling. And when you're done, you have a working app you can actually use.
We'll build this in Python first (so you can run it from your terminal), then show you how the same logic applies to a random quote generator in JavaScript for the browser. By the end, you'll know how to pull quotes from a free motivational quotes API, handle errors gracefully, and extend the app however you like.
The API we're using is ZenQuotes API — it's completely free, requires no API key for basic usage, and returns clean JSON data. Perfect for beginners.
What Is a Quotes API?
A quotes API is a web service that returns quote data — usually the quote text, the author's name, and sometimes a category or tag. You send an HTTP GET request to a URL, and the server sends back JSON with the quote details. That's it.
ZenQuotes returns data that looks like this:
[
{
"q": "The best way to get started is to quit talking and begin doing.",
"a": "Walt Disney",
"h": "<blockquote>...</blockquote>"
}
]
The q field is the quote text, a is the author, and h is a pre-formatted HTML version. You'll mostly use q and a in your app.
Why Use a Free Quotes API Instead of a Static List?
You could just hard-code 50 quotes into your app. But that gets boring fast, and you'd have to update it manually. Using a motivational quotes API free of charge gives you access to thousands of quotes without maintaining a database yourself.
Here's what you gain by using an API:
- Fresh, rotating content every time the app runs
- No database setup needed
- Real API experience that transfers to bigger projects
- Cleaner code — the data lives elsewhere, your app just displays it
And since ZenQuotes doesn't require an API key for the random endpoint, there's zero setup friction. You just make a request and get data back.
Step-by-Step Guide: Build a Quote App with the API in Python
Let's build this thing. Open your terminal and make sure you have Python 3 installed. You'll also need the requests library. If you don't have it, run:
pip install requests
Step 1: Fetch a Random Quote
Start with a simple script that pulls one random quote and prints it to the terminal.
import requests
def get_random_quote():
url = "https://zenquotes.io/api/random"
response = requests.get(url)
if response.status_code == 200:
data = response.json()
quote = data[0]["q"]
author = data[0]["a"]
print(f'"{quote}"')
print(f"— {author}")
else:
print(f"Something went wrong. Status code: {response.status_code}")
get_random_quote()
Run this script and you'll see a random quote printed in your terminal. That's your first working API call.
Step 2: Fetch Multiple Quotes at Once
ZenQuotes also has a /quotes endpoint that returns up to 50 quotes in one request. Here's how to use it:
import requests
def get_multiple_quotes():
url = "https://zenquotes.io/api/quotes"
response = requests.get(url)
if response.status_code == 200:
quotes = response.json()
for item in quotes[:5]: # Print first 5 quotes
print(f'"{item["q"]}" — {item["a"]}')
print("-" * 60)
else:
print(f"Request failed. Status code: {response.status_code}")
get_multiple_quotes()
This pulls a batch of quotes and loops through the first five. You can adjust the slice [:5] to show more or fewer quotes.
Step 3: Add a Simple CLI Quote App
Now let's make it interactive. The user can press Enter to get a new quote, or type "quit" to exit.
import requests
def fetch_quote():
url = "https://zenquotes.io/api/random"
try:
response = requests.get(url, timeout=5)
response.raise_for_status()
data = response.json()
return data[0]["q"], data[0]["a"]
except requests.exceptions.Timeout:
return None, "Request timed out. Check your connection."
except requests.exceptions.HTTPError as e:
return None, f"HTTP error: {e}"
except requests.exceptions.RequestException as e:
return None, f"Connection error: {e}"
def run_app():
print("Random Quote Generator — press Enter for a new quote, type 'quit' to exit.\n")
while True:
user_input = input("Press Enter for a quote: ").strip().lower()
if user_input == "quit":
print("See you later.")
break
quote, author = fetch_quote()
if quote:
print(f'\n"{quote}"\n— {author}\n')
else:
print(f"\nCould not fetch quote: {author}\n")
run_app()
This is a real, working CLI app. It handles timeouts, HTTP errors, and connection issues. You can run it any time you need a quick dose of motivation.
Understanding the API Response
When you call https://zenquotes.io/api/random, you always get back a JSON array with one object. Here's what each field means:
| Field | Type | Description |
|---|---|---|
q |
String | The quote text |
a |
String | The author's name |
h |
String | Pre-formatted HTML blockquote |
Always access index [0] on the response because the API wraps everything in a list, even for a single quote.
Error Handling: What Can Go Wrong?
APIs fail sometimes. The server could be down, your internet might cut out, or you might hit a rate limit. Here's how to handle the most common issues:
- Timeout: Always set a
timeoutparameter inrequests.get(). Five seconds is a safe bet. - HTTP errors (4xx, 5xx): Use
response.raise_for_status()to catch these automatically. - JSON parse errors: Wrap
response.json()in a try/except to handle unexpected responses. - Rate limiting: ZenQuotes limits free requests. If you're hitting the API too fast, add a small delay with
time.sleep(1)between calls.
Here's a retry wrapper you can drop into any project:
import requests
import time
def safe_fetch_quote(retries=3):
url = "https://zenquotes.io/api/random"
for attempt in range(retries):
try:
response = requests.get(url, timeout=5)
response.raise_for_status()
data = response.json()
return data[0]["q"], data[0]["a"]
except requests.exceptions.RequestException as e:
print(f"Attempt {attempt + 1} failed: {e}")
time.sleep(2)
return None, "Failed to fetch quote after multiple attempts."
quote, author = safe_fetch_quote()
if quote:
print(f'"{quote}" — {author}')
else:
print(author)
This retries up to three times with a two-second gap between attempts. If all retries fail, it returns a friendly error message instead of crashing.
Build a Quote App with API in JavaScript
Want to take this to the browser? Here's the same idea as a random quote generator in JavaScript. ZenQuotes blocks browser requests due to CORS, so for a front-end version switch to the Quotable API (https://api.quotable.io/random), which is CORS-friendly and also free.
// JavaScript version using Quotable API (CORS-friendly)
async function getRandomQuote() {
try {
const response = await fetch("https://api.quotable.io/random");
if (!response.ok) throw new Error(`HTTP error: ${response.status}`);
const data = await response.json();
document.getElementById("quote").textContent = `"${data.content}"`;
document.getElementById("author").textContent = `— ${data.author}`;
} catch (error) {
document.getElementById("quote").textContent = "Could not load quote.";
console.error(error);
}
}
document.getElementById("new-quote-btn").addEventListener("click", getRandomQuote);
window.onload = getRandomQuote;
Pair this with a simple HTML file that has a #quote paragraph, an #author paragraph, and a button with id new-quote-btn. You'll have a fully working browser app in under 20 lines of code.
Real-World Use Cases
Once you know how to pull quotes from an API, you can wire that into all sorts of projects:
- Daily email digest: Schedule a Python script to email you a motivational quote every morning using
smtplib. - Slack bot: Post a daily quote to your team's Slack channel using the Slack Webhooks API.
- Desktop wallpaper generator: Combine quotes with the
Pillowlibrary to generate wallpaper images automatically. - Blog widget: Embed a live quote widget on your website using the JavaScript fetch version above.
- Terminal startup message: Add the quote fetcher to your shell profile so you see a fresh quote every time you open a terminal.
Frequently Asked Questions
Is the ZenQuotes API completely free?
Yes, the basic random and quotes endpoints are free with no API key required. There are paid tiers for higher rate limits and extra features, but you don't need them for a beginner project.
Do I need to sign up to use this quotes API for beginners?
No sign-up needed for the free endpoints. Just make a GET request to the URL and you'll get data back straight away.
Why does my JavaScript app get a CORS error with ZenQuotes?
ZenQuotes doesn't allow browser-side requests from other domains. Use the Quotable API (https://api.quotable.io/random) instead — it has CORS headers set correctly for browser use.
How often does ZenQuotes update its quote database?
The database is maintained by ZenQuotes and updated periodically. With thousands of quotes available, you're unlikely to see repeats in normal daily usage.
Can I filter quotes by category or author?
The free ZenQuotes tier doesn't support filtering. If you need category-based quotes, try the Quotable API — it supports tags and author filters via query parameters like ?tags=motivational.
What's the rate limit on the free ZenQuotes API?
ZenQuotes limits free users to a set number of requests per hour from the same IP. For personal projects, you're unlikely to hit it. If you do, add time.sleep(1) between requests in your loop.
Conclusion
That's a working quotes generator app built from scratch — with real error handling, a CLI version in Python, and a browser version in JavaScript. You now know how to call a free quotes API, parse JSON responses, handle failures cleanly, and wire up an app around it. The pattern you've learned here carries over to any API you use next.
Pick one of the real-world use cases above and actually build it. The daily email version is a great next step, or try the JavaScript front-end if you want to see something in the browser. The more you build with APIs, the more comfortable you'll get — fast.
Head over to Free API Hub to find more free APIs you can build with — no keys, no paywalls, just clean data ready to use. Start building something today.







