Extended metadata schema

The PhotoSpeak XMP-ps namespace — generated from the shared schema

PhotoSpeak stores everything it knows about a photo inside the photo file itself, as XMP metadata. The descriptive fields use standard namespaces (Dublin Core, IPTC, MWG regions); everything richer — voice recordings, transcripts, people, place, story, embeddings, provenance — lives in a custom namespace so it travels with the image and is yours to keep.

Namespace URI: http://photospeak.app/xmp/1.0/
Preferred prefix: ps (e.g. ps:Weather)
Free reader / recover your data: photospeak.app/viewer

Recovering your data without PhotoSpeak

Every enriched image also carries a plain-language manifest in the standard photoshop:Instructions field (visible in Photoshop, Lightroom, Bridge and Windows file details), naming this namespace and listing its fields. So even if PhotoSpeak is gone, the image tells you what it holds and where to read it. The data is standard XMP: any XMP library (for example the open-source ExifTool) can extract the raw ps:* values, then decode them as described below. The free Universal Gallery viewer does all of this in your browser, with no account and no server.

How the heavy fields are packed

Every field in this namespace

This namespace defines 82 fields. Not every image contains every field — each carries only what applies to it.

FieldTypeDescription
Context note (audio)
ps:ContextNotestringContext note record identifier
ps:ContextNoteDurationstringDuration of the context note audio
ps:ContextNoteFormatstringAudio format of the context note source
ps:ContextNoteHashstringHash of the context note audio file
ps:ContextNoteTextstringFull text of the context note
Continuation sets
ps:ContinuationOfstringpHash of the parent image this is a continuation of
ps:LinkedImagesstringJSON array of image UUIDs linked in this continuation set
ps:VolumeNumberintegerVolume number in a continuation set (1 = original, 2+ = overflow)
Derivatives
ps:AnimatedFacePathsstringPaths to animated face derivatives
ps:ColourisedPathstringPath to the colourised version of this image
ps:DepthMapPathstringPath to the depth map for this image
Detection
ps:DetectReviewedTypesstringDetection types that have been reviewed
ps:DetectSuppressedstringDetection results suppressed by the user
Diarization
ps:TranscriptionDiarizationstringSpeaker diarization L1 block (JSON) for the transcription audio.
ps:VoiceEmbeddingsstringPer-segment packed voice embeddings for the transcription audio.
Embeddings
ps:FaceEmbeddingsstringPer-region face embeddings (model-tagged JSON array). See desktop xmp.py.
Enrichment control
ps:EnrichmentOptOutstringWhen '1', the geocode/environment/weather pipeline steps skip this image so derived fields can be hand-curated.
Environment
ps:AirQualitystringAir quality index at capture location
ps:DominantColorsstringDominant colour palette extracted from the image
ps:ElevationstringElevation at capture location
ps:GoldenHourstringGolden hour window at capture date and location
ps:MoonPhasestringMoon phase at capture date
ps:NearbyPOIsstringPoints of interest near capture location
ps:SeasonstringSeason at capture date and location
ps:SunPositionstringSun altitude and azimuth at capture time
ps:SunrisestringSunrise time at capture date and location
ps:SunsetstringSunset time at capture date and location
ps:TerrainstringTerrain type at capture location
ps:TimezonestringTimezone at capture location
ps:UVIndexstringUV index at capture time and location
ps:WeatherstringWeather conditions at time and place of capture
Hashes
ps:ClipEmbeddingstringCLIP model embedding vector
ps:ClipEmbeddingHashstringHash of the CLIP embedding for integrity check
ps:ClipEmbeddingModelstringCLIP model identifier used for embedding
ps:ImageDHashstringDifference hash of the image
ps:ImageHashDimensionsstringDimensions used when computing image hashes
ps:ImagePHashstringPerceptual hash of the image
Identity / author
ps:AppVersionstringPhotoSpeak app version that last wrote metadata
ps:PhotographerIdentityIdstringLinks the author to a row in the identity library (unified people model).
ps:PhotographerPortraitstringEmbedded or referenced photographer portrait
ps:PhotographerPortraitHashstringHash of the photographer portrait data
ps:SourceNotesstringNotes about the source or origin of the image (free-text journal entry)
Modes (knowledge substrate)
ps:CollectionsstringRESERVED, DORMANT (do not reuse this tag). Was the planned per-image collection-membership codec (JSON array [{id, name}]). SUPERSEDED for curated Collections by the account-data model (Collections S2-S6, 2026-07-05..06): membership now lives in the DB + profile mirror keyed by ImageUUID, NOT in the image - see docs/adr/0007 (Collections half) + docs/current/Image_Grouping_And_Relationships_WIP.md. The tag name stays reserved as the likely foundation for Linked-images (Concept B) / share-in-file, so it is intentionally NOT deleted.
ps:ModeDatastringKnowledge substrate v2 (ADR 0007). JSON ARRAY of self-describing mode entries: [{mode, name, version, fields:[{k, label, type, unit?, value}]}]. Self-describing so any PhotoSpeak client or library reader interprets it WITHOUT the mode definition. Field option-lists/order/icon/lens-hints/capture-prompts live in the definition registry (profile/ mirror), NOT the image.
Provenance
ps:CopiedFromstringThe parent instance's ImageUUID. Stamped when a same-machine duplicate (same UUID, different file) is renumbered to a fresh instance UUID, recording the lineage link (C2PA ingredient-reference pattern).
ps:ImageContentHashstringExact sha256 of the image's pixel bytes. Confirms a byte-identical copy (vs corruption) when a same-machine ImageUUID collision is detected. The exact UUID collision is the fork trigger; this is the copy-vs-corruption confirmation.
ps:ImageUUIDstringUnique identifier for this image instance
ps:OriginInstancestringInstance identifier of the originating PhotoSpeak install
ps:OriginOwnerstringOwner identifier from the originating instance
ps:OriginPlatformstringThe platform on which this image's PhotoSpeak instance ORIGINATED (desktop/mobile/web). Set ONCE at mint time alongside ImageUUID + OriginInstance and preserved thereafter - a later edit on another platform does NOT change it (that is AppVersion / FieldHLCs). A fork mints a new instance, so it takes the forking platform; CopiedFrom preserves the lineage.
ps:ProvenanceChainstringThe HLC-ordered, hash-linked event ledger (JSON array of ledger entries) - the durable twin of the coordinator's sync_events. See docs/reference/Ledger_Entry_Schema.md. Supersedes the SyncVersion/PublishedVersion slots.
ps:PublishedVersionintegerVersion number when last published
ps:SyncVersionintegerMonotonic sync version counter
Scene analysis
ps:EraMismatchstringFlag indicating EXIF date conflicts with estimated era
ps:EstimatedErastringEstimated decade or era the photo depicts
ps:EstimatedEraScorestringConfidence score for era estimation
ps:IsBlackAndWhitestringWhether the image is black and white
ps:PhotoOfPhotostringWhether this image is a photo of another photo
ps:PhotoOfPhotoScorestringConfidence score for photo-of-photo detection
Species
ps:SpeciesstringSpecies detected in the image
Subject (vs capture)
ps:SubjectDatestringWhat the photo is OF (ISO-8601 partial e.g. 1960 / 1960-05), distinct from EXIF capture date.
ps:SubjectGPSstringLat/lon of the scene depicted, distinct from capture GPS.
Sync / merge
ps:FieldHLCsstring{field_name: hlc} - the HLC of the last write to each scalar metadata field, so cross-device edits converge last-writer-wins on HLC instead of arrival order. Travels with the image as part of merge state.
Transcription (audio)
ps:TranscriptionstringAudio transcription record identifier
ps:TranscriptionDurationstringDuration of the transcription audio
ps:TranscriptionFormatstringAudio format of the transcription source
ps:TranscriptionHashstringHash of the transcription audio file
ps:TranscriptionTextstringFull text of the audio transcription (human-editable; feeds the LLM extractor)
Transcription boundaries
ps:TranscriptionOffsetsstringPer-recording boundaries within the appended transcription audio.
Voice threads
ps:VoiceThread1stringVoice thread slot 1
ps:VoiceThread2stringVoice thread slot 2
ps:VoiceThread3stringVoice thread slot 3
ps:VoiceThread4stringVoice thread slot 4
ps:VoiceThread5stringVoice thread slot 5
ps:VoiceThread6stringVoice thread slot 6
ps:VoiceThread7stringVoice thread slot 7
ps:VoiceThreadCountintegerNumber of voice threads attached to this image
ps:VoiceThreadsstringVoice threads container or summary
Watermark
ps:WatermarkPatchstringReversible watermark: lossless clean-crop patch that restores the marked region in PhotoSpeak/HTML viewers.
ps:WatermarkPatchHashstringIntegrity hash of the reversible-watermark clean-crop patch.
ps:WatermarkRectstringPlacement rectangle of the reversible watermark.
ps:WatermarkStylestringStyle descriptor of the reversible watermark.