app.zeens.c2pa

zeens.app

Documentation

Content Credentials (C2PA) read from a post's original photos at upload, for the photos the creator chose to show them on. The rkey matches the rkey of the associated post record, as with app.zeens.postMeta. This is a summary of what the C2PA manifest said, not the manifest itself: the manifest can carry an uncropped ingredient thumbnail and the photographer's GPS, so it is deliberately not republished. The summary is the creator's statement, signed by their repo; `status` records what the validator found, and a labeler may attest it independently.

main record

Content Credentials (C2PA) read from a post's original photos at upload, for the photos the creator chose to show them on. The rkey matches the rkey of the associated post record, as with app.zeens.postMeta. This is a summary of what the C2PA manifest said, not the manifest itself: the manifest can carry an uncropped ingredient thumbnail and the photographer's GPS, so it is deliberately not republished. The summary is the creator's statement, signed by their repo; `status` records what the validator found, and a labeler may attest it independently.

Record Key any Any valid record key

Properties

createdAt string datetime Required

An RFC 3339 formatted timestamp.

images array of ref #credential Required

One entry per photo with a credential the creator chose to show. Sparse: a photo without one, or with the toggle off, has no entry. `index` and `blob` say which photo an entry is for.

maxLength: 4 itemsminLength: 1 items
subject string at-uri Required

AT-URI of the post these credentials belong to.

View raw schema
{
  "description": "Content Credentials (C2PA) read from a post's original photos at upload, for the photos the creator chose to show them on. The rkey matches the rkey of the associated post record, as with app.zeens.postMeta. This is a summary of what the C2PA manifest said, not the manifest itself: the manifest can carry an uncropped ingredient thumbnail and the photographer's GPS, so it is deliberately not republished. The summary is the creator's statement, signed by their repo; `status` records what the validator found, and a labeler may attest it independently.",
  "key": "any",
  "record": {
    "properties": {
      "createdAt": {
        "format": "datetime",
        "type": "string"
      },
      "images": {
        "description": "One entry per photo with a credential the creator chose to show. Sparse: a photo without one, or with the toggle off, has no entry. `index` and `blob` say which photo an entry is for.",
        "items": {
          "ref": "#credential",
          "type": "ref"
        },
        "maxLength": 4,
        "minLength": 1,
        "type": "array"
      },
      "subject": {
        "description": "AT-URI of the post these credentials belong to.",
        "format": "at-uri",
        "type": "string"
      }
    },
    "required": [
      "subject",
      "images",
      "createdAt"
    ],
    "type": "object"
  },
  "type": "record"
}
action object

No description available.

Properties

action string Required

The C2PA action identifier, e.g. c2pa.color_adjustments, c2pa.cropped, or a vendor's own such as com.adobe.*. Stored raw so a reader maps it to words at render time.

maxLength: 128 bytes
description string Optional

The producer's own description of the action, when it gave one. The only words a reader has for a vendor action it does not know.

maxLength: 300 bytes
softwareAgent string Optional

The software that performed this action, when it differs from the manifest's generator.

maxLength: 256 bytes
View raw schema
{
  "properties": {
    "action": {
      "description": "The C2PA action identifier, e.g. c2pa.color_adjustments, c2pa.cropped, or a vendor's own such as com.adobe.*. Stored raw so a reader maps it to words at render time.",
      "maxLength": 128,
      "type": "string"
    },
    "description": {
      "description": "The producer's own description of the action, when it gave one. The only words a reader has for a vendor action it does not know.",
      "maxLength": 300,
      "type": "string"
    },
    "softwareAgent": {
      "description": "The software that performed this action, when it differs from the manifest's generator.",
      "maxLength": 256,
      "type": "string"
    }
  },
  "required": [
    "action"
  ],
  "type": "object"
}
capture object

No description available.

Properties

device string Optional

The capture device that signed, e.g. "Leica M11-P".

maxLength: 256 bytes
signedAt string datetime Optional

An RFC 3339 formatted timestamp.

signer string Optional

Organisation on the capture manifest's signing certificate.

maxLength: 256 bytes
View raw schema
{
  "properties": {
    "device": {
      "description": "The capture device that signed, e.g. \"Leica M11-P\".",
      "maxLength": 256,
      "type": "string"
    },
    "signedAt": {
      "format": "datetime",
      "type": "string"
    },
    "signer": {
      "description": "Organisation on the capture manifest's signing certificate.",
      "maxLength": 256,
      "type": "string"
    }
  },
  "type": "object"
}
credential object

No description available.

Properties

actions array of ref#action Optional

Actions from the active manifest, in the order recorded.

maxLength: 32 items
blob string cid Required

CID of the blob as stored on the PDS. Binds the entry to one exact image, so a reordered or replaced photo cannot inherit another photo's credential. The stored blob is usually a re-encode of the original, which is what `embedded` reports.

capture ref #capture Optional

Present when the photo's provenance reaches back to a camera that signed the capture, either because the active manifest is the camera's own or because an ingredient's is.

