
Recommendation. ExifTool is a Perl command-line utility that reads and writes file headers; it has no GPU, Apple-silicon framework, or graphical display requirement for a batch IPTC job. For a pure IPTC/XMP write across JPEG, TIFF, PNG, PSD, PDF and DNG, the Figment virtual Intel macOS plan at $29/month (2 vCPU, 8 GiB RAM, 80 GiB disk, browser-console access) is the right size. Step up to the physical i3 Mac at $49/month if you want to run Lightroom or Capture One alongside Terminal for visual QA, or request an M-series Mac from $95/month when the pipeline expands into GPU-heavy RAW rendering or AI keywording. Exact chip, RAM and disk for any physical plan are confirmed on the quote, and physical i3 and M-series orders are collected as requests until supply is confirmed.
Primary references for every command below are the ExifTool home page at exiftool.org and the IPTC tag table at exiftool.org/TagNames/IPTC.html.
Stock and archive platforms index IPTC during upload. These are the fields worth populating for every image, with tag IDs taken from the ExifTool IPTC ApplicationRecord table:
| IPTC Field | ExifTool Tag | Tag ID | Use |
|---|---|---|---|
| Creator (By-line) | IPTC:By-line | 80 | Photographer / rights holder |
| Copyright Notice | IPTC:CopyrightNotice | 116 | Licensing display |
| Keywords | IPTC:Keywords | 25 | Search indexing |
| Caption / Description | IPTC:Caption-Abstract | 120 | Editorial description |
| Date Created | IPTC:DateCreated | 55 | Chronological browsing |
| City | IPTC:City | 90 | Geographic filtering |
| Country | IPTC:Country-PrimaryLocationName | 101 | Geographic filtering |
| Headline | IPTC:Headline | 105 | Short display title |
Per the ExifTool IPTC documentation, embedded IPTC may be found in JPG, TIFF, PNG, MIFF, PS, PDF, PSD, XCF and DNG. Many modern readers prefer XMP, so write both namespaces in a single command — ExifTool handles that natively via -XMP-dc: and -XMP-photoshop: tag prefixes.
Open Terminal on the Mac (browser console for the $29 VM; physical plans use the access path stated on the quote), then:
exiftool binary to /usr/local/bin.exiftool -ver
which exiftool # expect /usr/local/bin/exiftool
If which returns nothing, add the path for this session: export PATH="/usr/local/bin:$PATH". Record whatever version exiftool -ver returns in your delivery notes — tag-write behaviour has shifted between ExifTool minor releases, and a later rerun on a different version can produce different XMP output.
This is the whole-library command. It writes IPTC and the matching XMP fields together so every downstream reader sees the same values. Run it first against a copy of the library; only drop the _original backup behaviour once a spot check is clean.
exiftool \
-IPTC:By-line="Jane Smith" \
-IPTC:CopyrightNotice="Copyright 2026 Jane Smith. All rights reserved." \
-IPTC:Keywords="landscape" -IPTC:Keywords="aerial" -IPTC:Keywords="dawn" \
-IPTC:Caption-Abstract="Aerial view of Mount Rainier at dawn." \
-IPTC:DateCreated="2026:06:15" \
-IPTC:City="Seattle" \
-IPTC:Country-PrimaryLocationName="United States" \
-XMP-dc:Creator="Jane Smith" \
-XMP-dc:Rights="Copyright 2026 Jane Smith. All rights reserved." \
-XMP-dc:Subject="landscape" -XMP-dc:Subject="aerial" -XMP-dc:Subject="dawn" \
-XMP-dc:Description="Aerial view of Mount Rainier at dawn." \
-XMP-photoshop:DateCreated="2026-06-15" \
-P -r \
"/path/to/image library/"
Notes on the flags, drawn from the ExifTool options documentation:
-r recurses into subdirectories.-P preserves the original FileModifyDate, which matters for library sorting.-IPTC:Keywords= adds each value as a separate list item, which is what agency search indexes expect.-overwrite_original, ExifTool keeps _original backup copies next to each file. Add that flag only after a sample run on a copy of the library has verified the result.Proprietary RAW formats (CR3, NEF, ARW, RW2, ORF, RAF, and DNG when it is your RAW master) can accept embedded metadata via ExifTool, but writing into the manufacturer container is the wrong default when those RAWs are your master files. Two practical patterns.
Exclude RAW from the main embed pass (double-dash --ext excludes):
exiftool \
-IPTC:By-line="Jane Smith" \
-IPTC:CopyrightNotice="Copyright 2026 Jane Smith. All rights reserved." \
--ext CR3 --ext CR2 --ext NEF --ext ARW --ext RW2 --ext ORF --ext RAF \
-P -r \
"/path/to/image library/"
Then generate matching XMP sidecars for the RAW files themselves (single-dash -ext includes only the listed extensions):
exiftool \
-XMP-dc:Creator="Jane Smith" \
-XMP-dc:Rights="Copyright 2026 Jane Smith. All rights reserved." \
-XMP-dc:Subject="landscape" -XMP-dc:Subject="aerial" -XMP-dc:Subject="dawn" \
-o %d%f.xmp \
-ext CR3 -ext NEF -ext ARW -ext RW2 -ext ORF -ext RAF \
-r \
"/path/to/raw library/"
-o %d%f.xmp writes a sidecar next to each RAW; the RAW binary is never opened for writing. Lightroom, Capture One and Bridge read these sidecars automatically.
For editorial stock and event work, keywords differ per file. ExifTool imports a CSV directly. The first column must be SourceFile; multi-value fields use a chosen separator (here |) that you pass with -sep.
SourceFile,IPTC:By-line,IPTC:CopyrightNotice,IPTC:Keywords,IPTC:Caption-Abstract,IPTC:DateCreated
/Volumes/Library/IMG_0001.jpg,Jane Smith,Copyright 2026 Jane Smith,mountain|snow|summit,Mount Rainier summit,2026:06:15
/Volumes/Library/IMG_0002.jpg,Jane Smith,Copyright 2026 Jane Smith,forest|trail|mist,Rainier trail in mist,2026:06:15
/Volumes/Library/IMG_0003.jpg,Jane Smith,Copyright 2026 Jane Smith,lake|reflection|alpine,Reflection Lake sunrise,2026:06:16
If a copyright, caption or filename contains a literal comma or double quote, wrap the field in double quotes and double any embedded quote per RFC 4180 CSV rules, otherwise the column count breaks and ExifTool will refuse the row.
Inject it with:
exiftool -csv=/path/to/metadata.csv -sep "|" -P "/path/to/image library/"
ExifTool only touches files listed in the CSV. Add -overwrite_original once a sample result looks right.
Spot-check a single file, then audit the whole library.
exiftool -IPTC:By-line -IPTC:CopyrightNotice -IPTC:Keywords \
-XMP-dc:Creator -XMP-dc:Rights \
"/path/to/image library/IMG_0001.jpg"
Export everything to CSV for a spreadsheet review:
exiftool -csv \
-IPTC:By-line -IPTC:CopyrightNotice -IPTC:Keywords \
-IPTC:Caption-Abstract -IPTC:DateCreated \
-r "/path/to/image library/" > metadata-audit.csv
A quick in-terminal count of files whose By-line column is blank:
exiftool -csv -IPTC:By-line -r "/path/to/image library/" \
| awk -F',' 'NR>1 && $2=="" {c++} END {print c+0 " files missing IPTC:By-line"}'
metadata-audit.csv row count matches the number of deliverable images..xmp sidecar in the same directory._original backup copies are either kept for rollback or removed after verification.exiftool -ver string is recorded in your delivery notes.ExifTool on this workload is I/O-bound. On a 10,000-JPEG library at roughly 6 MB per file (~60 GB total), the limits are disk throughput and Perl's per-file header parse, not CPU count. Two vCPUs are not the bottleneck, and ExifTool has no GPU or Apple-silicon dependency for metadata writes.
A simple monthly-cost worksheet, using the posted $29 monthly rate (no daily rate is published, so a half-month of use still pays the full monthly rate):
For the metadata step alone, the $29 virtual Intel macOS plan is enough.
Start your cloud Mac session → or review plans on /mac-hosting.
Related guides: