We are still figuring out the best way to define an IPA Metadata Standard. For the sake of transparency, the following document is our thoughts so far but is subject to change as we release future versions.

This is the JSON metadata that is associated with an IP Asset, and gets stored inside of an IP Account. You must call setMetadata(...) inside of the IP Account in order to set the metadata, and then call metadata() to read it.

Attributes & Structure

Below are the important attributes you should provide in your IP metadata. Under the Required For column is what the specific field is required for:

  • ๐Ÿ” Story Explorer - this field will help display your IP on the Story Explorer
  • ๐Ÿ•ต๏ธ Commercial Infringement Check - this field is required if your IP is commercial (that is, has commercialUse = true license terms attached). We will use these fields to run an infringement check on your IP.
  • ๐Ÿค– AI Agents - used for displaying metadata associated with AI Agents
Property NameTypeDescriptionRequired For
titlestringTitle of the IP๐Ÿ” Story Explorer
descriptionstringDescription of the IP๐Ÿ” Story Explorer
createdAtstringDate/Time that the IP was created (either ISO8601 or unix format). This field can be used to specify historical dates that arenโ€™t on-chain. For example, Harry Potter was published on June 26.๐Ÿ” Story Explorer
imagestringAn image for your IP.๐Ÿ” Story Explorer
imageHashstringHash of your image using SHA-256 hashing algorithm. See here for how that is done.๐Ÿ” Story Explorer
creatorsIpCreator[]An array of information about the creators. See the type defined below๐Ÿ” Story Explorer
mediaUrlstringUsed for infringement checking, points to the actual media (ex. image or audio)๐Ÿ•ต๏ธ Commercial Infringement Check
mediaHashstringHashed string of the media using SHA-256 hashing algorithm. See here for how that is done.๐Ÿ•ต๏ธ Commercial Infringement Check
mediaTypestringType of media (audio, video, image), based on mimeType. See the allowed media types here.๐Ÿ•ต๏ธ Commercial Infringement Check
aiMetadataAIMetadataUsed for registering & displaying AI Agent Metadata. See the type defined below๐Ÿค– AI Agents
N/AN/AYou can include other values as well.N/A

Type Definitions

Here are the type definitions for the complex types used in the metadata:

type IpCreator = {
  name: string;
  address: Address;
  contributionPercent: number; // add up to 100
  description?: string;
  image?: string;
  socialMedia?: IpCreatorSocial[];
  role?: string;
};

type IpCreatorSocial = {
  platform: string;
  url: string;
};

Media Types

The following media types are allowed for the mediaType field:

Media TypeDescription
image/jpegJPEG image
image/pngPNG image
image/apngAnimated PNG image
image/avifAV1 Image File Format
image/gifGIF image
image/svg+xmlSVG image
image/webpWebP image
audio/wavWAV audio
audio/mpegMP3 audio
audio/flacFLAC audio
audio/aacAAC audio
audio/oggOGG audio
audio/mp4MP4 audio
audio/x-aiffAIFF audio
audio/x-ms-wmaWMA audio
audio/opusOpus audio
video/mp4MP4 video
video/webmWebM video
video/quicktimeQuickTime video

Hashing Content

To hash content for the imageHash or mediaHash fields, you can use the SHA-256 hashing algorithm. Hereโ€™s an example of how to do this in JavaScript:

import { toHex, Hex } from "viem";

// get hash from a file
async function getFileHash(file: File): Promise<Hex> {
  const arrayBuffer = await file.arrayBuffer();
  const hashBuffer = await crypto.subtle.digest("SHA-256", arrayBuffer);
  return toHex(new Uint8Array(hashBuffer), { size: 32 });
}

// get hash from a url
async function getHashFromUrl(url: string): Promise<Hex> {
  const response = await axios.get(url, { responseType: "arraybuffer" });
  const buffer = Buffer.from(response.data);
  return "0x" + createHash("sha256").update(buffer).digest("hex");
}

Example Use Cases

This is the official Ippy mascot that is registered on mainnet. You can view it on our protocol explorer here.

{
  "title": "Ippy",
  "description": "Official mascot of Story.",
  "createdAt": "1728401700",
  "image": "https://ipfs.io/ipfs/QmSamy4zqP91X42k6wS7kLJQVzuYJuW2EN94couPaq82A8",
  "imageHash": "0x21937ba9d821cb0306c7f1a1a2cc5a257509f228ea6abccc9af1a67dd754af6e",
  "mediaUrl": "https://ipfs.io/ipfs/QmSamy4zqP91X42k6wS7kLJQVzuYJuW2EN94couPaq82A8",
  "mediaHash": "0x21937ba9d821cb0306c7f1a1a2cc5a257509f228ea6abccc9af1a67dd754af6e",
  "mediaType": "image/png",
  "creators": [
    {
      "name": "Story Foundation",
      "address": "0x67ee74EE04A0E6d14Ca6C27428B27F3EFd5CD084",
      "description": "The World's IP Blockchain",
      "contributionPercent": 100,
      "socialMedia": [
        {
          "platform": "Twitter",
          "url": "https://twitter.com/storyprotocol"
        },
        {
          "platform": "Telegram",
          "url": "https://t.me/StoryAnnouncements"
        },
        {
          "platform": "Website",
          "url": "https://story.foundation"
        },
        {
          "platform": "Discord",
          "url": "https://discord.gg/storyprotocol"
        },
        {
          "platform": "YouTube",
          "url": "https://youtube.com/@storyFDN"
        }
      ]
    }
  ],
  "tags": ["Ippy", "Story", "Story Mascot", "Mascot", "Official"], // experimental field
  "ipType": "Character" // experimental field
}

