OSINT^:OSINT

Reverse Image Search

Find where an image came from and whether it predates the event it supposedly shows — the first check on any visual claim.

beginnerupdated 2026-10-04google-lens · tineye · yandex · bing

What this covers

Establishing whether an image is what it claims to be, by finding earlier copies of it. This is the single highest-value check in visual verification and it takes under a minute, so it goes first, always — most viral misinformation is old footage relabelled, and the relabelling is what a reverse search catches. The engines disagree constantly, which is not a flaw to work around but the reason you run more than one.

Method

  1. Run several engines on the unmodified file. They index different corpora. One engine returning nothing means that engine has nothing, and nothing more than that.
  2. Sort by oldest where the engine lets you. Relevance ranking is actively unhelpful here — you want the earliest appearance, not the most popular one.
  3. Preprocess and re-run. Crop to the distinctive object, remove the overlay, flip it horizontally, upscale it. Each of these is a different query against the same corpus and each finds things the others miss.
  4. For video, extract keyframes and search each. A video is only as findable as its most distinctive still.
  5. Read the earliest hit’s own context. The oldest copy you can find is not necessarily the original. Follow its caption and its sourcing before you call it the source.
  6. Archive what you found, with its date, before you cite it. Search results are not stable — see Archiving & Evidence.

The judgement call that matters: decide what you are actually asking. “Where did this image come from” and “does this image predate the event it is captioned with” are different questions, and only the second one is usually answerable. The second is also the one that settles arguments, so aim at it.

Key tools

Google Lens

Web only, free, no account needed for a one-off. The strongest engine for objects — products, landmarks, vehicles, plants, architecture — and it has the best OCR of any of them, which means it will often read a sign in your image and search the text without being asked. That is exactly what you want for a photo with a shopfront in it, and exactly what you do not want for a photo whose text is incidental.

1. lens.google.com, or the camera icon in Google Images. Upload the file; do not
   paste a social-media URL, which searches the page rather than the image.
2. Drag the crop handles immediately. Lens defaults to the whole frame and the whole
   frame is almost always the wrong query. Crop to one object and re-run.
3. Switch between the result modes. "Exact matches" is the one that answers the
   verification question; the visual-similarity feed is for identifying the object.
4. "Find image source" (where offered) gives a dated list of pages carrying the image.
   This is the closest Lens gets to TinEye's oldest-first view, and it is worth
   scanning to the bottom rather than the top.
5. Capture: the result page as a screenshot plus the URLs of the earliest pages, and
   the crop you actually searched -- a result is not reproducible without the crop.

You can also hand it a URL directly, which is useful for scripting a triage pass over a set of images already hosted somewhere:

# searches the image at that URL; the image must be publicly reachable
open "https://lens.google.com/uploadbyurl?url=https://example.org/photo.jpg"

# url-encode anything with query parameters or the search will be of the wrong file
python3 -c 'import sys,urllib.parse; print("https://lens.google.com/uploadbyurl?url=" + urllib.parse.quote(sys.argv[1], safe=""))' \
  "https://example.org/img?id=123&size=full"

Lens personalises, so two people searching the same image get different result sets and neither is reproducible from the other’s screenshot. It is also weak on faces by design — it will refuse or deflect — and weak on anything that is mostly sky, water or crowd. Dates shown next to results are the page’s claimed date, not the image’s, and content farms backdate.

Yandex Images

Web only, free. The one that finds what Google misses, consistently enough that skipping it is a real gap in a verification. It is markedly better at faces, at crops of faces, and at Eastern European, Russian and Central Asian content of every kind — if the image has Cyrillic in it or is plausibly from that part of the world, Yandex is your first engine rather than your third.

1. yandex.com/images -> the camera icon -> upload, or paste an image URL.
2. The results page splits into "Similar images" and "Sites containing this image".
   The second list is the evidential one; the first is a lookalike feed and will
   cheerfully show you a different person with the same haircut.
3. Use the size filter in the left rail. Filtering to larger-than-your-copy is a fast
   way to find an earlier, less-compressed version, which is usually closer to source.
4. Re-run on a tight crop of a face or a patch, separately. Yandex handles partial
   matches far better than the others and a crop frequently returns hits the full
   frame does not.
5. Read the result page titles even when the thumbnails look wrong -- its indexing of
   Russian-language forums and VK is better than anything else available.

The same URL pattern works if you want to fire it from a script:

open "https://yandex.com/images/search?rpt=imageview&url=https://example.org/photo.jpg"

The face matching is good enough to be an ethical question rather than a technical one: it will identify private individuals from a crowd shot. Decide before you run it what you will do with a hit, and whether the person in the frame is a subject of your investigation or a bystander. Beyond that, Yandex’s similarity feed is the most confident and the most wrong of any engine — it will return a visually similar image with total assurance, so never treat a “similar” result as a match without comparing fixed detail yourself.

