FreeAPIHub
HomeAPIsAI ModelsAI ToolsBlog
Favorites
FreeAPIHub

The central hub for discovering, testing, and integrating the world's best AI models and APIs.

Platform

  • Categories
  • AI Models
  • APIs

Company

  • About Us
  • Contact
  • FAQ

Help

  • Terms of Service
  • Privacy Policy
  • Cookies

© 2026 FreeAPIHub. All rights reserved.

GitHubTwitterLinkedIn

Table of Contents

  1. 1What Is the Unsplash API?
  2. 2Why Use the Unsplash API Tutorial Approach Over Hardcoded Images?
  3. 3Step-by-Step Setup
  4. 4Code Examples: Working With the Unsplash API
  5. 5Python Example: Basic Fetch
  6. 6Python Example: Search Script With Error Handling
  7. 7Sample Output
  8. 8JavaScript Example: Search Photos With Fetch and Async/Await
  9. 9Sample Console Output
  10. 10Understanding the Output
  11. 11Error Handling: What Breaks and Why
  12. 12Real-World Use Cases
  13. 13Comparison: Unsplash vs Other Free Image APIs
  14. 14FAQ
  15. 15Do I need to pay for the Unsplash API?
  16. 16Is attribution required when using Unsplash photos?
  17. 17How do I get production access for the Unsplash API?
  18. 18Can I use Unsplash photos in a commercial product?
  19. 19What's the difference between /photos/random and /search/photos?
  20. 20Why does the API return null for the description field sometimes?
  21. 21Conclusion

Table of Contents

21 sections

  1. 1What Is the Unsplash API?
  2. 2Why Use the Unsplash API Tutorial Approach Over Hardcoded Images?
  3. 3Step-by-Step Setup
  4. 4Code Examples: Working With the Unsplash API
  5. 5Python Example: Basic Fetch
  6. 6Python Example: Search Script With Error Handling
  7. 7Sample Output
  8. 8JavaScript Example: Search Photos With Fetch and Async/Await
  9. 9Sample Console Output
  10. 10Understanding the Output
  11. 11Error Handling: What Breaks and Why
  12. 12Real-World Use Cases
  13. 13Comparison: Unsplash vs Other Free Image APIs
  14. 14FAQ
  15. 15Do I need to pay for the Unsplash API?
  16. 16Is attribution required when using Unsplash photos?
  17. 17How do I get production access for the Unsplash API?
  18. 18Can I use Unsplash photos in a commercial product?
  19. 19What's the difference between /photos/random and /search/photos?
  20. 20Why does the API return null for the description field sometimes?
  21. 21Conclusion

Trending

1

Flask vs Django vs FastAPI: Choosing the Best Python Web Framework

7 min706
2

Top 7 Free AI Tools for Academic Research and Paper Discovery

7 min530
3

Master API Testing with Postman: A Complete Beginner’s Guide

12 min510
4

Top AI Video Editing Tools Compared for Faster Content Creation

8 min481
5

Top AI Coding Tools to Revolutionize Development in 2026

9 min460
Media APIs
May 10, 20261 views

Unsplash API Tutorial: Fetch Free Royalty-Free Images in Python and JavaScript

Step-by-step Unsplash API tutorial to integrate over 3 million royalty-free images into your apps. Covers authentication, searching, random photos, and proper attribution. Works in Python and JavaScript with full error handling and sample output.

Developer workstation with two monitors showing a Python script fetching Unsplash photo data on the left and a grid of image thumbnails rendering on the right

Developer workstation with two monitors showing a Python script fetching Unsplash photo data on the left and a grid of image thumbnails rendering on the right

FreeAPIHub

You're building a blog, a portfolio, or a small SaaS dashboard, and you need real photos that don't look like cheap stock imagery. Buying licenses isn't an option. Scraping Google Images is a terrible idea. So what do you actually do?

This Unsplash API tutorial walks you through the simplest way to pull high-quality, royalty-free photos straight into your app. By the end, you'll have working Python and JavaScript code that searches Unsplash, grabs random images, and handles the errors you'll definitely hit on your first try.

I'll show you the parts the official docs gloss over — like rate limits, how to credit photographers properly, and what happens when your demo key runs out at 2 AM. Let's get you set up.

What Is the Unsplash API?

Unsplash is a library of over 3 million high-resolution photos, all released under the Unsplash License — free to use commercially, no attribution legally required (though the API terms ask for it). The Unsplash API gives you programmatic access to that library: search by keyword, fetch random photos, browse collections, or pull a specific image by ID.

