← Blog

Search Wikimedia Commons From Google Sheets With a Custom Function

Use the free Wikimedia Commons API in Google Sheets: a short Apps Script function that returns free images with license, author and thumbnail.

Wikimedia Commons is the media library behind Wikipedia. Over 100 million free photos, drawings, videos and scans. It has a free API with no key and no sign-up, and you can call it from Google Sheets with about 25 lines of Apps Script.

This post shows the whole function, how each part works, and how to show the pictures right in your cells with =IMAGE(). At the end, I’ll show the free template I built on top of the same API, if you’d rather not paste code.

TL;DR

  • One call to commons.wikimedia.org/w/api.php with generator=search returns files plus their license, author and a thumbnail URL.
  • Send an Api-User-Agent header with your contact; Wikimedia asks every script to name itself.
  • Sort by the index field, or your results come back out of search order.

Who this is for

  • Google Sheets power user: learn a real API call you can reuse for any JSON API.
  • Blogger or content manager: pull free images and their credits into your content calendar.
  • Teacher: build a sheet of real pictures for a lesson, with licenses next to each.
  • Apps Script beginner: a small, working custom function to learn from.
  • Marketer: a picture research sheet for a campaign, without a stock subscription.

Before you start

  • A Google Sheet (any sheet, a blank one is fine)
  • Extensions > Apps Script access
  • Your email or website, for the User-Agent

How the API call works

Here’s the request for “red panda”, 10 results:

https://commons.wikimedia.org/w/api.php?action=query&format=json&formatversion=2
  &generator=search&gsrnamespace=6&gsrlimit=10&gsrsearch=red%20panda
  &prop=imageinfo&iiprop=url|extmetadata&iiurlwidth=330
  &iiextmetadatafilter=LicenseShortName|Artist

What each part means:

  • generator=search: run a search, then return details for each result in the same call.
  • gsrnamespace=6: only search files. Namespace 6 is the File namespace on Commons.
  • gsrsearch: your words. Commons search tricks work here, like "exact phrase", -word, filetype:video or filew:>3000.
    • prop=imageinfo with **iiprop=url: extmetadata**: the file URL plus its metadata.
  • iiurlwidth=330: also give me a thumbnail 330 pixels wide.
  • iiextmetadatafilter: only the license and author fields, so the answer stays small.

Open it in a browser and you’ll see JSON with a pages list.

The function

Open Extensions > Apps Script, delete what’s there, paste this, and save:

function COMMONSSEARCH(search, count) {
  var url = 'https://commons.wikimedia.org/w/api.php?action=query&format=json&formatversion=2' +
    '&generator=search&gsrnamespace=6&gsrlimit=' + (count || 10) +
    '&gsrsearch=' + encodeURIComponent(search) +
    '&prop=imageinfo&iiprop=url|extmetadata&iiurlwidth=330' +
    '&iiextmetadatafilter=LicenseShortName|Artist';
  var res = UrlFetchApp.fetch(url, {
    muteHttpExceptions: true,
    headers: { 'Api-User-Agent': 'MySheet/1.0 ([email protected])' }
  });
  if (res.getResponseCode() !== 200) return 'Commons did not answer. Try again in a minute.';
  var pages = (JSON.parse(res.getContentText()).query || {}).pages || [];
  pages.sort(function (a, b) { return a.index - b.index; });
  var rows = [['TITLE', 'LICENSE', 'AUTHOR', 'THUMBNAIL', 'FILE URL']];
  pages.forEach(function (p) {
    var info = p.imageinfo && p.imageinfo[0];
    if (!info) return;
    var meta = info.extmetadata || {};
    var get = function (k) {
      return meta[k] ? String(meta[k].value).replace(/<[^>]*>/g, '').trim() : '';
    };
    rows.push([p.title.replace(/^File:/, ''), get('LicenseShortName'), get('Artist'), info.thumburl, info.url]);
  });
  return rows;
}

Change [email protected] to your own email or website.

Back in the sheet, type in A1:

=COMMONSSEARCH("red panda", 10)

Give it a few seconds. You get a header row and one row per file: title, license, author, thumbnail URL and full-size file URL.

Why each piece is there

  • encodeURIComponent turns spaces and quotes in your search into URL-safe text.
  • Api-User-Agent: Wikimedia asks every script to say who it is and how to reach you. Apps Script doesn’t let you change the normal User-Agent header, so Wikimedia accepts this one instead.
  • muteHttpExceptions stops the whole formula from erroring if Commons is busy, so you can show a friendly message.
  • sort by index: the API returns pages in its own order. Each page has an index that is its place in the search results. Without the sort, the best match might be row 7.
  • replace(/<[^>]*>/g, ‘’): the author field often comes back as an HTML link. This strips the tags.