digitalSourceType string Optional

IPTC digital source type of the asset, as a URI, e.g. http://cv.iptc.org/newscodes/digitalsourcetype/digitalCapture or .../trainedAlgorithmicMedia. The strongest signal of generative AI involvement.

maxLength: 256 bytes
embedded boolean Optional

True when the stored blob is the original file, byte for byte, so anyone can re-verify its credential from the PDS: from the manifest inside it, or for a cloud manifest by following the file's pointer. False when the upload was re-encoded, which strips both.

generator string Optional

The app or device that produced the active manifest, with its version, e.g. "Adobe Lightroom Classic 14.3".

maxLength: 256 bytes
index integer Required

Position of the photo in the post's embed.

minimum: 0maximum: 3
ingredients array of ref#ingredient Optional

Source files the active manifest names, e.g. the raw file a Lightroom export was made from. Titles and whether each carries a credential of its own, never thumbnails: an ingredient's thumbnail is often the uncropped original.

maxLength: 16 items
signedAt string datetime Optional

Time of the manifest's signature, from its trusted timestamp when it has one.

signer string Required

Organisation on the signing certificate, e.g. "Adobe Inc." or "Leica Camera AG".

maxLength: 256 bytes
status string Required

What validation found. trusted: the signer chains to the official C2PA Trust List. legacy: the signer chains only to the frozen Interim Trust List. unrecognised: the manifest is intact but its signer is on neither list. A manifest that failed validation is never written.

Known values: trusted, legacy, unrecognised
View raw schema
{
  "properties": {
    "actions": {
      "description": "Actions from the active manifest, in the order recorded.",
      "items": {
        "ref": "#action",
        "type": "ref"
      },
      "maxLength": 32,
      "type": "array"
    },
    "blob": {
      "description": "CID of the blob as stored on the PDS. Binds the entry to one exact image, so a reordered or replaced photo cannot inherit another photo's credential. The stored blob is usually a re-encode of the original, which is what `embedded` reports.",
      "format": "cid",
      "type": "string"
    },
    "capture": {
      "description": "Present when the photo's provenance reaches back to a camera that signed the capture, either because the active manifest is the camera's own or because an ingredient's is.",
      "ref": "#capture",
      "type": "ref"
    },
    "digitalSourceType": {
      "description": "IPTC digital source type of the asset, as a URI, e.g. http://cv.iptc.org/newscodes/digitalsourcetype/digitalCapture or .../trainedAlgorithmicMedia. The strongest signal of generative AI involvement.",
      "maxLength": 256,
      "type": "string"
    },
    "embedded": {
      "description": "True when the stored blob is the original file, byte for byte, so anyone can re-verify its credential from the PDS: from the manifest inside it, or for a cloud manifest by following the file's pointer. False when the upload was re-encoded, which strips both.",
      "type": "boolean"
    },
    "generator": {
      "description": "The app or device that produced the active manifest, with its version, e.g. \"Adobe Lightroom Classic 14.3\".",
      "maxLength": 256,
      "type": "string"
    },
    "index": {
      "description": "Position of the photo in the post's embed.",
      "maximum": 3,
      "minimum": 0,
      "type": "integer"
    },
    "ingredients": {
      "description": "Source files the active manifest names, e.g. the raw file a Lightroom export was made from. Titles and whether each carries a credential of its own, never thumbnails: an ingredient's thumbnail is often the uncropped original.",
      "items": {
        "ref": "#ingredient",
        "type": "ref"
      },
      "maxLength": 16,
      "type": "array"
    },
    "signedAt": {
      "description": "Time of the manifest's signature, from its trusted timestamp when it has one.",
      "format": "datetime",
      "type": "string"
    },
    "signer": {
      "description": "Organisation on the signing certificate, e.g. \"Adobe Inc.\" or \"Leica Camera AG\".",
      "maxLength": 256,
      "type": "string"
    },
    "status": {
      "description": "What validation found. trusted: the signer chains to the official C2PA Trust List. legacy: the signer chains only to the frozen Interim Trust List. unrecognised: the manifest is intact but its signer is on neither list. A manifest that failed validation is never written.",
      "knownValues": [
        "trusted",
        "legacy",
        "unrecognised"
      ],
      "type": "string"
    }
  },
  "required": [
    "index",
    "blob",
    "status",
    "signer"
  ],
  "type": "object"
}
ingredient object

No description available.

Properties

credential boolean Required

True when the ingredient carries a Content Credential of its own.

title string Optional

The ingredient's title as its manifest records it, usually a file name.

maxLength: 256 bytes
View raw schema
{
  "properties": {
    "credential": {
      "description": "True when the ingredient carries a Content Credential of its own.",
      "type": "boolean"
    },
    "title": {
      "description": "The ingredient's title as its manifest records it, usually a file name.",
      "maxLength": 256,
      "type": "string"
    }
  },
  "required": [
    "credential"
  ],
  "type": "object"
}

Lexicon Garden

@