TinEye

Web only. Free for interactive use with no account; the published free API tier is 100 searches per day and 300 per week for non-commercial use, with paid tiers above that. The index is smaller than Google’s and it does not do visual similarity at all — it does exact and near-exact matching of the same image, including crops, resizes and recolours.

That narrowness is the whole point: TinEye’s “Oldest” sort is the single strongest piece of evidence available for “this image predates the event it claims to show.” If TinEye returns a copy indexed in 2019 and the caption says the photo is from last week’s protest, the caption is false, and no amount of argument about context changes that.

1. tineye.com -> upload the file, or paste an image URL.
2. Change the sort from "Best Match" to "Oldest". This is the only control on the page
   that matters for verification. The options are Best Match, Most Changed, Biggest
   Image, Newest and Oldest.
3. Read the first result's crawl date and open the page it sits on. TinEye's date is
   when it first saw the image at that URL, not when the image was made -- it is a
   latest-possible-creation date, which is the useful direction.
4. "Most Changed" is the second-most-useful sort: it surfaces the versions that have
   been cropped, overlaid or edited, which shows you how the image has been used.
5. "Biggest Image" finds the least-compressed copy, which is what you want to hand to
   the other engines and to any forensic step.
6. Capture: the oldest result's URL, TinEye's stated date for it, the total match
   count, and an archive snapshot of that oldest page before it moves.

Absence from TinEye is close to meaningless — its crawl is much narrower than Google’s and it does not index most social platforms, so a genuinely viral image can show zero results. The date is a crawl date and a page can have been republished at a new URL, so an “oldest” of last month does not mean the image is from last month. And it is defeated by heavy re-editing in a way the similarity-based engines are not: a mirrored, re-captioned, re-encoded repost may not match at all, which is why the preprocessing step below exists.

Web only now. The Bing Search APIs — including Visual Search — were retired on 11 August 2025 and pre-retirement endpoints return HTTP 410, so any tutorial or script that calls a Bing visual search API is dead; Microsoft’s replacement is a grounding feature inside Azure AI Agents rather than an image-match endpoint. The web interface still works and is still worth a minute, because its regional coverage differs from both Google’s and Yandex’s.

1. bing.com/images -> the camera icon in the search box. (bing.com/visualsearch now
   redirects to a Microsoft marketing page, not the tool.)
2. Upload, paste a URL, or drag a file in.
3. Use the on-image crop box, which Bing exposes more prominently than Google does --
   it is the best of the three for "search just this one object in the picture".
4. "Pages with this image" is the evidential list; "Related content" is not.
5. Capture the same way as the others: screenshot, URLs, and the crop you used.

Scriptable as a URL, with the usual caveat that it is an undocumented web parameter rather than a supported interface and may change without notice:

open "https://www.bing.com/images/search?view=detailv2&iss=sbi&q=imgurl:https://example.org/photo.jpg"

No oldest-first sort, no date on most results, and a strong pull toward commercial and stock imagery. Treat it as a third opinion that occasionally produces the one hit nobody else had, rather than as a primary tool.

Preprocessing with ImageMagick

The step that separates a reverse search that works from one that returns nothing. Engines match on what is visually dominant, so an overlaid caption, a platform watermark or a wide establishing shot all push the match toward the wrong thing. Each transformation below is a separate query — run them all, do not pick one.

brew install imagemagick     # or: apt install imagemagick

# what you are actually working with: dimensions tell you how much has been lost already
magick identify -verbose photo.jpg | head -40

# crop to the distinctive object. percentages, or pixels as WxH+X+Y
magick photo.jpg -crop 40%x40%+30%+20% +repage crop-sign.jpg
magick photo.jpg -crop 640x480+120+80 +repage crop-vehicle.jpg

# mirror it. reposts are flipped constantly to defeat exact matching, and the engines
# do not try both orientations for you
magick photo.jpg -flop flipped.jpg

# cut off a burned-in caption bar or platform watermark along the bottom
magick photo.jpg -gravity south -chop 0x90 nobar.jpg

# upscale a small crop so an engine has pixels to work with. lanczos then a light
# unsharp is the combination that does not invent edges
magick crop-sign.jpg -filter Lanczos -resize 300% -unsharp 0x1 crop-up.jpg

# pull detail out of a dark or flat region before cropping to it
magick photo.jpg -auto-level -sigmoidal-contrast 3,50% enhanced.jpg

# strip metadata from anything you are about to upload to a third-party engine --
# you are handing them the file, and the file may carry a source's GPS
magick photo.jpg -strip clean.jpg