One thing worth knowing upfront: the demo (free) tier is capped at 50 requests per hour. That sounds tiny, but it's enough for development and small personal projects. Production apps need to apply for production access, which bumps the limit to 5,000 requests per hour.

Why Use the Unsplash API Tutorial Approach Over Hardcoded Images?

Here's why developers reach for this API instead of bundling images into their app:

  • It's free — no credit card, no payment wall, just a developer signup.
  • Massive catalog — over 3 million curated photos, so you'll always find something relevant.
  • Commercial use allowed — the Unsplash License covers most use cases, including paid products.
  • Real search — keyword search returns relevant results, not random matches.
  • Beginner-friendly — REST endpoints, JSON responses, no weird auth flows. Just an access key in a header.

If you've worked with paid stock APIs before, this feels almost suspiciously easy.

Step-by-Step Setup

You'll need three things before writing any code:

  1. A free Unsplash developer account at unsplash.com/developers.
  2. A new application registered in your dashboard — this gives you an Access Key.
  3. Python 3.8+ with the requests library, or Node.js 18+ for the JavaScript example.

Install the Python dependency:

pip install requests

Once you've got your Access Key, treat it like a password. Don't paste it into a public GitHub repo. Use an environment variable in real projects.

Code Examples: Working With the Unsplash API

Below you'll find three working examples. Two in Python, one in JavaScript. Each block is self-contained — copy any one of them and it'll run on its own.

Python Example: Basic Fetch

Let's start small. This pulls a single random photo and prints its URL and photographer.

import requests

# Replace with your real Access Key from unsplash.com/developers
ACCESS_KEY = "YOUR_UNSPLASH_ACCESS_KEY"

# Unsplash random photo endpoint
url = "https://api.unsplash.com/photos/random"

headers = {
    "Authorization": f"Client-ID {ACCESS_KEY}"
}

response = requests.get(url, headers=headers)
response.raise_for_status()  # raises an error on 4xx/5xx

photo = response.json()

print("Photo URL:", photo["urls"]["regular"])
print("Photographer:", photo["user"]["name"])
print("Profile:", photo["user"]["links"]["html"])

That's the whole thing. One GET request, one JSON parse, three print statements. If you swap YOUR_UNSPLASH_ACCESS_KEY for your real key and run it, you'll get a different photo every time.

Python Example: Search Script With Error Handling

Now the version you'd actually use in a project. This one searches Unsplash by keyword, paginates results, and handles the failures you'll hit eventually.

import requests
import time

ACCESS_KEY = "YOUR_UNSPLASH_ACCESS_KEY"
BASE_URL = "https://api.unsplash.com/search/photos"

# Demo tier caps at 50 requests/hour and 30 results per page (max)
MAX_PER_PAGE = 30

def search_unsplash(query, per_page=10, page=1):
    headers = {"Authorization": f"Client-ID {ACCESS_KEY}"}
    params = {
        "query": query,
        "per_page": min(per_page, MAX_PER_PAGE),
        "page": page,
        "orientation": "landscape"  # optional: portrait, landscape, squarish
    }

    try:
        response = requests.get(BASE_URL, headers=headers, params=params, timeout=10)
        response.raise_for_status()
    except requests.exceptions.HTTPError as e:
        if response.status_code == 401:
            print("Auth failed — check your Access Key.")
        elif response.status_code == 403:
            print("Rate limit hit. Demo tier allows 50 requests/hour.")
        else:
            print(f"HTTP error: {e}")
        return []
    except requests.exceptions.Timeout:
        print("Request timed out. Try again in a moment.")
        return []
    except requests.exceptions.RequestException as e:
        print(f"Network error: {e}")
        return []

    data = response.json()
    results = data.get("results", [])

    if not results:
        print(f"No photos found for '{query}'. Try a broader term.")
        return []

    photos = []
    for item in results:
        photos.append({
            "id": item["id"],
            "description": item.get("description") or item.get("alt_description") or "No description",
            "url": item["urls"]["regular"],
            "download": item["links"]["download"],
            "photographer": item["user"]["name"],
            "profile": item["user"]["links"]["html"]
        })
    return photos

if __name__ == "__main__":
    photos = search_unsplash("mountain sunrise", per_page=5)
    for p in photos:
        print(f"\n{p['description']}")
        print(f"  By: {p['photographer']} ({p['profile']})")
        print(f"  Image: {p['url']}")
        time.sleep(0.2)  # be polite to the API

