DEV Community

Cover image for Google Lens API: How to Reverse Image Search a Local File in 2026
Truffle Pig Data
Truffle Pig Data

Posted on

Google Lens API: How to Reverse Image Search a Local File in 2026

Point Google Lens at a photo and it names the product, finds who sells it, and lists every page where that image appears. Getting the same answers in code is harder: there is no official API, and most reverse-image tools demand a public URL for every photo you search, which is no help when the images sit in a folder on your laptop. I'll show the manual route and where it breaks, then the shortcut: the Google Lens API on Apify, which lets you upload images straight from your computer, no public URL needed, and returns matches as structured JSON.

Disclosure: the Apify links in this post are affiliate links. If you run the Actor, I may earn a referral commission at no extra cost to you.

Does Google Lens have an API?

No. Lens ships inside Chrome, Android, and the Google app, and there has never been a public endpoint or a key to request. Google's developer-facing vision tools answer a different question: what is in an image, not where it appears across the web. So in practice a Google Lens API means a scraper you consume like an API: send an image, get matches back as JSON.

What the Google Lens API returns

The Google Lens API returns visual matches, product listings, and exact-match pages for an image as structured JSON, with title, source, url, and thumbnail on every row.

Field Example Notes
title Aeron Chair Size B, Graphite What the matching page calls it
source ebay.com The site hosting the match
url https://www.ebay.com/itm/... Direct link to that page
price 499 On products rows, with currency
inStock true Whether the listing is buyable

search_type picks the mode: visual_matches finds lookalikes, around 59 rows for a typical image; products returns shoppable listings with prices, around 19; exact_matches is the attribution mode, up to 400 pages carrying the identical image.

Who this is for

E-commerce teams matching catalog photos to who else sells the product at what price, photographers and stock agencies doing image attribution and license checks at scale, and builders giving an AI agent eyes for visual product search.

The manual way, and where it breaks

The DIY version is a headless browser driving lens.google: load the page, feed it an image, wait, parse the result cards. It demos fine and then rots. The upload flow is a UI, not an endpoint, so every search drags a full Chrome instance along. Results render through JavaScript, and the layout shifts often enough that selectors die in weeks. And it is one image at a time with no export; nobody audits 500 product photos that way.

The faster way: run the Google Lens API

You send a documented JSON input and get a dataset back, with nothing to babysit.

Apify Console

  1. Open the Google Lens API and click Try for free.
  2. Paste an image_url, or drop files into the Upload images field, then pick a search_type.
  3. Run it and download the dataset as JSON, CSV, or Excel.

REST

curl -X POST "https://api.apify.com/v2/acts/johnvc~google-lens-api/runs?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "image_url": "https://example.com/product-photo.jpg", "search_type": "products", "max_results": 20 }'
Enter fullscreen mode Exit fullscreen mode

Run endpoint details are in the Apify API docs.

Run a reverse image search in Python

Call the Actor with apify-client; each dataset item is one match:

from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")

run = client.actor("johnvc/google-lens-api").call(
    run_input={
        "image_url": "https://example.com/product-photo.jpg",
        "search_type": "visual_matches",
        "max_results": 10,
    }
)

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["title"], item["source"], item["url"])
Enter fullscreen mode Exit fullscreen mode

The published task Reverse image search in Python has a runnable version.

Search by a local file, no public URL needed

Here's the part that made me want to write this post. Most reverse-image tools insist on a public URL, so step one of searching a private photo is publishing it somewhere, which defeats the point. This Actor takes the file itself. In the Console, the Upload images field accepts files up to 20 MB each and 30 MB per run, and uploads are staged privately behind a signed link, so your image never gets a public address. From code, base64-encode the file into the image_base64 array, up to 10 images per run:

import base64
from pathlib import Path

from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")

encoded = base64.b64encode(Path("chair.jpg").read_bytes()).decode()

run = client.actor("johnvc/google-lens-api").call(
    run_input={
        "image_base64": [encoded],
        "search_type": "visual_matches",
        "max_results": 3,
    }
)

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["title"], item["source"], item["url"])
Enter fullscreen mode Exit fullscreen mode