Optional Properties

The following properties are optional but can provide additional context about your IP Asset:

We are still figuring out the best way to define an IPA Metadata Standard. The fields below are bound to change or be removed at some point.

Property NameTypeDescription
ipTypestringType of the IP Asset, can be defined arbitrarily by the creator. I.e. โ€œcharacterโ€, โ€œchapterโ€, โ€œlocationโ€, โ€œitemsโ€, โ€œmusicโ€, etc
relationshipsIpRelationship[]The detailed relationship info with the IPAโ€™s direct parent asset, such as APPEARS_IN, FINETUNED_FROM, etc. See more examples here.
watermarkImagestringA separate image with your watermark already applied. This way apps choosing to use it can render this version of the image (with watermark applied).
mediaIpMedia[]An array of supporting media. Media type defined below
appStoryAppThis is assigned to verified application from Story directly (on a request basis so far). We will map each App ID to a name
tagsstring[]Any tags that can help surface this IPA
robotTermsIPRobotTermsAllows you to set Do Not Train for a specific agent
N/AN/AYou can include other values as well.

Type Definitions

type IpRelationship = {
  parentIpId: Address;
  type: string; // see "Relationship Types" docs below
};

Relationship Types

The different relationship types that can be used for the relationships attribute.

Story Relationships

  1. APPEARS_IN - A character APPEARS_IN a chapter.

  2. BELONGS_TO - A chapter BELONGS_TO a book.

  3. PART_OF - A book is PART_OF a series.

  4. CONTINUES_FROM - A chapter CONTINUES_FROM the previous one.

  5. LEADS_TO - An event LEADS_TO a consequence.

  6. FORESHADOWS - An event FORESHADOWS future developments.

  7. CONFLICTS_WITH - A character CONFLICTS_WITH another character.

  8. RESULTS_IN - A decision RESULTS_IN a significant change.

  9. DEPENDS_ON - A subplot DEPENDS_ON the main plot.

  10. SETS_UP - A prologue SETS_UP the story.

  11. FOLLOWS_FROM - A chapter FOLLOWS_FROM the previous one.

  12. REVEALS_THAT - A twist REVEALS_THAT something unexpected occurred.

  13. DEVELOPS_OVER - A character DEVELOPS_OVER the course of the story.

  14. INTRODUCES - A chapter INTRODUCES a new character or element.

  15. RESOLVES_IN - A conflict RESOLVES_IN a particular outcome.

  16. CONNECTS_TO - A theme CONNECTS_TO the main narrative.

  17. RELATES_TO - A subplot RELATES_TO the central theme.

  18. TRANSITIONS_FROM - A scene TRANSITIONS_FROM one setting to another.

  19. INTERACTED_WITH - A character INTERACTED_WITH another character.

  20. LEADS_INTO - An event LEADS_INTO the climax.?
    PARALLEL - story happening in parallel or around the same timeframe

AI Relationships

  1. TRAINED_ON - A model is TRAINED_ON a dataset.

  2. FINETUNED_FROM - A model is FINETUNED_FROM a base model.

  3. GENERATED_FROM - An image is GENERATED_FROM a fine-tuned model.

  4. REQUIRES_DATA - A model REQUIRES_DATA for training.

  5. BASED_ON - A remix is BASED_ON a specific workflow.

  6. INFLUENCES - Sample data INFLUENCES model output.

  7. CREATES - A pipeline CREATES a fine-tuned model.

  8. UTILIZES - A workflow UTILIZES a base model.

  9. DERIVED_FROM - A fine-tuned model is DERIVED_FROM a base model.

  10. PRODUCES - A model PRODUCES generated images.

  11. MODIFIES - A remix MODIFIES the base workflow.

  12. REFERENCES - An AI-generated image REFERENCES original data.

  13. OPTIMIZED_BY - A model is OPTIMIZED_BY specific algorithms.

  14. INHERITS - A fine-tuned model INHERITS features from the base model.

  15. APPLIES_TO - A fine-tuning process APPLIES_TO a model.

  16. COMBINES - A remix COMBINES elements from multiple datasets.

  17. GENERATES_VARIANTS - A model GENERATES_VARIANTS of an image.

  18. EXPANDS_ON - A fine-tuning process EXPANDS_ON base capabilities.

  19. CONFIGURES - A workflow CONFIGURES a modelโ€™s parameters.

  20. ADAPTS_TO - A fine-tuned model ADAPTS_TO new data.