+repage after a crop is not optional: without it the file keeps the original canvas geometry and some tools will re-expand it. Upscaling adds no information — it makes a small crop palatable to an engine’s minimum-size requirements, and anything it appears to reveal is interpolation, so never read a plate number off an upscale. And every enhancement you apply is a change to evidence: keep the original untouched, work on copies, and record the exact command alongside the result, the same way Image & Video Forensics handles hashing and the chain from received file to analysed file.

ffmpeg

Video does not reverse-search. Frames do. Pull the frames that are worth searching and you have turned an unsearchable clip into eight or ten image queries.

brew install ffmpeg     # or: apt install ffmpeg

# every encoded keyframe, decoded fast because P- and B-frames are skipped outright.
# this is the cheapest first pass and usually enough
ffmpeg -skip_frame nokey -i video.mp4 -fps_mode vfr -q:v 2 key-%03d.jpg

# frames at scene changes: 0.3 is a sane threshold, lower it to 0.1 for static footage
ffmpeg -i video.mp4 -vf "select='gt(scene,0.3)'" -fps_mode vfr scene-%03d.jpg

# one frame every five seconds, as a fallback for a single unbroken shot that has no
# scene changes to detect
ffmpeg -i video.mp4 -vf fps=1/5 every5-%03d.jpg

# a contact sheet, to pick the searchable frame by eye instead of opening fifty files
ffmpeg -i video.mp4 -vf "select='gt(scene,0.1)',scale=320:-1,tile=4x4" -fps_mode vfr sheet.png

# the exact frame at a timestamp, once you know which second carries the readable sign
ffmpeg -ss 00:01:12.500 -i video.mp4 -frames:v 1 frame.png

# crop, upscale and sharpen that frame in one pass, ready to hand to an engine
ffmpeg -i frame.png -vf "crop=400:300:820:460,scale=iw*4:ih*4:flags=lanczos,unsharp=5:5:1.0" search-me.png

# mirror a frame, for the flipped-repost case
ffmpeg -i frame.png -vf hflip frame-flipped.png

# blank out a burned-in platform logo rather than cropping the frame down
ffmpeg -i frame.png -vf "delogo=x=20:y=20:w=160:h=60" nologo.png

-vsync vfr appears in most tutorials for this and has been removed in ffmpeg 9 — it now fails with “Option not found”. Use -fps_mode vfr, which replaced it in ffmpeg 5. Scene detection also fires on camera pans and on cuts to black as readily as on a genuine change of location, so expect a third of the frames to be useless; conversely a single-shot clip yields no scene frames at all, which is why the fps=1/5 fallback is there. Downloading the video in the first place, and reading its container metadata, are on Social Media Platforms and Image & Video Forensics respectively.

InVID / WeVerify

A browser extension, free, from an EU research project. It collapses the whole video path above into a few clicks and — the part that genuinely saves time — it extracts keyframes from a platform URL without you downloading the file at all, then fires each keyframe at several engines in one go.

1. Install from weverify.eu/verification-plugin (Chrome and Firefox builds).
2. "Keyframes": paste the video URL. It fetches, segments and returns a grid of
   keyframes with reverse-search buttons under each one.
3. Click through Google / Yandex / Bing / TinEye per keyframe. The buttons open the
   engines in new tabs -- you still read the results yourself, it just saves the
   upload step for each of the four.
4. "Magnifier": loads a still into a zoom-and-enhance panel, for reading a sign
   without leaving the browser.
5. "Analysis": pulls the platform's own upload metadata for a YouTube/Facebook/X URL,
   which gives you a latest-possible date for the upload -- not for the footage.
6. "Image forensics" runs ELA and noise filters. Use it for triage only; the real
   version of that work is on the forensics sheet.

Platform integrations break whenever a platform changes its markup, so expect at least one tab of the plugin to be dead at any given time; the keyframe extraction and the reverse-search buttons are the durable parts. It gives you no reproducible command and no file hash, so anything you intend to publish should be re-done with ffmpeg and recorded properly. And it uploads frames to third-party engines, which is the same exposure question as any web tool — for sensitive material, extract locally and decide deliberately what leaves your machine.

The smaller engines

Worth a minute each when the big four come back empty, because they index corpora the others do not touch.

ToolWhat it is good for
RootAboutReverse image search across Internet Archive holdings — old web, scanned books and ephemera that no live-web crawler has.
Search by ImageBrowser extension that fires one image at a configurable list of engines at once. The fastest way to run the full set without uploading four times.
Karma DecayReverse search restricted to Reddit, which is where a surprising share of recycled images surfaces first.
PimeyesFace search specifically, and paid beyond a teaser. Powerful, legally fraught in several jurisdictions, and a tool to think hard about before using on anyone who is not a subject.

None of these replaces the main four. Reaching for them is a sign that your query is wrong more often than it is a sign that the image is unindexed — go back and crop harder before you go further down this list.