Sizing note: the platform caps total run input at 9 MB, and base64 inflates files by about a third, so budget roughly 6 MB of images per run on this path. Bigger files belong in the Console's upload field.

Check a whole folder of images

Attribution and price checks rarely involve a single photo. The task Bulk reverse image search shows the batch pattern: images in, one combined dataset out, one row per match.

Find out where your photos are being used

Run a photo through exact_matches and every page carrying the identical file comes back as a row, which turns "I think that's my shot" into a list of URLs you can act on. The task Check if photos are stolen is set up for exactly this workflow.

Try it on free credit first

Billing is per result and max_results caps the rows before a run starts, so a three-row smoke test costs close to nothing on a new account's free platform credit. The task Reverse image search API free tier is that capped starter run.

The same workflow in Chinese

If your team searches in Chinese, two task pages cover this ground natively: 以图搜图 API for search-by-image and 图片盗用检测 for image-theft detection.

Use it from Claude and other MCP clients

Apify exposes the Actor over the Model Context Protocol, so Claude, Claude Code, and Cursor can call it mid-conversation and answer "who sells this chair and for how much" with live rows. The task Google Lens in Claude via MCP has the config, and you can read more about Claude Code at claude.ai.

Working example on GitHub

The quick-start repo has a runnable Python client plus MCP install walkthroughs for Claude, Cursor and ChatGPT.

GitHub logo johnisanerd / Apify-Google-Lens-API

google lens api: Python + MCP quick-start for the Google Lens API on Apify. Call it from Python (uv) or as an MCP tool in Claude and Cursor. Returns structured JSON for google lens api.

🔍 Google Lens API: reverse image search from Python and MCP

Actor: johnvc/google-lens-api · Input schema

This repo shows two ways to use the Google Lens API on Apify: a Python quick start and MCP installs for five AI clients. Send an image straight from your computer, base64 from code, or any public image URL, and get back visually similar results, shoppable product matches with prices, or every page carrying the exact same image, which is the bulk reverse image search photographers use for attribution checks. Most reverse image tools demand a public URL; this one does not.

Video Walkthrough

Watch the walkthrough

Text walkthrough

The google lens api takes an image (a local file via image_base64 or the console upload field, or a public image_url) plus a search_type. visual_matches is the general reverse image search and returns about 59 rows per lookup with title, source, url, thumbnail and the full image link…




FAQ about scraping Google Lens

How much does the Google Lens scraper cost to run?

You pay per result: each match row is one billable event, and max_results caps the count before the run starts. Volumes differ by mode, roughly 19 rows for products, 59 for visual_matches, up to 400 for exact_matches, so cap exact-match runs unless you want the full sweep. New accounts come with free platform credit; the free-tier task above runs on it.

Can the scraper search an image that is not online?

It can, and that is the headline feature. Push files through the Console's upload field or send base64 through image_base64 from code; either way the upload sits behind a private signed link instead of a public URL, so private photos stay private.

Does the scraper work from Claude or another MCP client?

Yes. Connect Apify's MCP server and the Actor shows up as a callable tool in Claude, Claude Code, or Cursor. The MCP task above has the config.

Can I schedule the scraper to watch for stolen images?

Yes, and attribution is where scheduling pays off. Save your images as a task, attach an Apify schedule, and each run appends the current set of exact matches, so a new unauthorized copy shows up as a new row. Start from the Google Lens API.

What will the scraper not tell me?

A few things, honestly. The image field comes back null on exact-match rows, so lean on thumbnail there. Ratings and review counts rarely appear because most source pages never publish them. And results mirror what Lens itself finds: a photo with no web footprint returns few rows, and that is the correct answer, not a bug.

More from Truffle Pig Data

Same corner of the toolbox: the Google Images API for keyword-to-images instead of image-to-pages, and the Yandex Reverse Image Search API for a second engine's opinion on the same photo.

Wrapping up

Google never shipped a Lens API, but the data is reachable anyway, and it now works on images that never touch the public web. Point the Google Lens API at a URL, or at a file on your desk, and see what comes back.

Top comments (0)