> ## Documentation Index
> Fetch the complete documentation index at: https://docs.siftstack.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Getting started with Metadata in Sift

> Learn how to create Metadata keys and filter resources in Sift

export const MintTable = ({columns = [], rows = [], columnWidths = []}) => {
  const pushTextWithLineBreaks = (parts, text, keyBase) => {
    const segments = String(text).split(/\\n|\n/);
    segments.forEach((segment, idx) => {
      if (segment) {
        parts.push(<span key={`${keyBase}-text-${idx}`}>{segment}</span>);
      }
      if (idx < segments.length - 1) {
        parts.push(<br key={`${keyBase}-br-${idx}`} />);
      }
    });
  };
  const parseMarkdown = text => {
    if (text === null || text === undefined) return "";
    const str = String(text);
    const parts = [];
    let lastIndex = 0;
    const pattern = /(`[^`]+`|\*\*[^*]+\*\*|\*[^*]+\*|\[([^\]]+)\]\(([^)]+)\))/g;
    let match;
    while (true) {
      match = pattern.exec(str);
      if (match === null) {
        break;
      }
      if (match.index > lastIndex) {
        pushTextWithLineBreaks(parts, str.substring(lastIndex, match.index), `before-${lastIndex}`);
      }
      const fullMatch = match[0];
      if (fullMatch.startsWith("`") && fullMatch.endsWith("`")) {
        parts.push(<code key={match.index}>{fullMatch.slice(1, -1)}</code>);
      } else if (fullMatch.startsWith("**") && fullMatch.endsWith("**")) {
        parts.push(<strong key={match.index}>{fullMatch.slice(2, -2)}</strong>);
      } else if (fullMatch.startsWith("*") && fullMatch.endsWith("*")) {
        parts.push(<em key={match.index}>{fullMatch.slice(1, -1)}</em>);
      } else if (fullMatch.startsWith("[")) {
        const linkText = match[2];
        const linkUrl = match[3];
        parts.push(<a key={match.index} href={linkUrl} className="text-black-600 dark:text-black-400">
            {linkText}
          </a>);
      }
      lastIndex = pattern.lastIndex;
    }
    if (lastIndex < str.length) {
      pushTextWithLineBreaks(parts, str.substring(lastIndex), `tail-${lastIndex}`);
    }
    if (parts.length > 0) {
      return parts;
    }
    const plainParts = [];
    pushTextWithLineBreaks(plainParts, str, "plain");
    return plainParts.length ? plainParts : str;
  };
  const safeColumns = Array.isArray(columns) ? columns : [];
  const safeRows = Array.isArray(rows) ? rows : [];
  const safeColumnWidths = Array.isArray(columnWidths) ? columnWidths : [];
  const hasColumnWidths = safeColumnWidths.some(w => w !== null && w !== undefined && w !== "");
  const toCssWidth = width => typeof width === "number" ? `${width}px` : String(width);
  const getColumnStyle = idx => {
    const rawWidth = safeColumnWidths[idx];
    if (rawWidth === null || rawWidth === undefined || rawWidth === "") {
      return undefined;
    }
    const width = toCssWidth(rawWidth);
    return {
      width,
      minWidth: width
    };
  };
  const containerStyle = hasColumnWidths ? undefined : {
    overflowX: "auto"
  };
  const tableStyle = hasColumnWidths ? {
    tableLayout: "fixed",
    width: "100%"
  } : {
    width: "max-content",
    minWidth: "100%"
  };
  if (!Array.isArray(columns) || !Array.isArray(rows) || !Array.isArray(columnWidths)) {
    console.warn("MintTable received invalid props:", {
      columns,
      rows,
      columnWidths
    });
  }
  if (!safeColumns.length && !safeRows.length) {
    return null;
  }
  return <div className="mint-table-container" style={containerStyle}>
      <table style={tableStyle}>
        {hasColumnWidths && <colgroup>
            {safeColumns.map((_, idx) => {
    const style = getColumnStyle(idx);
    return <col key={idx} style={style} />;
  })}
          </colgroup>}
        <thead>
          <tr>
            {safeColumns.map((col, idx) => <th key={idx} className="text-left" style={getColumnStyle(idx)}>
                <b>{parseMarkdown(col)}</b>
              </th>)}
          </tr>
        </thead>
        <tbody>
          {safeRows.map((row, rIdx) => {
    const safeRow = Array.isArray(row) ? row : [];
    return <tr key={rIdx}>
                {safeRow.map((cell, cIdx) => <td key={cIdx} style={getColumnStyle(cIdx)}>
                    {parseMarkdown(cell)}
                  </td>)}
              </tr>;
  })}
        </tbody>
      </table>
    </div>;
};

export const SiftIcon = ({className}) => <span className={`inline-flex items-center align-middle text-black dark:text-white ${className || ''}`}>
    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Artwork" x="0px" y="0px" viewBox="0 0 1005.58 733.96" style={{
  enableBackground: "new 0 0 1005.58 733.96",
  width: "2em",
  height: "2em"
}} xmlSpace="preserve">
      <path fill="currentColor" d="M552.16,150.89c-165.6,0-180.29,160.61-300.62,192.32v2.67h601.24v-2.67C747.74,324.18,717.72,150.89,552.16,150.89z   M453.46,583.08c165.6,0,180.29-160.61,300.62-192.32v-2.67H152.84v2.67C257.88,409.78,287.91,583.08,453.46,583.08z" />
    </svg>
  </span>;

## Overview

In this tutorial, you'll create and apply Metadata in Sift, then use it to filter a Run. Metadata helps you organize resources using consistent key-value pairs across your workspace.

## Prerequisites

* At least one Run in your workspace

## Step 1: Understand Metadata in Sift

Metadata in Sift uses key-value pairs to organize and filter resources across your workspace. Each Metadata key is defined once and assigned a data type to ensure consistent values. Metadata values support three data types: **string**, **number**, and **boolean**.

You can apply Metadata to the following resources: **Runs**, **Assets**, **Annotations**, **Rules**, **Reports**, **Report Templates**, **Campaigns**, **Calculated Channels**, and **User-Defined Functions**.

## Step 2: Create a Metadata key

Let's create a numeric Metadata key.

1. Click your profile icon, which shows the first initial of your account name.
2. Select **Manage**.
3. In the **Manage** navigation menu, click **Metadata**.
4. Click **+ Create Metadata Key**.
5. In the **Name** box, enter the following:
   ```
   priority_level
   ```
6. In the **Type** list, select **number**.
7. Click **Create**.

## Step 3: Add a Metadata key to a Run

Now, let's add the created Metadata key to a Run.

1. In **Sift**, click <SiftIcon className="icon-sift" />.

2. In the **Runs** table, click the name of a Run to add the Metadata key you just created.

   Later in [Step 5](#step-5-optional-remove-metadata-key), you will have the option to remove the Metadata key. For now, we will use this Run as an example to demonstrate how Runs, like all Sift resources, can support Metadata.

3. Click **Edit**.

4. Click **+ Add Metadata**.

5. In the **Select or create key** list, select **priority\_level**.

6. In the **Enter number** list, enter the following (where `1` on the 1-5 scale refers to high priority):
   ```
   1
   ```

7. Click **Save changes**.

## Step 4: Locate a Run by its Metadata key

Let's locate the Run using the **priority\_level** Metadata key.

1. In **Sift**, click <SiftIcon className="icon-sift" />.
2. In the **Runs** tab, click **Metadata**.
3. In the **Select key** list, select **priority\_level**.
4. In the **Enter number** box, enter **1**.

## Step 5 (optional): Remove Metadata key

To remove the Metadata key added to the Run, consider the following steps:

1. In the Run's overview page, click **Edit**.
2. In the **Metadata** section, locate the **priority\_level** key.
3. Click <Icon icon="circle-minus" /> **Remove**.
4. Click **Save changes**.

## Conclusion

You created a Metadata key, applied it to a Run, and used it to filter resources in Sift. Metadata helps you organize your workspace and quickly locate the data you need.

## Resources

* Reference: [Metadata](../../documentation/manage/organize-and-filter-resources-with-metadata)
* How-to guide: [Manage Metadata](../../documentation/manage/organize-and-filter-resources-with-metadata)