When I ran “red panda” on 2026-10-26, the top three were a CC0 photo, a CC BY-SA 3.0 photo and a CC BY-SA 4.0 photo. That’s normal for Commons: licenses vary file by file, which is why the LICENSE column matters.

Show the pictures with IMAGE()

In F2, type:

=IMAGE(D2)

D is the THUMBNAIL column. Fill it down and every row gets a little picture. Make the rows taller (right click the row numbers > Resize rows > 100) so you can see them.

If Sheets shows an Allow access bar above the pictures, click it. Sheets asks before loading images from other sites.

More on the function in the IMAGE formula guide.

Add filters with search words

You don’t need new code for filters. Commons search understands keywords, so put them in the search text:

  • Only photos: =COMMONSSEARCH("red panda filetype:bitmap", 10)
  • Only videos: filetype:video
  • Only big files: filew:>3000
  • Only public domain or CC0: haswbstatement:P275=Q6938433|P6216=Q19652

That last one reads Commons’ structured data: P275 is “license” and Q6938433 is CC0; P6216 is “copyright status” and Q19652 is “public domain”.

Be polite to the API

  • Each formula is one request. A few dozen in a sheet is fine. Thousands at once isn’t.
  • Custom functions rerun when the sheet recalculates. To avoid calling the API again and again for the same search, cache the answer with CacheService (up to 6 hours).
  • If you get a 429 status, Wikimedia is asking you to slow down. Wait a minute.

The template: the same API, built out

I kept going with this and built Free Image Finder, a free Google Sheet on the same API. It does everything above plus:

  • A Search tab with yellow cells and dropdowns for Media type, License, Quality, Sort, Min width and Results (5 to 100), and a gallery of up to 100 pictures with Save checkboxes.
  • Three modes: words, a Commons category, or Near a place with coordinates from Google Maps.
  • A Results tab with 15 columns, including CREDIT NEEDED and a ready CREDIT LINE.
  • An Export tab with file URLs, a download script and credit lines.
  • Results cached for 6 hours.

And six formulas you can type in any cell:

  • =COMMONS(search, [type], [count], [license], [sort], [quality], [minWidth])
  • =COMMONSCOUNT(search, [type], [license], [quality], [minWidth]): how many files match
  • =COMMONSCATEGORY(category, [count]): every file in a category
  • =COMMONSNEAR(latitude, longitude, [radius], [count]): files taken near a place, up to 10,000 m
  • =COMMONSFILE(fileNames): details for a list of file names or links
  • =COMMONSPOTD([date]): the picture of the day

Common pitfalls

  • Forgetting the User-Agent: Wikimedia can block scripts that don’t name themselves. Put your real contact in Api-User-Agent.
  • Results out of order: sort by index. The pages list isn’t in search order.
  • Using PAGE URL in IMAGE(): IMAGE needs the file or thumbnail URL, not the Commons page. Use the THUMBNAIL column.
  • Loading full-size files in cells: FILE URL can be a 20 MB photo or a video. Use the 330 px thumbnail for display.
  • Searching all of Commons, not just files: leave out gsrnamespace=6 and you get category and gallery pages too.
  • Assuming every result is credit free: most files need a credit. Pull LicenseShortName and check it.
  • Too many formulas at once: hundreds of calls on every recalculation will get you rate limited. Cache, and keep it to a few dozen.

Learn the Google Sheets formulas in this post

Better Sheets has hundreds more tutorials like these. If you want to get better at Google Sheets, join Better Sheets.

FAQ

Do I need an API key for the Wikimedia Commons API?

No. It’s free with no key and no sign-up. Wikimedia asks that you send a User-Agent with a contact and keep your request rate reasonable.

Can IMPORTXML or IMPORTDATA read the Commons API?

Not cleanly. The API returns JSON, and those functions expect XML, HTML or CSV. A small Apps Script function is the simple way.

How many results can I get?

The search API returns up to 500 per request for normal users. The Free Image Finder Search tab goes up to 100, and the COMMONS formula up to 500.

Why do some rows have no thumbnail?

Some file types, like certain audio files, have no picture. Skip rows with a blank THUMBNAIL, or wrap IMAGE in IF: =IF(D2="", "", IMAGE(D2)).

Are all the images free to use commercially?

Every file on Commons is under a free license or in the public domain. Most need a credit, and CC BY-SA adds share alike for changed versions. Check the LICENSE column.

Get the sheet

Rather skip the code? Get Free Image Finder. Type a word, and the gallery fills in with pictures you’re allowed to use. Full feature list on the tool page.

Ads keep the free stuff free. Members browse ad-free — log in or see pricing.
Big Year 2027 calendar: the whole year on one Google Sheet

Free 2027 calendar.Plan all of 2027 on one Google Sheet, free.

Copy it to your Google Drive.

Free. No password, no card. The sheet link shows up right here.