EXIF Metadata Extractor: Photo & Video GPS, Camera, Dates avatar

EXIF Metadata Extractor: Photo & Video GPS, Camera, Dates

Pricing

from $1.50 / 1,000 file analyzeds

Go to Apify Store
EXIF Metadata Extractor: Photo & Video GPS, Camera, Dates

EXIF Metadata Extractor: Photo & Video GPS, Camera, Dates

Read EXIF, XMP, IPTC and video metadata from photo, raw and video links: camera, lens, exposure, capture time with its real UTC offset, GPS with the nearest city, edits, AI hints and a privacy check. Only the metadata bytes are downloaded.

Pricing

from $1.50 / 1,000 file analyzeds

Rating

0.0

(0)

Developer

Alexander Daskalov

Alexander Daskalov

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

9 days ago

Last modified

Security

Limited permissions

Share

Read the hidden metadata of photos, camera raw files and videos from their links. Paste links (JPG, HEIC iPhone photos, PNG, WebP, DNG and other raw files, MP4 and MOV videos, or Google Drive and Dropbox file links) and get one clean record per file:

  • 📍 GPS position with altitude, direction, speed and a Google Maps link, plus the nearest city, region and country (offline, nothing is sent anywhere).
  • 🕒 When it was really taken: the local time, its UTC offset and the time in UTC. The offset comes from the file itself (the camera's offset tag, the GPS clock, or the time zone at the GPS position on that date), never from a server's clock.
  • 📷 Camera and exposure: make, model, lens, shutter speed (1/250), aperture, ISO, focal length and its 35 mm equivalent, flash, white balance.
  • 🎬 Videos too: creation time (QuickTime stores it in UTC; iPhone videos keep their local offset), GPS, duration, frame rate, codec and size.
  • 🛡️ A privacy check per file: does it leak its location, the camera's serial number, the owner's name, an embedded thumbnail or an edit history? riskLevel is high, low or none.
  • ✏️ Edits and AI: the editing software, saves after capture, the IPTC "AI-generated" source type, Stable Diffusion / ComfyUI text in PNGs and C2PA manifests.
  • ©️ Rights: creator, copyright, title, description and keywords merged from EXIF, IPTC and XMP, with where each came from.
  • 🗺️ Map files for free: every geotagged file also goes into photos.geojson, photos.kml (Google Earth, My Maps) and photos.csv.

Only the metadata is downloaded. A 3.5 MB iPhone photo costs 64 KB of download, and a phone video only its index, not the video, so big files are fast. No API key, no account to connect, no setup.

What can you do with it?

  • Privacy checks before publishing: find the photos in a folder, a CMS or a marketplace listing that still carry GPS, serial numbers or owner names.
  • OSINT and verification: when and where was this photo or video taken, with which device, and was it edited or AI-generated?
  • Photo libraries and DAM: fill a catalogue with capture dates in UTC, places, cameras, lenses and keywords.
  • Real estate, insurance and field work: check that inspection or claim photos were taken at the right address and on the right day.
  • Maps of your photos: open photos.kml in Google Earth or photos.geojson in any web map.
  • After a scraper: read the photo links another Actor collected (a dataset field such as imageUrl) and add their metadata.

What files does it accept?

InputExampleSupported
Photoshttps://example.com/photos/IMG_2041.jpg✅ JPG, HEIC/HEIF (iPhone), AVIF, PNG, WebP, TIFF, GIF
Camera raw fileshttps://example.com/raw/DSC_0412.NEF✅ DNG, CR2, CR3, NEF, ARW, ORF, RW2, RAF and more (read whole)
Videoshttps://example.com/clips/IMG_3310.MOV✅ MP4, MOV, M4V, 3GP
Google Drive filehttps://drive.google.com/file/d/…/view✅ shared as "Anyone with the link"
Dropbox filehttps://www.dropbox.com/scl/fi/…?dl=0✅
Cloud storage file URLa public S3 or bucket URL✅ if it opens without logging in
Links in a datasetanother run's dataset ID + the field with the links✅ e.g. imageUrl, images[*].url
Web pages, folders, social media posts❌ link the file itself

Note that most social networks and messengers remove metadata from uploaded photos: link the original files.

How much does it cost?

Pay per file read. No monthly fee.

EventFREE / BRONZESILVERGOLD and up
File analyzed (photo, raw file or video)$0.002$0.0018$0.0015
Actor start$0.00005 / run

Examples: one photo costs $0.002; a privacy check of 50 listing photos costs $0.10; 1,000 photos cost $2.00 ($1.80 on Silver, $1.50 on Gold and up).

You pay only for files that were read. A link that is private, broken or not a photo or video gives an error record and isn't charged. A readable file with no metadata is charged: "this file is clean" is the answer a privacy check is for. With Only files with GPS on, files without a GPS position aren't returned or charged.

Cap your spend: set a maximum cost per run; the run stops before the file it can't pay for.

How to read photo metadata

  1. Click Try for free. The example input reads a geotagged photo, a geotagged video and a photo with no metadata.
  2. Paste your own links into Photo and video links, one per line, or give a dataset ID and the field with the links.
  3. Optional: turn on Only files with GPS or SHA-256 of each file, or turn off the nearest city or the raw tags.
  4. Run, then open the Overview, GPS and place or Privacy check view, download JSON, CSV or Excel, or open the map files from the run's output.

Input example

{
"files": [
"https://example.com/photos/IMG_2041.HEIC",
"https://example.com/clips/IMG_3310.MOV"
],
"reverseGeocode": true,
"includeAllTags": true,
"onlyWithGps": false,
"hashFiles": false,
"maxFiles": 1000
}

Chained after a scraper run:

{
"datasetId": "YOUR_DATASET_ID",
"datasetField": "images[*].url",
"onlyWithGps": true
}

Output

One record per file. An iPhone 12 mini photo from Wikimedia Commons (allTags shortened):

{
"url": "https://upload.wikimedia.org/wikipedia/commons/e/e1/GPS-0012_San_Diego_Air_%26_Space_Museum.jpg",
"source": "direct",
"fileName": "GPS-0012_San_Diego_Air_&_Space_Museum.jpg",
"fileType": "JPEG",
"mimeType": "image/jpeg",
"fileSizeBytes": 3487543,
"bytesDownloaded": 65536,
"wholeFileRead": false,
"sha256": null,
"camera": {"make": "Apple", "model": "iPhone 12 mini", "serialNumber": null, "lensMake": "Apple",
"lensModel": "iPhone 12 mini back dual wide camera 4.2mm f/1.6",
"lensId": "iPhone 12 mini back dual wide camera 4.2mm f/1.6", "ownerName": null, "software": "17.6.1"},
"exposure": {"exposureTime": "1/40", "exposureTimeSec": 0.025, "fNumber": 1.6, "iso": 640, "focalLengthMm": 4.2,
"focalLength35mm": 26, "exposureProgram": "Program AE", "exposureBiasEv": 0,
"meteringMode": "Multi-segment", "flashFired": false, "whiteBalance": "Auto"},
"capture": {"localDateTime": "2024-09-22T14:43:48", "utcOffset": "-07:00", "dateTime": "2024-09-22T14:43:48-07:00",
"dateTimeUtc": "2024-09-22T21:43:48Z", "offsetSource": "OffsetTimeOriginal", "timeZone": null,
"dateSource": "DateTimeOriginal"},
"gps": {"latitude": 32.726547, "longitude": -117.154633, "altitudeM": 72.1, "directionDeg": 151.26,
"directionRef": "True", "speedKmh": 0, "gpsDateTimeUtc": "2024-09-22T21:43:47Z", "horizontalErrorM": 6.05,
"mapsUrl": "https://www.google.com/maps?q=32.726547,-117.154633"},
"place": {"city": "San Diego", "region": "California", "country": "United States", "countryCode": "US",
"distanceKm": 1.5},
"media": {"width": 4032, "height": 3024, "orientation": 1, "orientationText": "Horizontal (normal)",
"rotationDeg": null, "displayWidth": 4032, "displayHeight": 3024, "megapixels": 12.19,
"durationSec": null, "frameRate": null, "videoCodec": null},
"editing": {"software": "17.6.1", "processingSoftware": null, "historyAgents": [], "modifiedAfterCapture": false,
"editedLikely": false, "editReasons": []},
"rights": {"creator": [], "keywords": [], "copyright": null, "title": null, "description": null, "headline": null,
"credit": null, "usageTerms": null, "webStatement": null, "rating": null, "city": null, "region": null,
"country": null, "sublocation": null, "origins": {"creator": [], "keywords": []}},
"provenance": {"digitalSourceType": null, "aiGenerated": false, "aiGeneratorHints": [], "c2paManifest": false,
"c2paClaimGenerator": null, "hasEmbeddedThumbnail": true},
"privacy": {"leaksLocation": true, "leaks": ["gps", "thumbnail"], "riskLevel": "high"},
"allTags": {"IFD0:Make": "Apple", "IFD0:Model": "iPhone 12 mini", "GPS:GPSLatitude": 32.7265472222222,
"ExifIFD:ISO": 640},
"allTagsTruncated": false,
"warnings": [],
"processedAt": "2026-10-16T09:12:40+00:00",
"error": null
}

A video (a MOV with GPS): QuickTime's creation time is UTC, so the local time and offset come from the time zone at the GPS position on that date:

{"capture": {"localDateTime": "2026-07-14T18:30:05", "utcOffset": "+03:00", "dateTime": "2026-07-14T18:30:05+03:00",
"dateTimeUtc": "2026-07-14T15:30:05Z", "offsetSource": "quicktime-utc+gps-position",
"timeZone": "Europe/Sofia", "dateSource": "CreateDate"},
"media": {"width": 640, "height": 360, "durationSec": 3, "frameRate": 25, "videoCodec": "avc1"}}

An edited photo with no GPS but a serial number, the owner's name and a Photoshop history:

{"editing": {"software": "Adobe Photoshop 25.0 (Windows)", "historyAgents": ["Adobe Photoshop 25.0 (Windows)"],
"modifiedAfterCapture": true, "editedLikely": true,
"editReasons": ["edited with Adobe Photoshop 25.0 (Windows)", "saved 2026-07-20 10:00, after it was taken"]},
"privacy": {"leaksLocation": false, "leaks": ["serialNumber", "ownerName", "editHistory"], "riskLevel": "low"}}

An AI image (a Stable Diffusion PNG with the IPTC source type):

{"provenance": {"digitalSourceType": "trainedAlgorithmicMedia", "aiGenerated": true,
"aiGeneratorHints": ["Stable Diffusion generation parameters in the PNG text"],
"c2paManifest": false, "c2paClaimGenerator": null, "hasEmbeddedThumbnail": false}}

A link that can't be used gives a record with the reason in error (not charged):

{"url": "https://example.com/photos/old.jpg", "error": "file not available (HTTP 404): is the link public?"}

Field notes:

  • capture.offsetSource says where the UTC offset came from: OffsetTimeOriginal (the camera wrote it), gps-time (the camera clock against the GPS clock, to the nearest 15 minutes), gps-position (the time zone at the GPS position on that date, summer time included), quicktime-utc+gps-position (videos) or quicktime-utc (a video without GPS: only the UTC time is known). With none of these, utcOffset and dateTimeUtc stay null rather than guessing.
  • gps is null when the file has no position; a 0, 0 position (what cameras without a fix write) counts as none.
  • place is the nearest town of 1,000+ people in GeoNames, with distanceKm to it; far from any town (at sea) it is still the nearest one, so check the distance.
  • media.displayWidth / displayHeight are the size as shown, after the orientation tag (or a HEIC's rotation) is applied.
  • editing.editedLikely is a hint, not proof: it is true when an editor wrote the file or it was saved after it was taken.
  • provenance.aiGenerated is true when the file says so (IPTC trainedAlgorithmicMedia, generator text in a PNG, an AI tool as software). Most AI images carry no such marks once they have been re-saved: false does not mean a photo is real.
  • allTags keeps every tag ExifTool found, grouped (IFD0:Make, XMP-dc:Subject, QuickTime:CreateDate); binary blocks are left out and it is cut at 200 KB.

How accurate is it?

The metadata is read by ExifTool, the reference tool photographers, archives and forensic labs use, which knows thousands of tags and every camera maker's private notes. We tested the mapping on sample files with known answers (JPEG, HEIC, PNG, WebP, DNG, MOV, MP4, an edited photo, an AI PNG, photos with only a GPS clock or only a GPS position) and on a real iPhone photo: every camera, exposure, time, offset, GPS, place, privacy, editing and AI field matched. Reading only the metadata part gives exactly the same tags as reading the whole file, on every sample.

How fast is it?

Files are downloaded 8 at a time and read by one ExifTool process that stays open. Measured on Apify at the default 256 MB: the example input (a photo, a video and a clean photo) finishes in about 3 seconds including start-up; 30 photos and videos took 3.4 seconds, with ExifTool reading a batch of 20 in 0.3 seconds. The 3.5 MB iPhone photo above took 0.2 seconds to fetch, because only its first 64 KB were downloaded.

What it doesn't do

  • No street addresses: the place is the nearest city, region and country, from offline data. Street-level addresses would need a paid geocoding service.
  • No metadata the file doesn't have: most social networks and messengers strip it on upload, and screenshots never had it. Link the original file.
  • No editing or removing metadata: it reads, it doesn't write.
  • No proof of authenticity: editedLikely and aiGenerated report what the file says about itself; a determined forger can change both.
  • No web pages or folders: link each file itself.

Use it with AI agents (MCP)

https://mcp.apify.com?tools=bossless/exif-metadata-extractor

Ask your assistant "where and when were these photos taken, and do any of them leak my location?", and it runs this actor and answers from the records.

Use the API from code

curl -X POST "https://api.apify.com/v2/acts/bossless~exif-metadata-extractor/run-sync-get-dataset-items?token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"files": ["https://example.com/photos/IMG_2041.jpg"]}'
from apify_client import ApifyClient
client = ApifyClient("YOUR_TOKEN")
run = client.actor("bossless/exif-metadata-extractor").call(run_input={
"files": ["https://example.com/photos/IMG_2041.HEIC", "https://example.com/clips/IMG_3310.MOV"],
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
if item["error"]:
print(item["url"], "error:", item["error"])
continue
gps, place = item["gps"] or {}, item["place"] or {}
print(item["fileName"], item["capture"]["dateTimeUtc"], gps.get("latitude"), gps.get("longitude"),
place.get("city"), "privacy:", item["privacy"]["riskLevel"])

FAQ

Is my location data sent anywhere? No. Places and time zones come from offline data inside the Actor; no geocoding service is called.

Why is utcOffset null for some photos? Older cameras store the local time without its offset. When the file has neither an offset tag nor a GPS clock or position, the offset can't be known, and the Actor doesn't guess from a server's clock.

Does it read RAW files? Yes, through ExifTool. Raw files are downloaded whole (their metadata can sit anywhere), so they take longer than JPEGs.

How big can files be? Photos and videos whose metadata is at a known place (JPEG, HEIC, WebP, MP4, MOV) can be any size when the server supports range requests, as nearly all do. Files downloaded whole (PNG, TIFF, raw, SHA-256, servers without range requests) are limited by the run's disk: about 300 MB at the default 256 MB of memory; give the run more memory for bigger ones.

What happens with a private or broken link? You get a record with the reason in error, and it isn't charged.

Is this affiliated with ExifTool, Apple, Google or any camera maker? No. It is not affiliated with any of them.

Credits

Metadata is read with ExifTool by Phil Harvey (Perl Artistic License / GPL). Place names come from GeoNames (CC BY 4.0) via the reverse-geocode package, and time zones from timezonefinder (MIT) with the IANA time zone database.