Journalism skill

Photo metadata

Embed caption, credit, alt text, and license inside the image file so the metadata travels wherever the photo goes.

Why this matters

Metadata embedded in an image file travels with the file. Photo CMSs (Photo Mechanic, Lightroom, Capture One) and wire intake systems read a photo's caption, credit, and rights from its IPTC and XMP blocks — not from a separate document or the email it arrived in. If the caption, credit, alt text, and license are not inside the file, they are gone the moment the photo is downloaded, forwarded, or re-uploaded.

One exiftool pass writes the EXIF, IPTC, and XMP layers together and leaves every other tag (camera settings, shot time) untouched. Embedded metadata is what lets a partner newsroom find a photo, credit it correctly, and republish it under a clear license without contacting the photographer. Strip it, and the same photo is an orphaned file.

When to use

When not to use: editing pixels (this is metadata only); writing alt text for an HTML <img> tag (use accessibility-compliance); preserving web pages as evidence (use web-archiving).

The discipline

These are the failures a capable model makes anyway. They matter more than any tag name.

1

Caption only what is visible

Describe what the frame shows, not what you were told. Do not infer events, intent, identities, relationships, or legal status you cannot see. "Demonstrators gather to protest a court ruling" is a claim about facts not in the frame; "A crowd holds signs outside a courthouse" is the photo.

2

Label people from visible evidence

Name an agency or role only from a visible marking — a labeled vest, a uniform, a badge, a patch. Otherwise write "officers in tactical gear," "a man in a blue shirt." Never assert someone's immigration or legal status unless it is unambiguous in the frame.

3

Always write alt text — it is not the caption

Write both: a short screen-reader description in XMP-iptcCore:AltTextAccessibility and the publishable caption in IPTC:Caption-Abstract. Models routinely write the caption and skip the alt text.

4

Keep structured fields neutral

Editorial framing or a contested label belongs in Headline, never in City, Caption-Abstract, or the location fields. Partner newsrooms apply their own language; clean structured fields let them.

5

Verify the round-trip from the file

Read the metadata back from the written file, not from your buffer. After any upload or transfer, re-read it from the destination — a 200 response proves the bytes were accepted, not that the metadata survived.

Field map

A JPEG can carry the same fact in three places. Write all three; exiftool keeps them consistent. EXIF is written by the camera and survives tools that strip other layers. IPTC-IIM is the legacy newsroom standard; wire intake systems still index it first. XMP is the modern XML layer with no byte limits.

Role IPTC (IIM) XMP EXIF
Photographer IPTC:By-line XMP-dc:Creator EXIF:Artist
Credit (org / full) IPTC:Credit (org, max 32 chars) XMP-photoshop:Credit (full name / org)
Caption IPTC:Caption-Abstract XMP-dc:Description, XMP-iptcCore:ExtDescrAccessibility EXIF:ImageDescription
Alt text (short) XMP-iptcCore:AltTextAccessibility
Keywords IPTC:Keywords (repeatable) XMP-dc:Subject
Copyright IPTC:CopyrightNotice XMP-dc:Rights EXIF:Copyright
License (CC, machine-readable) XMP-cc:License, XMP-xmpRights:Marked, XMP-xmpRights:WebStatement, XMP-xmpRights:UsageTerms
Headline IPTC:Headline XMP-photoshop:Headline
Location IPTC:Sub-location, IPTC:City, IPTC:Province-State, IPTC:Country-* XMP-iptcCore:Location, XMP-photoshop:City, XMP-photoshop:State, XMP-photoshop:Country
Date IPTC:DateCreated XMP-photoshop:DateCreated EXIF:DateTimeOriginal (source of truth)

One pass that writes all three layers

This command tags a single file with photographer, credit, caption, alt text, keywords, copyright, Creative Commons license, and location — then copies the shoot date from EXIF rather than typing it.

CAPTION="A crowd holds signs outside the Mercer County Courthouse, Friday, June 19, 2026, in Trenton, N.J. (Dana Rivera/Example News Collective)"
ALT="A crowd of people holding handmade signs stands on the steps of a stone courthouse."