Tool reference

ToolWhat it doesCost
InVIDA toolkit that supports the verification of videos and images.free
Google LensObject, landmark and text matching with strong OCR.free
TinEyeExact and near-exact matching with oldest-first sorting.free / paid API
RootAboutReverse image search across Internet Archive holdings.free

Pitfalls

  • Cropped, mirrored or filtered images defeat exact matching. Flip horizontally and re-run; recompressed and mirrored reposts are extremely common and TinEye in particular will miss them.
  • Absence of results is not originality. It usually means the original lives on a platform the engine cannot index. Say “not found by X, Y and Z”, never “original”.
  • The oldest hit can still be a repost. Read its context rather than treating the crawl date as the answer.
  • Dates on result pages are the page’s claim. Content farms backdate, CMSs rewrite timestamps on edit, and an archive snapshot is the only date you can stand behind.
  • Screenshots of screenshots lose the detail engines match on. Ask for the original file.
  • Results are personalised and are not reproducible. Archive the result page, and always record the crop you searched — without it, nobody can repeat your query.
  • Uploading is disclosure. Every web engine on this page keeps what you give it. For a file from a source, strip it first and think about whether it should be uploaded at all.

Worked example

One datum: a photograph circulating with the claim that it shows a named street during a protest three days ago.

  1. Unmodified file, four engines. Lens returns stock-photo lookalikes. Bing returns news aggregators from this week. Yandex returns a Russian-language forum thread. TinEye, sorted Oldest, returns a first crawl dated four years ago on a regional news site.
  2. Open the oldest page. It carries the same image, uncropped, with a caption naming a different city and a different event. The claim is already broken at this point, and everything after this is confirming rather than discovering.
  3. Confirm it is the same image, not a lookalike. Crop both copies to the same corner — a shop awning with a readable name — and compare. Identical awning, identical crack in the paving, identical parked van. Fixed detail agreeing is the test; general resemblance is not.
  4. Explain why the other engines missed it. The circulating version is mirrored and has a caption bar burned along the bottom. magick circulating.jpg -flop -gravity south -chop 0x90 fixed.jpg undoes both, and a re-run gets Lens to the same original — which demonstrates the edit and shows the preprocessing step earning its place.
  5. Date the circulating version, not just the original. TinEye’s “Newest” sort and the aggregator pages put the relabelled version’s first appearance at four days ago, a day before the protest it is captioned with — which is itself a finding.
  6. Archive before citing. The four-year-old page, the aggregator pages, and the TinEye result page all go to the Wayback Machine, because the regional news site is exactly the kind of source that reorganises its URLs. See Archiving & Evidence.

What you can assert: the image was indexed on a named site four years before the event it is captioned with, the circulating copy is a mirrored and cropped derivative of it, and specific fixed details match between the two.

What would falsify it: the two images being different photographs of the same unchanged street — which is what the awning crack and the parked van rule out, and which is why you compare fixed detail rather than overall appearance. A crawl date that TinEye got wrong would also do it, so the archived copy of the four-year-old page, with its own publication date, is the thing worth having.

Broader catalogues

More tools

Further tools for this area from the OSINT Newsletter Tools Library (Fact-checking/verification OSINT), excluding those already listed above.

ToolWhat it does
Fact CheckA non-partisan fact-checking platform that investigates political claims, public statements and misinformation (US focused).
Google Fact Check ToolsA free Google verification tool that helps users search existing fact-checks from trusted organisations worldwide.
PolitifactAn independent fact-checking platform that verifies claims made by politicians, public figures, organisations, and viral online…
SnopesFact-checking and investigative journalism platform used to assess the accuracy, origin and context of online claims, rumours…
StopFake ToolsA fact-checking and verification resource focused primarily on identifying and debunking disinformation, misleading claims, and…

Sources

Both catalogues below are maintained by other people and are considerably larger than this page. Use them as the canonical index; this sheet is a working route through them.

Neither publishes a licence, so nothing here is copied from them: tool names, one-line descriptions, cost flags and links are catalogue facts, and the method and commentary are this site’s own. See credits.

On this page

☧ CPTS · ordered posts

Locked

Unlock with your Main_Key through local GPG.

Start the local GPG helper

In your cheatsheet checkout, run:

npm run unlock:helper

Open the link it prints, or paste its pairing code below. Keep the terminal open until GPG finishes.

Import an index you already decrypted

Download the encrypted index, then decrypt with GPG:

gpg --output report-index.json --decrypt report-index.gpg

Your private key stays in GPG. The decrypted index is saved in this browser so you can reopen it after navigation, refreshes and restarts. Lock this browser or clear this site's browser data to remove the saved index. Nothing is uploaded.