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

# OMSS IDs

> Learn about the OMSS ID format and how it is used to identify and resolve media in OMSS Core.

export const OMSSIDBuilder = () => {
  const [namespace, setNamespace] = React.useState("tmdb");
  const [values, setValues] = React.useState(["123", "456"]);
  const [result, setResult] = React.useState("");
  const [error, setError] = React.useState("");
  const [copied, setCopied] = React.useState(false);
  const FORBIDDEN = /[:\ ]/;
  const encodeSegment = s => encodeURIComponent(s);
  const needsEncoding = s => FORBIDDEN.test(s);
  React.useEffect(() => {
    const allSegments = [namespace, ...values];
    const hasEmpty = allSegments.some(s => s.trim() === "");
    if (hasEmpty) {
      setError("Namespace and all values must be non-empty.");
      setResult("");
      return;
    }
    setError("");
    const encoded = allSegments.map(encodeSegment);
    setResult(encoded.join(":"));
  }, [namespace, values]);
  const addValue = () => setValues(v => [...v, ""]);
  const removeValue = i => setValues(v => v.filter((_, idx) => idx !== i));
  const updateValue = (i, val) => setValues(v => v.map((s, idx) => idx === i ? val : s));
  const copyToClipboard = () => {
    if (!result) return;
    navigator.clipboard.writeText(result).then(() => {
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    });
  };
  const inputClass = "w-full px-3 py-1.5 text-sm rounded-lg border border-zinc-300 dark:border-zinc-700 bg-white dark:bg-zinc-900 !text-zinc-900 dark:!text-zinc-100 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-blue-500 font-mono";
  return <div className="not-prose p-5 rounded-2xl border border-zinc-200 dark:border-zinc-800 bg-zinc-50 dark:bg-zinc-950 space-y-4 my-6">
      {}
      <div className="space-y-1">
        <label className="text-xs text-zinc-500 dark:text-zinc-400">
          Namespace
          {needsEncoding(namespace) && <span className="ml-2 text-yellow-500">⚠ will be URI-encoded</span>}
        </label>
        <input className={inputClass} value={namespace} placeholder="e.g. tmdb" onChange={e => setNamespace(e.target.value)} />
      </div>

      {}
      <div className="space-y-2">
        <label className="text-xs text-zinc-500 dark:text-zinc-400">Values</label>
        {values.map((val, i) => <div key={i} className="flex gap-2 items-center">
            <input className={inputClass} value={val} placeholder={`value_${i + 1}`} onChange={e => updateValue(i, e.target.value)} />
            {needsEncoding(val) && <span className="text-yellow-500 text-xs shrink-0">⚠ encoded</span>}
            {values.length > 1 && <button onClick={() => removeValue(i)} className="text-red-400 hover:text-red-600 text-xs shrink-0 px-1">
                ✕
              </button>}
          </div>)}
        <button onClick={addValue} className="text-xs text-blue-500 hover:text-blue-700 dark:text-blue-400">
          + Add value
        </button>
      </div>

      {}
      <div className="space-y-1">
        <label className="text-xs text-zinc-500 dark:text-zinc-400">
          Generated OMSS ID
        </label>
        {error ? <p className="text-xs text-red-500 pl-4">{error}</p> : <div className="flex items-center gap-2">
            <code className="flex-1 px-3 py-2 rounded-lg bg-zinc-900 dark:bg-zinc-800 text-green-400 text-sm font-mono break-all">
              {result || "—"}
            </code>
            <button onClick={copyToClipboard} disabled={!result} className="shrink-0 px-3 py-2 text-xs rounded-lg bg-zinc-200 dark:bg-zinc-700 hover:bg-zinc-300 dark:hover:bg-zinc-600 disabled:opacity-40 transition-colors">
              {copied ? "✓ Copied" : "Copy"}
            </button>
          </div>}
      </div>

      {}
      {result && <div className="space-y-1">
          <label className="text-xs text-zinc-500 dark:text-zinc-400">Segment breakdown</label>
          <div className="flex flex-wrap gap-1">
            {result.split(":").map((seg, i) => <span key={i} className={`text-xs px-2 py-0.5 rounded-full font-mono ${i === 0 ? "bg-blue-100 dark:bg-blue-900 text-blue-700 dark:text-blue-300" : "bg-zinc-200 dark:bg-zinc-700 text-zinc-700 dark:text-zinc-300"}`}>
                {i === 0 ? `ns: ${seg}` : `value_${i}: ${decodeURIComponent(seg)}`}
              </span>)}
          </div>
        </div>}
    </div>;
};

OMSS Core ([unlike the current OMSS](/spec/latest/ref/introduction#media-ids)) does not use TMDB as the primary identifier for media. Instead, it uses a new identifier format called the OMSS ID. The OMSS ID is a unique identifier that can be used to identify and resolve media across different providers and services.

## Format

OMSS identifiers follow the format `<namespace>:<value_1>:<value_2>:...:<value_n>`. Values can contain any character except colons and whitespaces. If a value or namespace contains a forbidden character, it must be URI-encoded (`%3A` for colons and `%20` for whitespaces).

[Namespaces](/core/explanation/glossary#namespace) are used to differentiate between different [ID-Providers](/core/explanation/glossary#id-provider) and their respective identifier values. The namespace is the first part of the OMSS ID, followed by one or more values that uniquely identify the media within that namespace.

## OMSS Builder

You can use the OMSS ID Builder below to create a valid OMSS ID. Enter the namespace and values, and the builder will generate the corresponding OMSS ID for you.

<OMSSIDBuilder />


## Related topics

- [Introduction to OMSS v1.0](/spec/v1.0/ref/introduction.md)
- [Introduction to OMSS v1.1](/spec/latest/ref/introduction.md)
- [OMSS v1.0 Specification](/spec/v1.0/ref/spec.md)