exiftool -codedcharacterset=utf8 -overwrite_original \
  -EXIF:Artist="Dana Rivera" -XMP-dc:Creator="Dana Rivera" -IPTC:By-line="Dana Rivera" \
  -IPTC:Credit="Example News Collective" -XMP-photoshop:Credit="Dana Rivera / Example News Collective" \
  -IPTC:Caption-Abstract="$CAPTION" -XMP-dc:Description="$CAPTION" \
    -EXIF:ImageDescription="$CAPTION" -XMP-iptcCore:ExtDescrAccessibility="$CAPTION" \
  -XMP-iptcCore:AltTextAccessibility="$ALT" \
  -IPTC:Keywords="protest" -IPTC:Keywords+="Trenton" \
    -XMP-dc:Subject="protest" -XMP-dc:Subject+="Trenton" \
  -EXIF:Copyright="(c) 2026 Example News Collective. Licensed CC BY 4.0." \
    -IPTC:CopyrightNotice="(c) 2026 Example News Collective. CC BY 4.0." \
    -XMP-dc:Rights="(c) 2026 Example News Collective. Licensed CC BY 4.0." \
  -XMP-xmpRights:Marked=True \
    -XMP-xmpRights:WebStatement="https://creativecommons.org/licenses/by/4.0/" \
    -XMP-xmpRights:UsageTerms="Licensed CC BY 4.0. Credit: Dana Rivera / Example News Collective." \
    -XMP-cc:License="https://creativecommons.org/licenses/by/4.0/" \
    -XMP-cc:AttributionName="Dana Rivera / Example News Collective" \
  -IPTC:City="Trenton" -IPTC:Province-State="New Jersey" \
    -IPTC:Country-PrimaryLocationName="United States" -IPTC:Country-PrimaryLocationCode="USA" \
  "-IPTC:DateCreated<EXIF:DateTimeOriginal" "-IPTC:TimeCreated<EXIF:DateTimeOriginal" \
    "-XMP-photoshop:DateCreated<EXIF:DateTimeOriginal" \
  photo.jpg

Then verify from the file — the step that gets skipped:

exiftool -G1 -s -IPTC:By-line -IPTC:Caption-Abstract \
  -XMP-iptcCore:AltTextAccessibility -XMP-cc:License -IPTC:Keywords photo.jpg

Batch tagging a folder

For a shoot, drive exiftool from a manifest instead of one command per file. embed.py in this skill's directory takes a folder plus a JSON manifest — constant credit and license fields, then per-image alt text, caption, and keywords — writes tagged copies, and reads each one back to confirm the metadata landed. Run python3 embed.py --help.

Common mistakes

Mistake Fix
Wrote a caption, no alt text Always write AltTextAccessibility too — they are different fields
By-line / Credit / City silently truncated Those IIM fields cap at 32 chars; put the full credit in XMP-photoshop:Credit
Caption states things not in the frame Describe only what is visible; move unseeable context out
Editorial label in City or caption Put framing in Headline; keep structured fields neutral
Assumed the upload kept the metadata Re-read the metadata from the destination file
Keywords as one comma-joined string Write repeatable Keywords records (and a dc:Subject list)
CC license note in plain text only Add the machine-readable cc:License and xmpRights:Marked fields

IPTC-IIM byte limits

IIM fields are byte-capped; exiftool truncates silently unless you pass -m. XMP has no limit, so put the short form in IPTC and the full form in XMP. Use -codedcharacterset=utf8 so accented names and curly quotes survive in the IPTC layer.

Field Max bytes
By-line 32
Credit 32
City 32
Province-State 32
Sub-location 32
Country-PrimaryLocationName 64
Country-PrimaryLocationCode 3
Headline 256
SpecialInstructions (usage terms) 256
CopyrightNotice 128
Caption-Abstract 2000
Keywords (per record) 64

Installation

# Recommended: install the journalism-core plugin

/plugin marketplace add jamditis/claude-skills-journalism

/plugin install journalism-core@claude-skills-journalism

# Or copy just this skill from the plugin tree

git clone https://github.com/jamditis/claude-skills-journalism.git

cp -r claude-skills-journalism/journalism-core/skills/photo-metadata ~/.claude/skills/

Or browse this skill in the GitHub repository.

Related skills

Metadata that travels with the photo

Caption, credit, alt text, and license embedded in the file — readable by any wire system or photo CMS.

View on GitHub