A few things to point out. The orientation parameter saves you from filtering portrait shots out of a landscape gallery. The fallback chain on description handles the fact that not every photo has a written description — some only have alt text, some have neither. And the rate-limit check on 403 is the error most beginners can't decode on their first run.

Sample Output

Mountain peak at golden hour
  By: Sarah Chen (https://unsplash.com/@sarahchen)
  Image: https://images.unsplash.com/photo-1506905925346-21bda4d32df4?ixlib=rb-4.0.3...

Foggy alpine sunrise over rocky ridge
  By: Marco Bianchi (https://unsplash.com/@marcob)
  Image: https://images.unsplash.com/photo-1464822759023-fed622ff2c3b?ixlib=rb-4.0.3...

Snow-capped mountains reflected in still lake
  By: Aiko Tanaka (https://unsplash.com/@aikot)
  Image: https://images.unsplash.com/photo-1454496522488-7a8e488e8606?ixlib=rb-4.0.3...

JavaScript Example: Search Photos With Fetch and Async/Await

Same idea, JavaScript flavor. This is a clean unsplash javascript integration using native fetch — no axios, no extra packages.

// Node.js 18+ or any modern browser
const ACCESS_KEY = "YOUR_UNSPLASH_ACCESS_KEY";
const BASE_URL = "https://api.unsplash.com/search/photos";

// Demo tier: 50 requests/hour, 30 results per page max
async function searchUnsplash(query, perPage = 10) {
  const url = `${BASE_URL}?query=${encodeURIComponent(query)}&per_page=${perPage}&orientation=landscape`;

  try {
    const response = await fetch(url, {
      headers: {
        "Authorization": `Client-ID ${ACCESS_KEY}`
      }
    });

    if (!response.ok) {
      if (response.status === 401) {
        throw new Error("Auth failed — check your Access Key.");
      }
      if (response.status === 403) {
        throw new Error("Rate limit hit. Demo tier = 50 req/hour.");
      }
      throw new Error(`Request failed — HTTP ${response.status}`);
    }

    const data = await response.json();
    const results = data.results ?? [];

    if (results.length === 0) {
      console.log(`No photos found for '${query}'. Try a broader term.`);
      return;
    }

    results.forEach(photo => {
      const description = photo.description || photo.alt_description || "No description";
      console.log(`\n${description}`);
      console.log(`  By: ${photo.user.name} (${photo.user.links.html})`);
      console.log(`  Image: ${photo.urls.regular}`);
    });
  } catch (error) {
    console.error("Search failed:", error.message);
  }
}

searchUnsplash("coffee shop", 5);

Sample Console Output

Latte art on wooden table
  By: Jamie Park (https://unsplash.com/@jamiep)
  Image: https://images.unsplash.com/photo-1495474472287-4d71bcdd2085?ixlib=rb-4.0.3...

Barista pouring espresso into white cup
  By: Liam O'Connor (https://unsplash.com/@liamoc)
  Image: https://images.unsplash.com/photo-1510707577719-ae7c14805e3a?ixlib=rb-4.0.3...

Cozy cafe interior with hanging lights
  By: Priya Sharma (https://unsplash.com/@priyas)
  Image: https://images.unsplash.com/photo-1453614512568-c4024d13c247?ixlib=rb-4.0.3...

Understanding the Output

The Unsplash search response is a JSON object with three top-level fields. Here's what each one means:

  • total — total number of photos matching your query, across all pages.
  • total_pages — how many pages of results exist at your current per_page size.
  • results — the array of actual photo objects. This is what you iterate over.

Inside each photo object, the fields you'll use most:

  • id — unique photo ID. Useful for fetching that exact photo again later.
  • urls.regular — a 1080px-wide version of the image. Good default for most layouts.
  • urls.small, urls.thumb — smaller variants for grids and previews.
  • urls.raw — the full source. You can append your own resize parameters here.
  • user.name — photographer's name. You need this for attribution.
  • user.links.html — link to their Unsplash profile. Also required for attribution.
  • links.download — call this endpoint when a user actually downloads the image. Unsplash requires it for tracking.
  • alt_description — fallback when description is null. Use it for your alt attribute.

Error Handling: What Breaks and Why

This is the part most tutorials skip. Here are the real errors you'll hit:

401 Unauthorized — your Access Key is wrong, missing, or you forgot the Client-ID prefix in the Authorization header. The header value is literally Client-ID xyz123, not just xyz123.

403 Forbidden — you blew through the 50-requests-per-hour demo cap. There's no way around this on the free tier other than waiting an hour or applying for production access. Cache results aggressively.

404 Not Found — usually a typo in the endpoint. /photos/random works. /photo/random (singular) doesn't.

Empty results array — your query was too narrow or misspelled. Try a broader term. "sunset over Mount Fuji at 4 AM in winter" returns nothing. "sunset mountain" returns thousands.

Slow responses — Unsplash is generally fast, but image-heavy responses can take a few seconds. Always set a timeout in requests.get(). I use 10 seconds.

Real-World Use Cases

Here's where this free image api example actually shines in production:

Blog header images. When a writer publishes a post tagged "productivity", auto-fetch a relevant landscape photo for the hero image. Saves hours per week.

Empty-state illustrations. Instead of designing custom empty states for every screen, search by feature name and pick a clean photo as a placeholder.

User profile backgrounds. Let users pick a banner from a curated Unsplash search instead of asking them to upload one. Higher completion rates.

Mood boards and inspiration tools. Build a quick image search api free tool that lets designers compile reference boards by keyword. Dribbble and Notion both use the API for this.

Comparison: Unsplash vs Other Free Image APIs

API Free Limit Catalog Size Auth Required Commercial Use
Unsplash 50 req/hour (demo), 5,000 req/hour (production) 3+ million Access Key Yes
Pexels 200 req/hour, 20,000 req/month 3.2+ million API Key Yes
Pixabay 100 req/minute 4+ million API Key Yes
Lorem Picsum No published limit ~1,000 None Placeholder only

FAQ

Do I need to pay for the Unsplash API?

No. Both the demo and production tiers are free. The demo tier caps at 50 requests per hour, which is enough for development. Production access (5,000/hour) requires a short application but doesn't cost anything.

Is attribution required when using Unsplash photos?

Legally, no — the Unsplash License doesn't require attribution. But the API Terms of Service do require you to credit the photographer with a link to their profile when displaying photos pulled from the API. It's a one-line addition and keeps you compliant.

How do I get production access for the Unsplash API?

Submit your app for review through your Unsplash developer dashboard. They check that you're following the API guidelines (proper attribution, hotlinking images, triggering download events). Approval usually takes a few days.

Can I use Unsplash photos in a commercial product?

Yes. The Unsplash License covers commercial use, including paid SaaS products, client work, and ad campaigns. You can't sell the photos themselves as standalone products or compile them into a competing photo service.

What's the difference between /photos/random and /search/photos?

The random endpoint returns one or more random photos, optionally filtered by query, collection, or topic. The search endpoint returns ranked results based on a keyword query with pagination. Use random for variety, search for relevance.

Why does the API return null for the description field sometimes?

Photographers don't always write descriptions when uploading. Unsplash's machine-generated alt_description usually has something. Always fall back from description to alt_description to a default string before displaying or using it as alt text.

Conclusion

You now have a working royalty free photos api setup that searches over 3 million images, handles errors cleanly, and runs in both Python and JavaScript. The hardest part — figuring out the auth header format and the rate limits — is behind you.

Next step: wire this into a small project. A blog hero image picker, a mood board generator, or a placeholder system for an admin dashboard. The code above is enough to get any of those running in an afternoon.

Looking for more free APIs you can use without a credit card? Browse the Free API Hub directory to find one that fits your next project.

Tags

#unsplash api tutorial#free image api example#royalty free photos api#unsplash javascript integration#image search api free#media apis#python tutorial

Found this helpful?

Share this article with fellow developers or save it for later reference. Your support helps us create more quality content.

Suggested for You

All posts
Comparison of Flask, Django, and FastAPI Python web frameworks
706
7 minProgramming

Flask vs Django vs FastAPI: Choosing the Best Python Web Framework

Read
Illustration of AI tools aiding academic research and paper discovery with digital interface of scientific papers
530
7 minAcademic Research

Top 7 Free AI Tools for Academic Research and Paper Discovery

Read
API testing using Postman interface with sample API requests and responses
510
12 minAPI Development

Master API Testing with Postman: A Complete Beginner’s Guide

Read
Comparison of AI video editing tools showing interface features and video clips
481
8 minVideo Editing

Top AI Video Editing Tools Compared for Faster Content Creation

Read
AI coding tools enhancing software development workflow in 2026
460
9 minSoftware Development

Top AI Coding Tools to Revolutionize Development in 2026

Read