# Data Catalog and Tracking Plans YAML Reference


> Complete reference for defining your Data Catalog and Tracking Plan resources using YAML configuration files.



This guide serves as a detailed reference for the CLI project YAML files that contain definitions of your Data Catalog and Tracking Plan resources.

## Overview

In the context of the Rudder CLI (`rudder-cli`) tool, a project typically consists of a root directory that contains all the project files. Within this root directory, each YAML file can contain definitions for resources of a particular type, for example, events, properties, custom data types, and Tracking Plans.

The location and naming of these YAML files is flexible, as you can store the YAML files anywhere within the project's root directory or subdirectories.

**Info:** Every spec file must set the top-level field `version` to `rudder/v1`.

You can also group some resources of the same type in the same file, allowing structures that can best serve your project's requirements. For example, you could have:

- A `events.yaml` file in the project's root directory that defines multiple events
- Another file `subdirectory/user-events.yaml` that defines additional events

**Info:** The Rudder CLI tool processes all valid YAML files within the project structure to recognize the defined resources.

The following sections detail the specific YAML formats and parameter definitions for each resource type.

For discriminator-based validation in Tracking Plan event rules and custom types, see the [Conditional Validation YAML Reference](https://www.rudderstack.com/docs/rudder-cli/yaml-data-catalog-and-tracking-plans/yaml-conditional-validation/).

## Events

You can define one or more events in the YAML file by setting `kind` to `events`.

The `spec` parameter of the YAML file has the following structure:

| Property | Type | Description |
| :----| :-----| :------|
| `events` <br/> Required | Array of [event definitions](#event-definition) | An array of event definitions grouped together in the same file. |

### Event definition

The event definitions have a structure that depends on the event type. All definitions share some common properties, as listed in the below table:

| Property | Type | Description |
| :----| :-----| :------|
| `id ` <br/> Required | String | Unique identifier for the event within the project. This parameter must be unique across all events. |
| `event_type` <br/> Required | String | Event type. Acceptable values are `track`, `identify`, `page`, `screen`, and `group`. |
| `description` | String | Event description. |
| `category` | String | Reference to an existing [event category](#event-categories). <br /><br />See [Manage Event Categories using Rudder CLI](https://www.rudderstack.com/docs/rudder-cli/data-catalog-and-tracking-plans/data-catalog/events/#event-categories) for more information. |

Additionally, `track` events (`event_type: track`) also support the following property:

| Property | Type | Description |
| :----| :-----| :------|
| `name` <br/> Required | String | The `track` event name. In other words, this parameter corresponds to the `event` property of the corresponding RudderStack `track` event. |

### Example {#event-example}

```yaml
version: rudder/v1
kind: events
metadata:
  name: myeventgroup
spec:
  events:
    - id: product_viewed
      name: "Product Viewed"
      event_type: track
      description: "This event is triggered every time a user views a product."
      category: "#category:browsing_category" # Reference to the Browsing category
    - id: added_to_cart
      name: "Added To Cart"
      event_type: track
      description: "This event is triggered every time the user adds a product to their cart."
    - id: identify
      event_type: identify
      description: "An event that identifies the user."
    - id: page
      event_type: page
```

### Event validation rules

<div class="vr-explorer vr-explorer--filtered" data-vr-explorer data-vr-instance="1">
<div class="vr-explorer__toolbar">
<div class="vr-explorer__toolbar-row">
<div class="vr-explorer__search-wrap">
<label class="vr-explorer__search-label" for="vr-rules-search-1">Search rules</label>
<input id="vr-rules-search-1" class="vr-explorer__search" type="search" placeholder="Search rules…" data-vr-search autocomplete="off">
</div>
<div class="vr-explorer__spec-wrap">
Spec version
<div class="vr-explorer__spec-toggle">
<button type="button" class="vr-explorer__spec-btn is-active" data-vr-spec="v1">v1</button>
<button type="button" class="vr-explorer__spec-btn" data-vr-spec="legacy">v0.1</button>
</div>
</div>
</div>
<div class="vr-explorer__toolbar-row vr-explorer__toolbar-row--filters">
<div class="vr-explorer__phase">
Filter by phase
<button type="button" class="vr-explorer__phase-btn is-active" data-vr-phase="all">All</button>
<button type="button" class="vr-explorer__phase-btn" data-vr-phase="syntactic">Syntactic</button>
<button type="button" class="vr-explorer__phase-btn" data-vr-phase="semantic">Semantic</button>
</div>
<p class="vr-explorer__count" data-vr-count data-vr-total="5">Showing <strong>5</strong> of 5 rules</p>
</div>
</div>
<div class="vr-explorer__rules"><div class="vr-rule" id="vr-rule-1-datacatalog-events-semantic-valid-v1" data-vr-rule data-phase="semantic" data-spec-version="v1" data-section="filtered-1" data-search="datacatalog/events/semantic-valid event references must resolve to existing resources semantic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">Event references must resolve to existing resources</h4>
<div class="vr-rule__meta">
semantic
error</div>
<p class="vr-rule__id">Rule ID: <code>datacatalog/events/semantic-valid</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-datacatalog-events-semantic-valid-v1-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-events-semantic-valid-v1-valid">

✓
Valid

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-datacatalog-events-semantic-valid-v1-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-events-semantic-valid-v1-invalid">

✕
Invalid

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-datacatalog-events-semantic-valid-v1">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-datacatalog-events-semantic-valid-v1-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Unique event name and type combinations (v1)</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: my-events
spec:
  events:
    - id: page_viewed
      event_type: track
      name: Page Viewed
    - id: product_clicked
      event_type: track
      name: Product Clicked</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-datacatalog-events-semantic-valid-v1-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Duplicate event name and type across files (v1)</h4><p class="vr-example__desc">Duplicate event name and event_type pairs in the resource graph fail validation.</p><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: my-events
spec:
  events:
    - id: page_viewed_2
      event_type: track
      name: Page Viewed</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
spec.yaml
<code class="vr-diagnostics__ref">/events/0</code>
duplicate name &#39;Page Viewed&#39; within kind &#39;events&#39;
</li></ul>
</div></div></div>
</div></div></div>
<div class="vr-rule" id="vr-rule-1-datacatalog-events-semantic-valid-legacy" data-vr-rule data-phase="semantic" data-spec-version="legacy" data-section="filtered-1" data-search="datacatalog/events/semantic-valid event references must resolve to existing resources semantic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">Event references must resolve to existing resources</h4>
<div class="vr-rule__meta">
semantic
error</div>
<p class="vr-rule__id">Rule ID: <code>datacatalog/events/semantic-valid</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-datacatalog-events-semantic-valid-legacy-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-events-semantic-valid-legacy-valid">

✓
Valid

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-datacatalog-events-semantic-valid-legacy-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-events-semantic-valid-legacy-invalid">

✕
Invalid

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-datacatalog-events-semantic-valid-legacy">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-datacatalog-events-semantic-valid-legacy-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Unique event name and type combinations (legacy)</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/0.1
kind: events
metadata:
  name: my-events
spec:
  events:
    - id: page_viewed
      event_type: track
      name: Page Viewed
    - id: product_clicked
      event_type: track
      name: Product Clicked</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-datacatalog-events-semantic-valid-legacy-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Duplicate event name and type across files (legacy)</h4><p class="vr-example__desc">Duplicate event name and event_type pairs in the resource graph fail validation.</p><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/0.1
kind: events
metadata:
  name: my-events
spec:
  events:
    - id: page_viewed_2
      event_type: track
      name: Page Viewed</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
spec.yaml
<code class="vr-diagnostics__ref">/events/0</code>
duplicate name &#39;Page Viewed&#39; within kind &#39;events&#39;
</li></ul>
</div></div></div>
</div></div></div>
<div class="vr-rule" id="vr-rule-1-datacatalog-events-spec-syntax-valid-v1" data-vr-rule data-phase="syntactic" data-spec-version="v1" data-section="filtered-1" data-search="datacatalog/events/spec-syntax-valid event spec syntax must be valid syntactic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">Event spec syntax must be valid</h4>
<div class="vr-rule__meta">
syntactic
error</div>
<p class="vr-rule__id">Rule ID: <code>datacatalog/events/spec-syntax-valid</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-datacatalog-events-spec-syntax-valid-v1-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-events-spec-syntax-valid-v1-valid">

✓
Valid

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-datacatalog-events-spec-syntax-valid-v1-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-events-spec-syntax-valid-v1-invalid">

✕
Invalid

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-datacatalog-events-spec-syntax-valid-v1">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-datacatalog-events-spec-syntax-valid-v1-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Valid events spec</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: my-events
spec:
  events:
    - id: page_viewed
      event_type: track
      name: Page Viewed
    - id: user_identified
      event_type: identify</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-datacatalog-events-spec-syntax-valid-v1-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">v1 event missing required event_type field</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: my-events
spec:
  events:
    - id: page_viewed
      name: Page Viewed</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
spec.yaml
<code class="vr-diagnostics__ref">/events/0/event_type</code>
&#39;event_type&#39; is required
</li></ul>
</div></div></div>
</div></div></div>
<div class="vr-rule" id="vr-rule-1-datacatalog-events-spec-syntax-valid-legacy" data-vr-rule data-phase="syntactic" data-spec-version="legacy" data-section="filtered-1" data-search="datacatalog/events/spec-syntax-valid event spec syntax must be valid syntactic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">Event spec syntax must be valid</h4>
<div class="vr-rule__meta">
syntactic
error</div>
<p class="vr-rule__id">Rule ID: <code>datacatalog/events/spec-syntax-valid</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-datacatalog-events-spec-syntax-valid-legacy-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-events-spec-syntax-valid-legacy-valid">

✓
Valid

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-datacatalog-events-spec-syntax-valid-legacy-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-events-spec-syntax-valid-legacy-invalid">

✕
Invalid (2 examples)

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-datacatalog-events-spec-syntax-valid-legacy">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-datacatalog-events-spec-syntax-valid-legacy-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Valid legacy events spec</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/0.1
kind: events
metadata:
  name: my-events
spec:
  events:
    - id: page_viewed
      event_type: track
      name: Page Viewed
      description: User viewed a page
    - id: user_identified
      event_type: identify</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-datacatalog-events-spec-syntax-valid-legacy-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Legacy event missing required id field</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/0.1
kind: events
metadata:
  name: my-events
spec:
  events:
    - name: Page Viewed
      event_type: track</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
spec.yaml
<code class="vr-diagnostics__ref">/events/0/id</code>
&#39;id&#39; is required
</li></ul>
</div></div><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Legacy event with invalid event_type</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/0.1
kind: events
metadata:
  name: my-events
spec:
  events:
    - id: my_event
      event_type: custom</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
spec.yaml
<code class="vr-diagnostics__ref">/events/0/event_type</code>
oneof
</li></ul>
</div></div></div>
</div></div></div>
<div class="vr-rule" id="vr-rule-1-project-duplicate-urn-all" data-vr-rule data-phase="syntactic" data-spec-version="all" data-section="filtered-1" data-search="project/duplicate-urn urns must be unique across the project syntactic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">URNs must be unique across the project</h4>
<div class="vr-rule__meta">
syntactic
errorAll spec versions</div>
<p class="vr-rule__id">Rule ID: <code>project/duplicate-urn</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-project-duplicate-urn-all-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-project-duplicate-urn-all-valid">

✓
Valid

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-project-duplicate-urn-all-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-project-duplicate-urn-all-invalid">

✕
Invalid

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-project-duplicate-urn-all">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-project-duplicate-urn-all-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Distinct URNs across files</h4><p class="vr-example__desc">Each spec declares a different resource, so URNs do not collide.</p><div class="rs-code">
<div class="rs-code__head">
a.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: events-a
spec:
  events:
    - id: order_completed
      name: Order Completed</code></pre></div>
</div><div class="rs-code">
<div class="rs-code__head">
b.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: events-b
spec:
  events:
    - id: cart_viewed
      name: Cart Viewed</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-project-duplicate-urn-all-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Same URN declared in two files</h4><p class="vr-example__desc">Both files declare the same event ID, which resolves to one URN. The rule flags each occurrence.</p><div class="rs-code">
<div class="rs-code__head">
a.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: events-a
spec:
  events:
    - id: order_completed
      name: Order Completed</code></pre></div>
</div><div class="rs-code">
<div class="rs-code__head">
b.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: events-b
spec:
  events:
    - id: order_completed
      name: Order Completed (duplicate)</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
a.yaml
<code class="vr-diagnostics__ref">/spec/events/0/id</code>
duplicate URN &#39;event:order_completed&#39;
</li><li class="vr-diagnostics__item">
b.yaml
<code class="vr-diagnostics__ref">/spec/events/0/id</code>
duplicate URN &#39;event:order_completed&#39;
</li></ul>
</div></div></div>
</div></div></div>
<div class="vr-rule" id="vr-rule-1-project-manifest-inline-conflict-all" data-vr-rule data-phase="syntactic" data-spec-version="all" data-section="filtered-1" data-search="project/manifest-inline-conflict a (workspace_id, urn) must not be defined in both an import-manifest and inline metadata.import with differing remote_ids syntactic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">A (workspace_id, urn) must not be defined in both an import-manifest and inline metadata.import with differing remote_ids</h4>
<div class="vr-rule__meta">
syntactic
errorAll spec versions</div>
<p class="vr-rule__id">Rule ID: <code>project/manifest-inline-conflict</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-project-manifest-inline-conflict-all-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-project-manifest-inline-conflict-all-valid">

✓
Valid

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-project-manifest-inline-conflict-all-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-project-manifest-inline-conflict-all-invalid">

✕
Invalid (2 examples)

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-project-manifest-inline-conflict-all">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-project-manifest-inline-conflict-all-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Manifest and inline metadata import distinct resources</h4><p class="vr-example__desc">One resource is imported via the manifest, a different one via inline metadata. No URN appears in both, so the project is valid.</p><div class="rs-code">
<div class="rs-code__head">
events.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: events
  import:
    workspaces:
      - workspace_id: &#34;ws-1&#34;
        resources:
          - urn: &#34;event:cart_viewed&#34;
            remote_id: &#34;remote_b&#34;
spec:
  events:
    - id: order_completed
      name: Order Completed
    - id: cart_viewed
      name: Cart Viewed</code></pre></div>
</div><div class="rs-code">
<div class="rs-code__head">
import-manifest.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: import-manifest
metadata:
  name: import-manifest
spec:
  workspaces:
    - workspace_id: &#34;ws-1&#34;
      resources:
        - urn: &#34;event:order_completed&#34;
          remote_id: &#34;remote_a&#34;</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-project-manifest-inline-conflict-all-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Same URN imported by both a manifest and inline metadata</h4><p class="vr-example__desc">The URN event:order_completed is declared in both the manifest and an inline metadata.import block — an ambiguous double import. The rule flags both locations; remove one.</p><div class="rs-code">
<div class="rs-code__head">
events.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: events
  import:
    workspaces:
      - workspace_id: &#34;ws-1&#34;
        resources:
          - urn: &#34;event:order_completed&#34;
            remote_id: &#34;remote_b&#34;
spec:
  events:
    - id: order_completed
      name: Order Completed</code></pre></div>
</div><div class="rs-code">
<div class="rs-code__head">
import-manifest.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: import-manifest
metadata:
  name: import-manifest
spec:
  workspaces:
    - workspace_id: &#34;ws-1&#34;
      resources:
        - urn: &#34;event:order_completed&#34;
          remote_id: &#34;remote_a&#34;</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
import-manifest.yaml
<code class="vr-diagnostics__ref">/spec/workspaces/0/resources/0/urn</code>
URN &#39;event:order_completed&#39; is defined in both an import-manifest and inline metadata
</li><li class="vr-diagnostics__item">
events.yaml
<code class="vr-diagnostics__ref">/metadata/import/workspaces/0/resources/0/urn</code>
URN &#39;event:order_completed&#39; is defined in both an import-manifest and inline metadata
</li></ul>
</div></div><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Manifest URN overlaps a legacy rudder/0.1 inline local_id import</h4><p class="vr-example__desc">The events spec uses the legacy rudder/0.1 format, whose inline imports reference resources by local_id &#43; remote_id. The local_id order_completed resolves to the URN event:order_completed — the same URN the manifest imports. Legacy specs are still subject to the conflict rule, so both locations are flagged; remove the inline metadata entry.</p><div class="rs-code">
<div class="rs-code__head">
events.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/0.1
kind: events
metadata:
  name: events
  import:
    workspaces:
      - workspace_id: &#34;ws-1&#34;
        resources:
          - local_id: order_completed
            remote_id: &#34;remote_b&#34;
spec:
  events:
    - id: order_completed
      name: Order Completed</code></pre></div>
</div><div class="rs-code">
<div class="rs-code__head">
import-manifest.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: import-manifest
metadata:
  name: import-manifest
spec:
  workspaces:
    - workspace_id: &#34;ws-1&#34;
      resources:
        - urn: &#34;event:order_completed&#34;
          remote_id: &#34;remote_a&#34;</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
import-manifest.yaml
<code class="vr-diagnostics__ref">/spec/workspaces/0/resources/0/urn</code>
URN &#39;event:order_completed&#39; is defined in both an import-manifest and inline metadata
</li><li class="vr-diagnostics__item">
events.yaml
<code class="vr-diagnostics__ref">/metadata/import/workspaces/0/resources/0/urn</code>
URN &#39;event:order_completed&#39; is defined in both an import-manifest and inline metadata
</li></ul>
</div></div></div>
</div></div></div>
<div class="vr-rule" id="vr-rule-1-project-metadata-syntax-valid-all" data-vr-rule data-phase="syntactic" data-spec-version="all" data-section="filtered-1" data-search="project/metadata-syntax-valid metadata syntax must be valid syntactic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">Metadata syntax must be valid</h4>
<div class="vr-rule__meta">
syntactic
errorAll spec versions</div>
<p class="vr-rule__id">Rule ID: <code>project/metadata-syntax-valid</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-project-metadata-syntax-valid-all-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-project-metadata-syntax-valid-all-valid">

✓
Valid (2 examples)

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-project-metadata-syntax-valid-all-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-project-metadata-syntax-valid-all-invalid">

✕
Invalid (2 examples)

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-project-metadata-syntax-valid-all">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-project-metadata-syntax-valid-all-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Metadata with only the required name</h4><p class="vr-example__desc">Minimal valid metadata: a name only.</p><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: my-events
spec:
  events: []</code></pre></div>
</div></div><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Metadata with a well-formed import block</h4><p class="vr-example__desc">An import block where each workspace declares workspace_id and each resource references a URN in the spec body.</p><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: my-events
  import:
    workspaces:
      - workspace_id: ws-123
        resources:
          - urn: &#34;event:order_completed&#34;
            remote_id: ev-remote-456
spec:
  events:
    - id: order_completed
      name: Order Completed</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-project-metadata-syntax-valid-all-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Metadata missing required name</h4><p class="vr-example__desc">Every spec metadata block must declare a name.</p><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  import:
    workspaces:
      - workspace_id: ws-123
spec:
  events: []</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
spec.yaml
<code class="vr-diagnostics__ref">/metadata/name</code>
&#39;name&#39; is required
</li></ul>
</div></div><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Import workspace missing required workspace_id</h4><p class="vr-example__desc">Each import workspace entry must declare a workspace_id.</p><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: my-events
  import:
    workspaces:
      - resources:
          - urn: &#34;event:order_completed&#34;
            remote_id: ev-remote-456
spec:
  events:
    - id: order_completed
      name: Order Completed</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
spec.yaml
<code class="vr-diagnostics__ref">/metadata/import/workspaces/0/workspace_id</code>
&#39;workspace_id&#39; is required
</li></ul>
</div></div></div>
</div></div></div>
</div>
</div>

## Event categories

You can define event categories in the YAML file by setting `kind` to `categories`.

The `spec` parameter of the YAML file has the following structure:

| Property | Type | Description |
| :----| :-----| :------|
| `categories` <br/> Required | Array of [category definitions](#category-definition) | An array of category definitions grouped together in the same file. |

### Category definition

All category definitions share the following properties:

| Property | Type | Description |
| :----| :-----| :------|
| `id` <br/> Required | String | Unique identifier for the category within the project. This parameter must be unique across all categories in all the YAML files within the project. |
| `name` <br/> Required | String | Display name of the category. |

### Example {#category-example}

```yaml
version: rudder/v1
kind: categories
metadata:
  name: event-categories
spec:
  categories:
    - id: signup_category
      name: Signup
    - id: login_category
      name: Login
    - id: browsing_category
      name: Browsing
    - id: miscellaneous_category
      name: Miscellaneous
```

### Category validation rules

<div class="vr-explorer vr-explorer--filtered" data-vr-explorer data-vr-instance="1">
<div class="vr-explorer__toolbar">
<div class="vr-explorer__toolbar-row">
<div class="vr-explorer__search-wrap">
<label class="vr-explorer__search-label" for="vr-rules-search-1">Search rules</label>
<input id="vr-rules-search-1" class="vr-explorer__search" type="search" placeholder="Search rules…" data-vr-search autocomplete="off">
</div>
<div class="vr-explorer__spec-wrap">
Spec version
<div class="vr-explorer__spec-toggle">
<button type="button" class="vr-explorer__spec-btn is-active" data-vr-spec="v1">v1</button>
<button type="button" class="vr-explorer__spec-btn" data-vr-spec="legacy">v0.1</button>
</div>
</div>
</div>
<div class="vr-explorer__toolbar-row vr-explorer__toolbar-row--filters">
<div class="vr-explorer__phase">
Filter by phase
<button type="button" class="vr-explorer__phase-btn is-active" data-vr-phase="all">All</button>
<button type="button" class="vr-explorer__phase-btn" data-vr-phase="syntactic">Syntactic</button>
<button type="button" class="vr-explorer__phase-btn" data-vr-phase="semantic">Semantic</button>
</div>
<p class="vr-explorer__count" data-vr-count data-vr-total="5">Showing <strong>5</strong> of 5 rules</p>
</div>
</div>
<div class="vr-explorer__rules"><div class="vr-rule" id="vr-rule-1-datacatalog-categories-semantic-valid-v1" data-vr-rule data-phase="semantic" data-spec-version="v1" data-section="filtered-1" data-search="datacatalog/categories/semantic-valid category names must be unique across the data catalog semantic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">Category names must be unique across the Data Catalog</h4>
<div class="vr-rule__meta">
semantic
error</div>
<p class="vr-rule__id">Rule ID: <code>datacatalog/categories/semantic-valid</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-datacatalog-categories-semantic-valid-v1-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-categories-semantic-valid-v1-valid">

✓
Valid

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-datacatalog-categories-semantic-valid-v1-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-categories-semantic-valid-v1-invalid">

✕
Invalid

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-datacatalog-categories-semantic-valid-v1">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-datacatalog-categories-semantic-valid-v1-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Unique category names (v1)</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: categories
metadata:
  name: my-categories
spec:
  categories:
    - id: user_actions
      name: User Actions
    - id: system_events
      name: System Events</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-datacatalog-categories-semantic-valid-v1-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Duplicate category names across files (v1)</h4><p class="vr-example__desc">Duplicate category names in the resource graph fail validation.</p><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: categories
metadata:
  name: my-categories
spec:
  categories:
    - id: user_actions_2
      name: User Actions</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
spec.yaml
<code class="vr-diagnostics__ref">/categories/0/name</code>
duplicate name &#39;User Actions&#39; within kind &#39;categories&#39;
</li></ul>
</div></div></div>
</div></div></div>
<div class="vr-rule" id="vr-rule-1-datacatalog-categories-semantic-valid-legacy" data-vr-rule data-phase="semantic" data-spec-version="legacy" data-section="filtered-1" data-search="datacatalog/categories/semantic-valid category names must be unique across the data catalog semantic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">Category names must be unique across the Data Catalog</h4>
<div class="vr-rule__meta">
semantic
error</div>
<p class="vr-rule__id">Rule ID: <code>datacatalog/categories/semantic-valid</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-datacatalog-categories-semantic-valid-legacy-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-categories-semantic-valid-legacy-valid">

✓
Valid

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-datacatalog-categories-semantic-valid-legacy-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-categories-semantic-valid-legacy-invalid">

✕
Invalid

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-datacatalog-categories-semantic-valid-legacy">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-datacatalog-categories-semantic-valid-legacy-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Unique category names (legacy)</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/0.1
kind: categories
metadata:
  name: my-categories
spec:
  categories:
    - id: user_actions
      name: User Actions
    - id: system_events
      name: System Events</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-datacatalog-categories-semantic-valid-legacy-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Duplicate category names across files (legacy)</h4><p class="vr-example__desc">Duplicate category names in the resource graph fail validation.</p><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/0.1
kind: categories
metadata:
  name: my-categories
spec:
  categories:
    - id: user_actions_2
      name: User Actions</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
spec.yaml
<code class="vr-diagnostics__ref">/categories/0/name</code>
duplicate name &#39;User Actions&#39; within kind &#39;categories&#39;
</li></ul>
</div></div></div>
</div></div></div>
<div class="vr-rule" id="vr-rule-1-datacatalog-categories-spec-syntax-valid-v1" data-vr-rule data-phase="syntactic" data-spec-version="v1" data-section="filtered-1" data-search="datacatalog/categories/spec-syntax-valid category spec syntax must be valid syntactic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">Category spec syntax must be valid</h4>
<div class="vr-rule__meta">
syntactic
error</div>
<p class="vr-rule__id">Rule ID: <code>datacatalog/categories/spec-syntax-valid</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-datacatalog-categories-spec-syntax-valid-v1-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-categories-spec-syntax-valid-v1-valid">

✓
Valid

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-datacatalog-categories-spec-syntax-valid-v1-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-categories-spec-syntax-valid-v1-invalid">

✕
Invalid

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-datacatalog-categories-spec-syntax-valid-v1">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-datacatalog-categories-spec-syntax-valid-v1-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Valid categories spec</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: categories
metadata:
  name: categories
spec:
  categories:
    - id: user_actions
      name: User Actions
    - id: system_events
      name: System Events</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-datacatalog-categories-spec-syntax-valid-v1-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Category missing required name field</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: categories
metadata:
  name: categories
spec:
  categories:
    - id: user_actions</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
spec.yaml
<code class="vr-diagnostics__ref">/spec/categories/0/name</code>
&#39;name&#39; is required
</li></ul>
</div></div></div>
</div></div></div>
<div class="vr-rule" id="vr-rule-1-datacatalog-categories-spec-syntax-valid-legacy" data-vr-rule data-phase="syntactic" data-spec-version="legacy" data-section="filtered-1" data-search="datacatalog/categories/spec-syntax-valid category spec syntax must be valid syntactic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">Category spec syntax must be valid</h4>
<div class="vr-rule__meta">
syntactic
error</div>
<p class="vr-rule__id">Rule ID: <code>datacatalog/categories/spec-syntax-valid</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-datacatalog-categories-spec-syntax-valid-legacy-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-categories-spec-syntax-valid-legacy-valid">

✓
Valid

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-datacatalog-categories-spec-syntax-valid-legacy-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-categories-spec-syntax-valid-legacy-invalid">

✕
Invalid

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-datacatalog-categories-spec-syntax-valid-legacy">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-datacatalog-categories-spec-syntax-valid-legacy-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Valid legacy categories spec</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/0.1
kind: categories
metadata:
  name: legacy-categories
spec:
  categories:
    - id: user_actions
      name: User Actions
    - id: system_events
      name: System Events</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-datacatalog-categories-spec-syntax-valid-legacy-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Legacy category missing required name field</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/0.1
kind: categories
metadata:
  name: legacy-categories
spec:
  categories:
    - id: user_actions</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
spec.yaml
<code class="vr-diagnostics__ref">/spec/categories/0/name</code>
&#39;name&#39; is required
</li></ul>
</div></div></div>
</div></div></div>
<div class="vr-rule" id="vr-rule-1-project-duplicate-urn-all" data-vr-rule data-phase="syntactic" data-spec-version="all" data-section="filtered-1" data-search="project/duplicate-urn urns must be unique across the project syntactic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">URNs must be unique across the project</h4>
<div class="vr-rule__meta">
syntactic
errorAll spec versions</div>
<p class="vr-rule__id">Rule ID: <code>project/duplicate-urn</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-project-duplicate-urn-all-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-project-duplicate-urn-all-valid">

✓
Valid

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-project-duplicate-urn-all-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-project-duplicate-urn-all-invalid">

✕
Invalid

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-project-duplicate-urn-all">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-project-duplicate-urn-all-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Distinct URNs across files</h4><p class="vr-example__desc">Each spec declares a different resource, so URNs do not collide.</p><div class="rs-code">
<div class="rs-code__head">
a.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: events-a
spec:
  events:
    - id: order_completed
      name: Order Completed</code></pre></div>
</div><div class="rs-code">
<div class="rs-code__head">
b.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: events-b
spec:
  events:
    - id: cart_viewed
      name: Cart Viewed</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-project-duplicate-urn-all-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Same URN declared in two files</h4><p class="vr-example__desc">Both files declare the same event ID, which resolves to one URN. The rule flags each occurrence.</p><div class="rs-code">
<div class="rs-code__head">
a.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: events-a
spec:
  events:
    - id: order_completed
      name: Order Completed</code></pre></div>
</div><div class="rs-code">
<div class="rs-code__head">
b.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: events-b
spec:
  events:
    - id: order_completed
      name: Order Completed (duplicate)</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
a.yaml
<code class="vr-diagnostics__ref">/spec/events/0/id</code>
duplicate URN &#39;event:order_completed&#39;
</li><li class="vr-diagnostics__item">
b.yaml
<code class="vr-diagnostics__ref">/spec/events/0/id</code>
duplicate URN &#39;event:order_completed&#39;
</li></ul>
</div></div></div>
</div></div></div>
<div class="vr-rule" id="vr-rule-1-project-manifest-inline-conflict-all" data-vr-rule data-phase="syntactic" data-spec-version="all" data-section="filtered-1" data-search="project/manifest-inline-conflict a (workspace_id, urn) must not be defined in both an import-manifest and inline metadata.import with differing remote_ids syntactic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">A (workspace_id, urn) must not be defined in both an import-manifest and inline metadata.import with differing remote_ids</h4>
<div class="vr-rule__meta">
syntactic
errorAll spec versions</div>
<p class="vr-rule__id">Rule ID: <code>project/manifest-inline-conflict</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-project-manifest-inline-conflict-all-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-project-manifest-inline-conflict-all-valid">

✓
Valid

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-project-manifest-inline-conflict-all-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-project-manifest-inline-conflict-all-invalid">

✕
Invalid (2 examples)

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-project-manifest-inline-conflict-all">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-project-manifest-inline-conflict-all-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Manifest and inline metadata import distinct resources</h4><p class="vr-example__desc">One resource is imported via the manifest, a different one via inline metadata. No URN appears in both, so the project is valid.</p><div class="rs-code">
<div class="rs-code__head">
events.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: events
  import:
    workspaces:
      - workspace_id: &#34;ws-1&#34;
        resources:
          - urn: &#34;event:cart_viewed&#34;
            remote_id: &#34;remote_b&#34;
spec:
  events:
    - id: order_completed
      name: Order Completed
    - id: cart_viewed
      name: Cart Viewed</code></pre></div>
</div><div class="rs-code">
<div class="rs-code__head">
import-manifest.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: import-manifest
metadata:
  name: import-manifest
spec:
  workspaces:
    - workspace_id: &#34;ws-1&#34;
      resources:
        - urn: &#34;event:order_completed&#34;
          remote_id: &#34;remote_a&#34;</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-project-manifest-inline-conflict-all-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Same URN imported by both a manifest and inline metadata</h4><p class="vr-example__desc">The URN event:order_completed is declared in both the manifest and an inline metadata.import block — an ambiguous double import. The rule flags both locations; remove one.</p><div class="rs-code">
<div class="rs-code__head">
events.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: events
  import:
    workspaces:
      - workspace_id: &#34;ws-1&#34;
        resources:
          - urn: &#34;event:order_completed&#34;
            remote_id: &#34;remote_b&#34;
spec:
  events:
    - id: order_completed
      name: Order Completed</code></pre></div>
</div><div class="rs-code">
<div class="rs-code__head">
import-manifest.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: import-manifest
metadata:
  name: import-manifest
spec:
  workspaces:
    - workspace_id: &#34;ws-1&#34;
      resources:
        - urn: &#34;event:order_completed&#34;
          remote_id: &#34;remote_a&#34;</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
import-manifest.yaml
<code class="vr-diagnostics__ref">/spec/workspaces/0/resources/0/urn</code>
URN &#39;event:order_completed&#39; is defined in both an import-manifest and inline metadata
</li><li class="vr-diagnostics__item">
events.yaml
<code class="vr-diagnostics__ref">/metadata/import/workspaces/0/resources/0/urn</code>
URN &#39;event:order_completed&#39; is defined in both an import-manifest and inline metadata
</li></ul>
</div></div><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Manifest URN overlaps a legacy rudder/0.1 inline local_id import</h4><p class="vr-example__desc">The events spec uses the legacy rudder/0.1 format, whose inline imports reference resources by local_id &#43; remote_id. The local_id order_completed resolves to the URN event:order_completed — the same URN the manifest imports. Legacy specs are still subject to the conflict rule, so both locations are flagged; remove the inline metadata entry.</p><div class="rs-code">
<div class="rs-code__head">
events.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/0.1
kind: events
metadata:
  name: events
  import:
    workspaces:
      - workspace_id: &#34;ws-1&#34;
        resources:
          - local_id: order_completed
            remote_id: &#34;remote_b&#34;
spec:
  events:
    - id: order_completed
      name: Order Completed</code></pre></div>
</div><div class="rs-code">
<div class="rs-code__head">
import-manifest.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: import-manifest
metadata:
  name: import-manifest
spec:
  workspaces:
    - workspace_id: &#34;ws-1&#34;
      resources:
        - urn: &#34;event:order_completed&#34;
          remote_id: &#34;remote_a&#34;</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
import-manifest.yaml
<code class="vr-diagnostics__ref">/spec/workspaces/0/resources/0/urn</code>
URN &#39;event:order_completed&#39; is defined in both an import-manifest and inline metadata
</li><li class="vr-diagnostics__item">
events.yaml
<code class="vr-diagnostics__ref">/metadata/import/workspaces/0/resources/0/urn</code>
URN &#39;event:order_completed&#39; is defined in both an import-manifest and inline metadata
</li></ul>
</div></div></div>
</div></div></div>
<div class="vr-rule" id="vr-rule-1-project-metadata-syntax-valid-all" data-vr-rule data-phase="syntactic" data-spec-version="all" data-section="filtered-1" data-search="project/metadata-syntax-valid metadata syntax must be valid syntactic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">Metadata syntax must be valid</h4>
<div class="vr-rule__meta">
syntactic
errorAll spec versions</div>
<p class="vr-rule__id">Rule ID: <code>project/metadata-syntax-valid</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-project-metadata-syntax-valid-all-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-project-metadata-syntax-valid-all-valid">

✓
Valid (2 examples)

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-project-metadata-syntax-valid-all-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-project-metadata-syntax-valid-all-invalid">

✕
Invalid (2 examples)

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-project-metadata-syntax-valid-all">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-project-metadata-syntax-valid-all-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Metadata with only the required name</h4><p class="vr-example__desc">Minimal valid metadata: a name only.</p><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: my-events
spec:
  events: []</code></pre></div>
</div></div><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Metadata with a well-formed import block</h4><p class="vr-example__desc">An import block where each workspace declares workspace_id and each resource references a URN in the spec body.</p><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: my-events
  import:
    workspaces:
      - workspace_id: ws-123
        resources:
          - urn: &#34;event:order_completed&#34;
            remote_id: ev-remote-456
spec:
  events:
    - id: order_completed
      name: Order Completed</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-project-metadata-syntax-valid-all-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Metadata missing required name</h4><p class="vr-example__desc">Every spec metadata block must declare a name.</p><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  import:
    workspaces:
      - workspace_id: ws-123
spec:
  events: []</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
spec.yaml
<code class="vr-diagnostics__ref">/metadata/name</code>
&#39;name&#39; is required
</li></ul>
</div></div><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Import workspace missing required workspace_id</h4><p class="vr-example__desc">Each import workspace entry must declare a workspace_id.</p><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: my-events
  import:
    workspaces:
      - resources:
          - urn: &#34;event:order_completed&#34;
            remote_id: ev-remote-456
spec:
  events:
    - id: order_completed
      name: Order Completed</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
spec.yaml
<code class="vr-diagnostics__ref">/metadata/import/workspaces/0/workspace_id</code>
&#39;workspace_id&#39; is required
</li></ul>
</div></div></div>
</div></div></div>
</div>
</div>

## Properties

You can define one or more properties in the YAML file by setting `kind` to `properties`.

The `spec` parameter of the YAML file has the following structure:

| Property | Type | Description |
| :----| :-----| :------|
| `properties` <br/> Required | Array of [property definitions](#property-definition) | An array of property definitions grouped together in the same file. |

### Property definition

A property definition has the following structure:

| Property | Type | Description |
| :----| :-----| :------|
| `id` <br/> Required | String | Unique identifier for the property within the project. This parameter must be unique across all properties in all the YAML files within the project. |
| `name` <br/> Required | String | This parameter corresponds to the field inside an event's `properties` or `traits` JSON. |
| `type` |  String | Set either `type` or `types` (not both). A single primitive type (`string`, `integer`, `number`, `object`, `array`, `boolean`, or `null`), or a URN reference to a custom type (`#custom-type:<id>`). |
| `types` | Array of strings | Set either `type` or `types` (not both). Use this when the property allows more than one primitive type. Each entry must be a primitive type name (not a custom type URN). |
| `item_type` | String | For `type: array`, set either `item_type` or `item_types` (not both). Describes a single type for each array element (primitive, or `#custom-type:<id>`). |
| `item_types` | Array of strings | For `type: array`, set either `item_type` or `item_types` (not both). Use when array elements can be one of several primitive types. |
| `description` |  String | Property description. |
| `config` | [`config`](#property-config) object | Additional validation rules for the property's values. Uses the same JSON Schema-style keywords as [`config` for custom types](#config-options), scoped to the property `type`. |

You must specify exactly one of `type` or `types`. For `type: array`, specify at most one of `item_type` or `item_types` to describe allowed element types.

#### Property config

| Property | Type | Description |
| :----| :-----| :------|
| `min_length` |  Integer | Minimum length of the property's string value. |
| `max_length` | Integer | Maximum length of the property's string value. |
| `pattern` |  String | Regular expression that the property's string values need to match with. |
| `enum` | Array of strings | List of all valid values for the property. |

Depending on the property `type`, you can use additional keywords in `config` with the same shapes as in [`config` options](#config-options) for custom types (for example `format`, `minimum`/`maximum`, or `min_items`/`max_items`).

### Example {#property-example}

```yaml
version: rudder/v1
kind: properties
metadata:
  name: ecommerce_properties
spec:
  properties:
    - id: product_id
      name: "product_id"
      type: string
      description: "Unique identifier for the product."
      config:
        min_length: 3
        max_length: 64
    - id: product_name
      name: "product_name"
      type: string
      description: "Name of the product."
      config:
        min_length: 2
        max_length: 255
    - id: product_price
      name: "product_price"
      type: number
      description: "Price of the product in the store's currency."
    - id: product_category
      name: "product_category"
      type: string
      description: "Category the product belongs to."
      config:
        enum:
        - "clothing"
        - "electronics"
        - "home_goods"
        - "beauty"
        - "accessories"
        max_length: 60
    - id: cart_items
      name: "cart_items"
      description: "Items present in the cart."
      type: array
      item_type: string
      config:
        min_items: 1
        unique_items: false
```

### Property validation rules

<div class="vr-explorer vr-explorer--filtered" data-vr-explorer data-vr-instance="1">
<div class="vr-explorer__toolbar">
<div class="vr-explorer__toolbar-row">
<div class="vr-explorer__search-wrap">
<label class="vr-explorer__search-label" for="vr-rules-search-1">Search rules</label>
<input id="vr-rules-search-1" class="vr-explorer__search" type="search" placeholder="Search rules…" data-vr-search autocomplete="off">
</div>
<div class="vr-explorer__spec-wrap">
Spec version
<div class="vr-explorer__spec-toggle">
<button type="button" class="vr-explorer__spec-btn is-active" data-vr-spec="v1">v1</button>
<button type="button" class="vr-explorer__spec-btn" data-vr-spec="legacy">v0.1</button>
</div>
</div>
</div>
<div class="vr-explorer__toolbar-row vr-explorer__toolbar-row--filters">
<div class="vr-explorer__phase">
Filter by phase
<button type="button" class="vr-explorer__phase-btn is-active" data-vr-phase="all">All</button>
<button type="button" class="vr-explorer__phase-btn" data-vr-phase="syntactic">Syntactic</button>
<button type="button" class="vr-explorer__phase-btn" data-vr-phase="semantic">Semantic</button>
</div>
<p class="vr-explorer__count" data-vr-count data-vr-total="6">Showing <strong>6</strong> of 6 rules</p>
</div>
</div>
<div class="vr-explorer__rules"><div class="vr-rule" id="vr-rule-1-datacatalog-properties-config-valid-v1" data-vr-rule data-phase="syntactic" data-spec-version="v1" data-section="filtered-1" data-search="datacatalog/properties/config-valid property config must be valid for the given type syntactic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">Property config must be valid for the given type</h4>
<div class="vr-rule__meta">
syntactic
error</div>
<p class="vr-rule__id">Rule ID: <code>datacatalog/properties/config-valid</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-datacatalog-properties-config-valid-v1-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-properties-config-valid-v1-valid">

✓
Valid

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-datacatalog-properties-config-valid-v1-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-properties-config-valid-v1-invalid">

✕
Invalid

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-datacatalog-properties-config-valid-v1">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-datacatalog-properties-config-valid-v1-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Valid string property config</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: properties
metadata:
  name: my-properties
spec:
  properties:
    - id: user_email
      name: User Email
      type: string
      config:
        format: &#34;email&#34;
        min_length: 5</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-datacatalog-properties-config-valid-v1-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">v1 string property config with invalid format</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: properties
metadata:
  name: my-properties
spec:
  properties:
    - id: user_email
      name: User Email
      type: string
      config:
        format: totally_wrong</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
spec.yaml
<code class="vr-diagnostics__ref">/properties/0/propConfig/format</code>
totally_wrong
</li></ul>
</div></div></div>
</div></div></div>
<div class="vr-rule" id="vr-rule-1-datacatalog-properties-config-valid-legacy" data-vr-rule data-phase="syntactic" data-spec-version="legacy" data-section="filtered-1" data-search="datacatalog/properties/config-valid property config must be valid for the given type syntactic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">Property config must be valid for the given type</h4>
<div class="vr-rule__meta">
syntactic
error</div>
<p class="vr-rule__id">Rule ID: <code>datacatalog/properties/config-valid</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-datacatalog-properties-config-valid-legacy-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-properties-config-valid-legacy-valid">

✓
Valid (2 examples)

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-datacatalog-properties-config-valid-legacy-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-properties-config-valid-legacy-invalid">

✕
Invalid

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-datacatalog-properties-config-valid-legacy">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-datacatalog-properties-config-valid-legacy-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Valid string property config with format (legacy)</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/0.1
kind: properties
metadata:
  name: my-properties
spec:
  properties:
    - id: user_email
      name: User Email
      type: string
      propConfig:
        format: &#34;email&#34;
        minLength: 5
        maxLength: 100</code></pre></div>
</div></div><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Valid integer property config with range (legacy)</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/0.1
kind: properties
metadata:
  name: my-properties
spec:
  properties:
    - id: age
      name: Age
      type: integer
      propConfig:
        minimum: 0
        maximum: 120</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-datacatalog-properties-config-valid-legacy-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">String property config with invalid format (legacy)</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/0.1
kind: properties
metadata:
  name: my-properties
spec:
  properties:
    - id: user_email
      name: User Email
      type: string
      propConfig:
        format: not_valid</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
spec.yaml
<code class="vr-diagnostics__ref">/properties/0/propConfig/format</code>
not_valid
</li></ul>
</div></div></div>
</div></div></div>
<div class="vr-rule" id="vr-rule-1-datacatalog-properties-semantic-valid-v1" data-vr-rule data-phase="semantic" data-spec-version="v1" data-section="filtered-1" data-search="datacatalog/properties/semantic-valid property references must resolve to existing resources semantic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">Property references must resolve to existing resources</h4>
<div class="vr-rule__meta">
semantic
error</div>
<p class="vr-rule__id">Rule ID: <code>datacatalog/properties/semantic-valid</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-datacatalog-properties-semantic-valid-v1-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-properties-semantic-valid-v1-valid">

✓
Valid

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-datacatalog-properties-semantic-valid-v1-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-properties-semantic-valid-v1-invalid">

✕
Invalid

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-datacatalog-properties-semantic-valid-v1">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-datacatalog-properties-semantic-valid-v1-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Unique property name and type combinations (v1)</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: properties
metadata:
  name: my-properties
spec:
  properties:
    - id: user_id
      name: User ID
      type: string
    - id: email
      name: Email
      type: string</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-datacatalog-properties-semantic-valid-v1-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Duplicate property name, type, and itemTypes across files (v1)</h4><p class="vr-example__desc">Duplicate property name, type, and itemTypes in the resource graph fail validation.</p><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: properties
metadata:
  name: my-properties
spec:
  properties:
    - id: user_id_2
      name: User ID
      type: string</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
spec.yaml
<code class="vr-diagnostics__ref">/properties/0</code>
duplicate name, type and itemTypes: &#39;User ID&#39; within kind &#39;properties&#39;
</li></ul>
</div></div></div>
</div></div></div>
<div class="vr-rule" id="vr-rule-1-datacatalog-properties-semantic-valid-legacy" data-vr-rule data-phase="semantic" data-spec-version="legacy" data-section="filtered-1" data-search="datacatalog/properties/semantic-valid property references must resolve to existing resources semantic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">Property references must resolve to existing resources</h4>
<div class="vr-rule__meta">
semantic
error</div>
<p class="vr-rule__id">Rule ID: <code>datacatalog/properties/semantic-valid</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-datacatalog-properties-semantic-valid-legacy-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-properties-semantic-valid-legacy-valid">

✓
Valid

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-datacatalog-properties-semantic-valid-legacy-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-properties-semantic-valid-legacy-invalid">

✕
Invalid

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-datacatalog-properties-semantic-valid-legacy">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-datacatalog-properties-semantic-valid-legacy-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Unique property name and type combinations (legacy)</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/0.1
kind: properties
metadata:
  name: my-properties
spec:
  properties:
    - id: user_id
      name: User ID
      type: string
    - id: email
      name: Email
      type: string</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-datacatalog-properties-semantic-valid-legacy-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Duplicate property name, type, and itemTypes across files (legacy)</h4><p class="vr-example__desc">Duplicate property name, type, and itemTypes in the resource graph fail validation.</p><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/0.1
kind: properties
metadata:
  name: my-properties
spec:
  properties:
    - id: user_id_2
      name: User ID
      type: string</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
spec.yaml
<code class="vr-diagnostics__ref">/properties/0</code>
duplicate name, type and itemTypes: &#39;User ID&#39; within kind &#39;properties&#39;
</li></ul>
</div></div></div>
</div></div></div>
<div class="vr-rule" id="vr-rule-1-datacatalog-properties-spec-syntax-valid-v1" data-vr-rule data-phase="syntactic" data-spec-version="v1" data-section="filtered-1" data-search="datacatalog/properties/spec-syntax-valid property spec syntax must be valid syntactic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">Property spec syntax must be valid</h4>
<div class="vr-rule__meta">
syntactic
error</div>
<p class="vr-rule__id">Rule ID: <code>datacatalog/properties/spec-syntax-valid</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-datacatalog-properties-spec-syntax-valid-v1-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-properties-spec-syntax-valid-v1-valid">

✓
Valid

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-datacatalog-properties-spec-syntax-valid-v1-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-properties-spec-syntax-valid-v1-invalid">

✕
Invalid

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-datacatalog-properties-spec-syntax-valid-v1">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-datacatalog-properties-spec-syntax-valid-v1-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Valid properties spec</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: properties
metadata:
  name: my-properties
spec:
  properties:
    - id: user_id
      name: User ID
      type: string
    - id: age
      name: Age
      type: integer</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-datacatalog-properties-spec-syntax-valid-v1-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">v1 property missing required id field</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: properties
metadata:
  name: my-properties
spec:
  properties:
    - name: User ID
      type: string</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
spec.yaml
<code class="vr-diagnostics__ref">/properties/0/id</code>
&#39;id&#39; is required
</li></ul>
</div></div></div>
</div></div></div>
<div class="vr-rule" id="vr-rule-1-datacatalog-properties-spec-syntax-valid-legacy" data-vr-rule data-phase="syntactic" data-spec-version="legacy" data-section="filtered-1" data-search="datacatalog/properties/spec-syntax-valid property spec syntax must be valid syntactic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">Property spec syntax must be valid</h4>
<div class="vr-rule__meta">
syntactic
error</div>
<p class="vr-rule__id">Rule ID: <code>datacatalog/properties/spec-syntax-valid</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-datacatalog-properties-spec-syntax-valid-legacy-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-properties-spec-syntax-valid-legacy-valid">

✓
Valid

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-datacatalog-properties-spec-syntax-valid-legacy-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-properties-spec-syntax-valid-legacy-invalid">

✕
Invalid (2 examples)

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-datacatalog-properties-spec-syntax-valid-legacy">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-datacatalog-properties-spec-syntax-valid-legacy-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Valid legacy properties spec</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/0.1
kind: properties
metadata:
  name: my-properties
spec:
  properties:
    - id: user_id
      name: User ID
      description: Unique identifier for the user
      type: string
    - id: email
      name: Email
      type: string</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-datacatalog-properties-spec-syntax-valid-legacy-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Legacy property missing required id field</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/0.1
kind: properties
metadata:
  name: my-properties
spec:
  properties:
    - name: User ID
      type: string</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
spec.yaml
<code class="vr-diagnostics__ref">/properties/0/id</code>
&#39;id&#39; is required
</li></ul>
</div></div><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Legacy property missing required name field</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/0.1
kind: properties
metadata:
  name: my-properties
spec:
  properties:
    - id: user_id
      type: string</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
spec.yaml
<code class="vr-diagnostics__ref">/properties/0/name</code>
&#39;name&#39; is required
</li></ul>
</div></div></div>
</div></div></div>
<div class="vr-rule" id="vr-rule-1-project-duplicate-urn-all" data-vr-rule data-phase="syntactic" data-spec-version="all" data-section="filtered-1" data-search="project/duplicate-urn urns must be unique across the project syntactic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">URNs must be unique across the project</h4>
<div class="vr-rule__meta">
syntactic
errorAll spec versions</div>
<p class="vr-rule__id">Rule ID: <code>project/duplicate-urn</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-project-duplicate-urn-all-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-project-duplicate-urn-all-valid">

✓
Valid

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-project-duplicate-urn-all-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-project-duplicate-urn-all-invalid">

✕
Invalid

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-project-duplicate-urn-all">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-project-duplicate-urn-all-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Distinct URNs across files</h4><p class="vr-example__desc">Each spec declares a different resource, so URNs do not collide.</p><div class="rs-code">
<div class="rs-code__head">
a.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: events-a
spec:
  events:
    - id: order_completed
      name: Order Completed</code></pre></div>
</div><div class="rs-code">
<div class="rs-code__head">
b.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: events-b
spec:
  events:
    - id: cart_viewed
      name: Cart Viewed</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-project-duplicate-urn-all-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Same URN declared in two files</h4><p class="vr-example__desc">Both files declare the same event ID, which resolves to one URN. The rule flags each occurrence.</p><div class="rs-code">
<div class="rs-code__head">
a.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: events-a
spec:
  events:
    - id: order_completed
      name: Order Completed</code></pre></div>
</div><div class="rs-code">
<div class="rs-code__head">
b.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: events-b
spec:
  events:
    - id: order_completed
      name: Order Completed (duplicate)</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
a.yaml
<code class="vr-diagnostics__ref">/spec/events/0/id</code>
duplicate URN &#39;event:order_completed&#39;
</li><li class="vr-diagnostics__item">
b.yaml
<code class="vr-diagnostics__ref">/spec/events/0/id</code>
duplicate URN &#39;event:order_completed&#39;
</li></ul>
</div></div></div>
</div></div></div>
<div class="vr-rule" id="vr-rule-1-project-manifest-inline-conflict-all" data-vr-rule data-phase="syntactic" data-spec-version="all" data-section="filtered-1" data-search="project/manifest-inline-conflict a (workspace_id, urn) must not be defined in both an import-manifest and inline metadata.import with differing remote_ids syntactic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">A (workspace_id, urn) must not be defined in both an import-manifest and inline metadata.import with differing remote_ids</h4>
<div class="vr-rule__meta">
syntactic
errorAll spec versions</div>
<p class="vr-rule__id">Rule ID: <code>project/manifest-inline-conflict</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-project-manifest-inline-conflict-all-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-project-manifest-inline-conflict-all-valid">

✓
Valid

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-project-manifest-inline-conflict-all-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-project-manifest-inline-conflict-all-invalid">

✕
Invalid (2 examples)

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-project-manifest-inline-conflict-all">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-project-manifest-inline-conflict-all-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Manifest and inline metadata import distinct resources</h4><p class="vr-example__desc">One resource is imported via the manifest, a different one via inline metadata. No URN appears in both, so the project is valid.</p><div class="rs-code">
<div class="rs-code__head">
events.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: events
  import:
    workspaces:
      - workspace_id: &#34;ws-1&#34;
        resources:
          - urn: &#34;event:cart_viewed&#34;
            remote_id: &#34;remote_b&#34;
spec:
  events:
    - id: order_completed
      name: Order Completed
    - id: cart_viewed
      name: Cart Viewed</code></pre></div>
</div><div class="rs-code">
<div class="rs-code__head">
import-manifest.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: import-manifest
metadata:
  name: import-manifest
spec:
  workspaces:
    - workspace_id: &#34;ws-1&#34;
      resources:
        - urn: &#34;event:order_completed&#34;
          remote_id: &#34;remote_a&#34;</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-project-manifest-inline-conflict-all-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Same URN imported by both a manifest and inline metadata</h4><p class="vr-example__desc">The URN event:order_completed is declared in both the manifest and an inline metadata.import block — an ambiguous double import. The rule flags both locations; remove one.</p><div class="rs-code">
<div class="rs-code__head">
events.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: events
  import:
    workspaces:
      - workspace_id: &#34;ws-1&#34;
        resources:
          - urn: &#34;event:order_completed&#34;
            remote_id: &#34;remote_b&#34;
spec:
  events:
    - id: order_completed
      name: Order Completed</code></pre></div>
</div><div class="rs-code">
<div class="rs-code__head">
import-manifest.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: import-manifest
metadata:
  name: import-manifest
spec:
  workspaces:
    - workspace_id: &#34;ws-1&#34;
      resources:
        - urn: &#34;event:order_completed&#34;
          remote_id: &#34;remote_a&#34;</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
import-manifest.yaml
<code class="vr-diagnostics__ref">/spec/workspaces/0/resources/0/urn</code>
URN &#39;event:order_completed&#39; is defined in both an import-manifest and inline metadata
</li><li class="vr-diagnostics__item">
events.yaml
<code class="vr-diagnostics__ref">/metadata/import/workspaces/0/resources/0/urn</code>
URN &#39;event:order_completed&#39; is defined in both an import-manifest and inline metadata
</li></ul>
</div></div><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Manifest URN overlaps a legacy rudder/0.1 inline local_id import</h4><p class="vr-example__desc">The events spec uses the legacy rudder/0.1 format, whose inline imports reference resources by local_id &#43; remote_id. The local_id order_completed resolves to the URN event:order_completed — the same URN the manifest imports. Legacy specs are still subject to the conflict rule, so both locations are flagged; remove the inline metadata entry.</p><div class="rs-code">
<div class="rs-code__head">
events.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/0.1
kind: events
metadata:
  name: events
  import:
    workspaces:
      - workspace_id: &#34;ws-1&#34;
        resources:
          - local_id: order_completed
            remote_id: &#34;remote_b&#34;
spec:
  events:
    - id: order_completed
      name: Order Completed</code></pre></div>
</div><div class="rs-code">
<div class="rs-code__head">
import-manifest.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: import-manifest
metadata:
  name: import-manifest
spec:
  workspaces:
    - workspace_id: &#34;ws-1&#34;
      resources:
        - urn: &#34;event:order_completed&#34;
          remote_id: &#34;remote_a&#34;</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
import-manifest.yaml
<code class="vr-diagnostics__ref">/spec/workspaces/0/resources/0/urn</code>
URN &#39;event:order_completed&#39; is defined in both an import-manifest and inline metadata
</li><li class="vr-diagnostics__item">
events.yaml
<code class="vr-diagnostics__ref">/metadata/import/workspaces/0/resources/0/urn</code>
URN &#39;event:order_completed&#39; is defined in both an import-manifest and inline metadata
</li></ul>
</div></div></div>
</div></div></div>
<div class="vr-rule" id="vr-rule-1-project-metadata-syntax-valid-all" data-vr-rule data-phase="syntactic" data-spec-version="all" data-section="filtered-1" data-search="project/metadata-syntax-valid metadata syntax must be valid syntactic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">Metadata syntax must be valid</h4>
<div class="vr-rule__meta">
syntactic
errorAll spec versions</div>
<p class="vr-rule__id">Rule ID: <code>project/metadata-syntax-valid</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-project-metadata-syntax-valid-all-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-project-metadata-syntax-valid-all-valid">

✓
Valid (2 examples)

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-project-metadata-syntax-valid-all-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-project-metadata-syntax-valid-all-invalid">

✕
Invalid (2 examples)

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-project-metadata-syntax-valid-all">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-project-metadata-syntax-valid-all-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Metadata with only the required name</h4><p class="vr-example__desc">Minimal valid metadata: a name only.</p><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: my-events
spec:
  events: []</code></pre></div>
</div></div><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Metadata with a well-formed import block</h4><p class="vr-example__desc">An import block where each workspace declares workspace_id and each resource references a URN in the spec body.</p><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: my-events
  import:
    workspaces:
      - workspace_id: ws-123
        resources:
          - urn: &#34;event:order_completed&#34;
            remote_id: ev-remote-456
spec:
  events:
    - id: order_completed
      name: Order Completed</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-project-metadata-syntax-valid-all-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Metadata missing required name</h4><p class="vr-example__desc">Every spec metadata block must declare a name.</p><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  import:
    workspaces:
      - workspace_id: ws-123
spec:
  events: []</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
spec.yaml
<code class="vr-diagnostics__ref">/metadata/name</code>
&#39;name&#39; is required
</li></ul>
</div></div><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Import workspace missing required workspace_id</h4><p class="vr-example__desc">Each import workspace entry must declare a workspace_id.</p><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: my-events
  import:
    workspaces:
      - resources:
          - urn: &#34;event:order_completed&#34;
            remote_id: ev-remote-456
spec:
  events:
    - id: order_completed
      name: Order Completed</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
spec.yaml
<code class="vr-diagnostics__ref">/metadata/import/workspaces/0/workspace_id</code>
&#39;workspace_id&#39; is required
</li></ul>
</div></div></div>
</div></div></div>
</div>
</div>

## Custom data types

You can define custom data types in the YAML file by setting `kind` to `custom-types`.

The `spec` parameter of the YAML file has the following structure:

| Property | Type | Description |
| :----| :-----| :------|
| `types` <br/> Required | Array of [custom type definitions](#custom-type-definition) | An array of custom type objects grouped together in the same file. |

### Custom type definition

| Property | Type | Description |
| :----| :-----| :------|
| `id` <br/> Required | String | Unique identifier for the custom type within the project. This parameter must be unique across all custom types in all the YAML files within the project. |
| `name` <br/> Required | String | Display name of the custom type. |
| `type` <br/> Required |  String | Base data type for the custom type. <br /><br /> Acceptable values are: `string`, `integer`, `number`, `object`, `array`, `boolean`. |
| `config` <br/> Required | [`config`](#config-options) object | Validation rules for the custom type. The configuration options vary depending on the `type` parameter. |
| `description` |  String | Description of the custom type. |

#### `config` options

The `config` object's configuration varies depending on the `type` parameter.

#### String

| Parameter | Description |
| --- | --- |
| `min_length` | Minimum string length |
| `max_length` | Maximum string length |
| `pattern` | Regular expression pattern |
| `format` | Predefined format like email, date, etc. |
| `enum` | Array of allowed values |
#### Number/Integer

| Parameter | Description |
| --- | --- |
| `minimum` | Minimum value |
| `maximum` | Maximum value |
| `exclusive_minimum` | Exclusive minimum value |
| `exclusive_maximum` | Exclusive maximum value |
| `multiple_of` | Multiple of value |
#### Array

| Parameter | Description |
| --- | --- |
| `item_types` | List of acceptable types for array items |
| `min_items` | Minimum number of items |
| `max_items` | Maximum number of items |
| `unique_items` | Boolean requiring uniqueness of items |

### Example {#custom-type-example}

```yaml
version: rudder/v1
kind: custom-types
metadata:
  name: email-types
spec:
  types:
    - id: emailtype
      name: "EmailType"
      description: "Custom type for email validation"
      type: string
      config:
        format: "email"
        min_length: 5
        max_length: 255
        pattern: "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
    - id: addresstype
      name: "AddressType"
      description: "Physical address information"
      type: object
      properties:
        - id: street
          type: string
          required: true
        - id: city
          type: string
          required: true
        - id: country
          type: string
          required: false
```

### Custom type validation rules

<div class="vr-explorer vr-explorer--filtered" data-vr-explorer data-vr-instance="1">
<div class="vr-explorer__toolbar">
<div class="vr-explorer__toolbar-row">
<div class="vr-explorer__search-wrap">
<label class="vr-explorer__search-label" for="vr-rules-search-1">Search rules</label>
<input id="vr-rules-search-1" class="vr-explorer__search" type="search" placeholder="Search rules…" data-vr-search autocomplete="off">
</div>
<div class="vr-explorer__spec-wrap">
Spec version
<div class="vr-explorer__spec-toggle">
<button type="button" class="vr-explorer__spec-btn is-active" data-vr-spec="v1">v1</button>
<button type="button" class="vr-explorer__spec-btn" data-vr-spec="legacy">v0.1</button>
</div>
</div>
</div>
<div class="vr-explorer__toolbar-row vr-explorer__toolbar-row--filters">
<div class="vr-explorer__phase">
Filter by phase
<button type="button" class="vr-explorer__phase-btn is-active" data-vr-phase="all">All</button>
<button type="button" class="vr-explorer__phase-btn" data-vr-phase="syntactic">Syntactic</button>
<button type="button" class="vr-explorer__phase-btn" data-vr-phase="semantic">Semantic</button>
</div>
<p class="vr-explorer__count" data-vr-count data-vr-total="6">Showing <strong>6</strong> of 6 rules</p>
</div>
</div>
<div class="vr-explorer__rules"><div class="vr-rule" id="vr-rule-1-datacatalog-custom-types-config-valid-v1" data-vr-rule data-phase="syntactic" data-spec-version="v1" data-section="filtered-1" data-search="datacatalog/custom-types/config-valid custom type config must be valid for the given type syntactic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">Custom type config must be valid for the given type</h4>
<div class="vr-rule__meta">
syntactic
error</div>
<p class="vr-rule__id">Rule ID: <code>datacatalog/custom-types/config-valid</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-datacatalog-custom-types-config-valid-v1-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-custom-types-config-valid-v1-valid">

✓
Valid

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-datacatalog-custom-types-config-valid-v1-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-custom-types-config-valid-v1-invalid">

✕
Invalid

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-datacatalog-custom-types-config-valid-v1">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-datacatalog-custom-types-config-valid-v1-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Valid string config with pattern</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: custom-types
metadata:
  name: my-custom-types
spec:
  types:
    - id: user_status
      name: UserStatus
      type: string
      config:
        enum: [&#34;active&#34;, &#34;inactive&#34;]</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-datacatalog-custom-types-config-valid-v1-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">v1 string config with invalid format</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: custom-types
metadata:
  name: my-custom-types
spec:
  types:
    - id: user_email
      name: UserEmail
      type: string
      config:
        format: not_a_valid_format</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
spec.yaml
<code class="vr-diagnostics__ref">/types/0/config/format</code>
not_a_valid_format
</li></ul>
</div></div></div>
</div></div></div>
<div class="vr-rule" id="vr-rule-1-datacatalog-custom-types-config-valid-legacy" data-vr-rule data-phase="syntactic" data-spec-version="legacy" data-section="filtered-1" data-search="datacatalog/custom-types/config-valid custom type config must be valid for the given type syntactic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">Custom type config must be valid for the given type</h4>
<div class="vr-rule__meta">
syntactic
error</div>
<p class="vr-rule__id">Rule ID: <code>datacatalog/custom-types/config-valid</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-datacatalog-custom-types-config-valid-legacy-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-custom-types-config-valid-legacy-valid">

✓
Valid (2 examples)

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-datacatalog-custom-types-config-valid-legacy-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-custom-types-config-valid-legacy-invalid">

✕
Invalid

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-datacatalog-custom-types-config-valid-legacy">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-datacatalog-custom-types-config-valid-legacy-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Valid string config with enum (legacy)</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/0.1
kind: custom-types
metadata:
  name: my-custom-types
spec:
  types:
    - id: user_status
      name: UserStatus
      type: string
      config:
        enum: [&#34;active&#34;, &#34;inactive&#34;]
        pattern: &#34;^[a-z]+$&#34;</code></pre></div>
</div></div><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Valid integer config with range (legacy)</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/0.1
kind: custom-types
metadata:
  name: my-custom-types
spec:
  types:
    - id: age
      name: Age
      type: integer
      config:
        minimum: 0
        maximum: 120</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-datacatalog-custom-types-config-valid-legacy-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">String config with invalid format (legacy)</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/0.1
kind: custom-types
metadata:
  name: my-custom-types
spec:
  types:
    - id: user_email
      name: UserEmail
      type: string
      config:
        format: invalid_format</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
spec.yaml
<code class="vr-diagnostics__ref">/types/0/config/format</code>
invalid_format
</li></ul>
</div></div></div>
</div></div></div>
<div class="vr-rule" id="vr-rule-1-datacatalog-custom-types-semantic-valid-v1" data-vr-rule data-phase="semantic" data-spec-version="v1" data-section="filtered-1" data-search="datacatalog/custom-types/semantic-valid custom type references must resolve to existing resources semantic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">Custom type references must resolve to existing resources</h4>
<div class="vr-rule__meta">
semantic
error</div>
<p class="vr-rule__id">Rule ID: <code>datacatalog/custom-types/semantic-valid</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-datacatalog-custom-types-semantic-valid-v1-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-custom-types-semantic-valid-v1-valid">

✓
Valid

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-datacatalog-custom-types-semantic-valid-v1-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-custom-types-semantic-valid-v1-invalid">

✕
Invalid

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-datacatalog-custom-types-semantic-valid-v1">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-datacatalog-custom-types-semantic-valid-v1-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Unique custom type names (v1)</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: custom-types
metadata:
  name: my-custom-types
spec:
  types:
    - id: address
      name: Address
      type: object
    - id: user_status
      name: UserStatus
      type: string</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-datacatalog-custom-types-semantic-valid-v1-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Duplicate custom type names across files (v1)</h4><p class="vr-example__desc">Duplicate custom type names in the resource graph fail validation.</p><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: custom-types
metadata:
  name: my-custom-types
spec:
  types:
    - id: address_v2
      name: Address
      type: object</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
spec.yaml
<code class="vr-diagnostics__ref">/types/0/name</code>
duplicate name &#39;Address&#39; within kind &#39;custom-types&#39;
</li></ul>
</div></div></div>
</div></div></div>
<div class="vr-rule" id="vr-rule-1-datacatalog-custom-types-semantic-valid-legacy" data-vr-rule data-phase="semantic" data-spec-version="legacy" data-section="filtered-1" data-search="datacatalog/custom-types/semantic-valid custom type references must resolve to existing resources semantic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">Custom type references must resolve to existing resources</h4>
<div class="vr-rule__meta">
semantic
error</div>
<p class="vr-rule__id">Rule ID: <code>datacatalog/custom-types/semantic-valid</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-datacatalog-custom-types-semantic-valid-legacy-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-custom-types-semantic-valid-legacy-valid">

✓
Valid

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-datacatalog-custom-types-semantic-valid-legacy-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-custom-types-semantic-valid-legacy-invalid">

✕
Invalid

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-datacatalog-custom-types-semantic-valid-legacy">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-datacatalog-custom-types-semantic-valid-legacy-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Unique custom type names (legacy)</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/0.1
kind: custom-types
metadata:
  name: my-custom-types
spec:
  types:
    - id: address
      name: Address
      type: object
    - id: user_status
      name: UserStatus
      type: string</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-datacatalog-custom-types-semantic-valid-legacy-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Duplicate custom type names across files (legacy)</h4><p class="vr-example__desc">Duplicate custom type names in the resource graph fail validation.</p><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/0.1
kind: custom-types
metadata:
  name: my-custom-types
spec:
  types:
    - id: address_v2
      name: Address
      type: object</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
spec.yaml
<code class="vr-diagnostics__ref">/types/0/name</code>
duplicate name &#39;Address&#39; within kind &#39;custom-types&#39;
</li></ul>
</div></div></div>
</div></div></div>
<div class="vr-rule" id="vr-rule-1-datacatalog-custom-types-spec-syntax-valid-v1" data-vr-rule data-phase="syntactic" data-spec-version="v1" data-section="filtered-1" data-search="datacatalog/custom-types/spec-syntax-valid custom type spec syntax must be valid syntactic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">Custom type spec syntax must be valid</h4>
<div class="vr-rule__meta">
syntactic
error</div>
<p class="vr-rule__id">Rule ID: <code>datacatalog/custom-types/spec-syntax-valid</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-datacatalog-custom-types-spec-syntax-valid-v1-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-custom-types-spec-syntax-valid-v1-valid">

✓
Valid

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-datacatalog-custom-types-spec-syntax-valid-v1-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-custom-types-spec-syntax-valid-v1-invalid">

✕
Invalid

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-datacatalog-custom-types-spec-syntax-valid-v1">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-datacatalog-custom-types-spec-syntax-valid-v1-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Valid custom-types spec</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: custom-types
metadata:
  name: my-custom-types
spec:
  types:
    - id: address
      name: Address
      type: object
    - id: user_status
      name: UserStatus
      type: string</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-datacatalog-custom-types-spec-syntax-valid-v1-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">v1 custom type missing required id field</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: custom-types
metadata:
  name: my-custom-types
spec:
  types:
    - name: UserStatus
      type: string</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
spec.yaml
<code class="vr-diagnostics__ref">/types/0/id</code>
&#39;id&#39; is required
</li></ul>
</div></div></div>
</div></div></div>
<div class="vr-rule" id="vr-rule-1-datacatalog-custom-types-spec-syntax-valid-legacy" data-vr-rule data-phase="syntactic" data-spec-version="legacy" data-section="filtered-1" data-search="datacatalog/custom-types/spec-syntax-valid custom type spec syntax must be valid syntactic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">Custom type spec syntax must be valid</h4>
<div class="vr-rule__meta">
syntactic
error</div>
<p class="vr-rule__id">Rule ID: <code>datacatalog/custom-types/spec-syntax-valid</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-datacatalog-custom-types-spec-syntax-valid-legacy-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-custom-types-spec-syntax-valid-legacy-valid">

✓
Valid

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-datacatalog-custom-types-spec-syntax-valid-legacy-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-custom-types-spec-syntax-valid-legacy-invalid">

✕
Invalid (2 examples)

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-datacatalog-custom-types-spec-syntax-valid-legacy">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-datacatalog-custom-types-spec-syntax-valid-legacy-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Valid legacy custom-types spec</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/0.1
kind: custom-types
metadata:
  name: my-custom-types
spec:
  types:
    - id: address
      name: Address
      description: Physical address structure
      type: object
    - id: user_status
      name: UserStatus
      type: string</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-datacatalog-custom-types-spec-syntax-valid-legacy-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Legacy custom type missing required name field</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/0.1
kind: custom-types
metadata:
  name: my-custom-types
spec:
  types:
    - id: user_status
      type: string</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
spec.yaml
<code class="vr-diagnostics__ref">/types/0/name</code>
&#39;name&#39; is required
</li></ul>
</div></div><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Legacy custom type missing required type field</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/0.1
kind: custom-types
metadata:
  name: my-custom-types
spec:
  types:
    - id: address
      name: Address</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
spec.yaml
<code class="vr-diagnostics__ref">/types/0/type</code>
&#39;type&#39; is required
</li></ul>
</div></div></div>
</div></div></div>
<div class="vr-rule" id="vr-rule-1-project-duplicate-urn-all" data-vr-rule data-phase="syntactic" data-spec-version="all" data-section="filtered-1" data-search="project/duplicate-urn urns must be unique across the project syntactic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">URNs must be unique across the project</h4>
<div class="vr-rule__meta">
syntactic
errorAll spec versions</div>
<p class="vr-rule__id">Rule ID: <code>project/duplicate-urn</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-project-duplicate-urn-all-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-project-duplicate-urn-all-valid">

✓
Valid

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-project-duplicate-urn-all-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-project-duplicate-urn-all-invalid">

✕
Invalid

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-project-duplicate-urn-all">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-project-duplicate-urn-all-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Distinct URNs across files</h4><p class="vr-example__desc">Each spec declares a different resource, so URNs do not collide.</p><div class="rs-code">
<div class="rs-code__head">
a.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: events-a
spec:
  events:
    - id: order_completed
      name: Order Completed</code></pre></div>
</div><div class="rs-code">
<div class="rs-code__head">
b.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: events-b
spec:
  events:
    - id: cart_viewed
      name: Cart Viewed</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-project-duplicate-urn-all-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Same URN declared in two files</h4><p class="vr-example__desc">Both files declare the same event ID, which resolves to one URN. The rule flags each occurrence.</p><div class="rs-code">
<div class="rs-code__head">
a.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: events-a
spec:
  events:
    - id: order_completed
      name: Order Completed</code></pre></div>
</div><div class="rs-code">
<div class="rs-code__head">
b.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: events-b
spec:
  events:
    - id: order_completed
      name: Order Completed (duplicate)</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
a.yaml
<code class="vr-diagnostics__ref">/spec/events/0/id</code>
duplicate URN &#39;event:order_completed&#39;
</li><li class="vr-diagnostics__item">
b.yaml
<code class="vr-diagnostics__ref">/spec/events/0/id</code>
duplicate URN &#39;event:order_completed&#39;
</li></ul>
</div></div></div>
</div></div></div>
<div class="vr-rule" id="vr-rule-1-project-manifest-inline-conflict-all" data-vr-rule data-phase="syntactic" data-spec-version="all" data-section="filtered-1" data-search="project/manifest-inline-conflict a (workspace_id, urn) must not be defined in both an import-manifest and inline metadata.import with differing remote_ids syntactic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">A (workspace_id, urn) must not be defined in both an import-manifest and inline metadata.import with differing remote_ids</h4>
<div class="vr-rule__meta">
syntactic
errorAll spec versions</div>
<p class="vr-rule__id">Rule ID: <code>project/manifest-inline-conflict</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-project-manifest-inline-conflict-all-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-project-manifest-inline-conflict-all-valid">

✓
Valid

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-project-manifest-inline-conflict-all-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-project-manifest-inline-conflict-all-invalid">

✕
Invalid (2 examples)

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-project-manifest-inline-conflict-all">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-project-manifest-inline-conflict-all-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Manifest and inline metadata import distinct resources</h4><p class="vr-example__desc">One resource is imported via the manifest, a different one via inline metadata. No URN appears in both, so the project is valid.</p><div class="rs-code">
<div class="rs-code__head">
events.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: events
  import:
    workspaces:
      - workspace_id: &#34;ws-1&#34;
        resources:
          - urn: &#34;event:cart_viewed&#34;
            remote_id: &#34;remote_b&#34;
spec:
  events:
    - id: order_completed
      name: Order Completed
    - id: cart_viewed
      name: Cart Viewed</code></pre></div>
</div><div class="rs-code">
<div class="rs-code__head">
import-manifest.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: import-manifest
metadata:
  name: import-manifest
spec:
  workspaces:
    - workspace_id: &#34;ws-1&#34;
      resources:
        - urn: &#34;event:order_completed&#34;
          remote_id: &#34;remote_a&#34;</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-project-manifest-inline-conflict-all-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Same URN imported by both a manifest and inline metadata</h4><p class="vr-example__desc">The URN event:order_completed is declared in both the manifest and an inline metadata.import block — an ambiguous double import. The rule flags both locations; remove one.</p><div class="rs-code">
<div class="rs-code__head">
events.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: events
  import:
    workspaces:
      - workspace_id: &#34;ws-1&#34;
        resources:
          - urn: &#34;event:order_completed&#34;
            remote_id: &#34;remote_b&#34;
spec:
  events:
    - id: order_completed
      name: Order Completed</code></pre></div>
</div><div class="rs-code">
<div class="rs-code__head">
import-manifest.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: import-manifest
metadata:
  name: import-manifest
spec:
  workspaces:
    - workspace_id: &#34;ws-1&#34;
      resources:
        - urn: &#34;event:order_completed&#34;
          remote_id: &#34;remote_a&#34;</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
import-manifest.yaml
<code class="vr-diagnostics__ref">/spec/workspaces/0/resources/0/urn</code>
URN &#39;event:order_completed&#39; is defined in both an import-manifest and inline metadata
</li><li class="vr-diagnostics__item">
events.yaml
<code class="vr-diagnostics__ref">/metadata/import/workspaces/0/resources/0/urn</code>
URN &#39;event:order_completed&#39; is defined in both an import-manifest and inline metadata
</li></ul>
</div></div><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Manifest URN overlaps a legacy rudder/0.1 inline local_id import</h4><p class="vr-example__desc">The events spec uses the legacy rudder/0.1 format, whose inline imports reference resources by local_id &#43; remote_id. The local_id order_completed resolves to the URN event:order_completed — the same URN the manifest imports. Legacy specs are still subject to the conflict rule, so both locations are flagged; remove the inline metadata entry.</p><div class="rs-code">
<div class="rs-code__head">
events.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/0.1
kind: events
metadata:
  name: events
  import:
    workspaces:
      - workspace_id: &#34;ws-1&#34;
        resources:
          - local_id: order_completed
            remote_id: &#34;remote_b&#34;
spec:
  events:
    - id: order_completed
      name: Order Completed</code></pre></div>
</div><div class="rs-code">
<div class="rs-code__head">
import-manifest.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: import-manifest
metadata:
  name: import-manifest
spec:
  workspaces:
    - workspace_id: &#34;ws-1&#34;
      resources:
        - urn: &#34;event:order_completed&#34;
          remote_id: &#34;remote_a&#34;</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
import-manifest.yaml
<code class="vr-diagnostics__ref">/spec/workspaces/0/resources/0/urn</code>
URN &#39;event:order_completed&#39; is defined in both an import-manifest and inline metadata
</li><li class="vr-diagnostics__item">
events.yaml
<code class="vr-diagnostics__ref">/metadata/import/workspaces/0/resources/0/urn</code>
URN &#39;event:order_completed&#39; is defined in both an import-manifest and inline metadata
</li></ul>
</div></div></div>
</div></div></div>
<div class="vr-rule" id="vr-rule-1-project-metadata-syntax-valid-all" data-vr-rule data-phase="syntactic" data-spec-version="all" data-section="filtered-1" data-search="project/metadata-syntax-valid metadata syntax must be valid syntactic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">Metadata syntax must be valid</h4>
<div class="vr-rule__meta">
syntactic
errorAll spec versions</div>
<p class="vr-rule__id">Rule ID: <code>project/metadata-syntax-valid</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-project-metadata-syntax-valid-all-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-project-metadata-syntax-valid-all-valid">

✓
Valid (2 examples)

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-project-metadata-syntax-valid-all-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-project-metadata-syntax-valid-all-invalid">

✕
Invalid (2 examples)

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-project-metadata-syntax-valid-all">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-project-metadata-syntax-valid-all-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Metadata with only the required name</h4><p class="vr-example__desc">Minimal valid metadata: a name only.</p><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: my-events
spec:
  events: []</code></pre></div>
</div></div><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Metadata with a well-formed import block</h4><p class="vr-example__desc">An import block where each workspace declares workspace_id and each resource references a URN in the spec body.</p><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: my-events
  import:
    workspaces:
      - workspace_id: ws-123
        resources:
          - urn: &#34;event:order_completed&#34;
            remote_id: ev-remote-456
spec:
  events:
    - id: order_completed
      name: Order Completed</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-project-metadata-syntax-valid-all-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Metadata missing required name</h4><p class="vr-example__desc">Every spec metadata block must declare a name.</p><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  import:
    workspaces:
      - workspace_id: ws-123
spec:
  events: []</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
spec.yaml
<code class="vr-diagnostics__ref">/metadata/name</code>
&#39;name&#39; is required
</li></ul>
</div></div><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Import workspace missing required workspace_id</h4><p class="vr-example__desc">Each import workspace entry must declare a workspace_id.</p><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: my-events
  import:
    workspaces:
      - resources:
          - urn: &#34;event:order_completed&#34;
            remote_id: ev-remote-456
spec:
  events:
    - id: order_completed
      name: Order Completed</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
spec.yaml
<code class="vr-diagnostics__ref">/metadata/import/workspaces/0/workspace_id</code>
&#39;workspace_id&#39; is required
</li></ul>
</div></div></div>
</div></div></div>
</div>
</div>

## Tracking Plans

You can define a Tracking Plan in the YAML file by setting `kind` to `tracking-plan`.

The `spec` parameter of the YAML file has the following structure:

| Property | Type | Description |
| :----| :-----| :------|
| `id` <br/> Required | String | Unique identifier for the Tracking Plan within the project. This parameter must be unique across all the Tracking Plans in the project. |
| `display_name` <br/> Required | String | A readable short name for the Tracking Plan. |
| `description` | String | Tracking plan description. |
| `rules` <br/> Required | Array of [rules definitions](#rule-definition) | Contains the list of events in the Tracking Plan along with the rules for their expected properties. |

### Rules definition

| Property | Type | Description |
| :----| :-----| :------|
| `type` <br/> Required | String | The rule type. The only acceptable value currently is `event_rule`.  |
| `id` <br/> Required | String | Rule ID. |
| `event` <br/> Required | String | URN reference to an existing event definition. See [Reference catalog resources](#reference-catalog-resources) for more information. |
| `additional_properties` | Boolean | Validation rule that checks if the event can have properties other than those defined in the rule's `properties` section. <br /><br />**Default value**: `false` |
| `identity_section` <br/> Required, for non-track events |  String | Defines in which field of the corresponding RudderStack event payload the rule's properties should be included. <br /><br />Acceptable values are: `properties`, `traits`, and `context.traits`. |
| `properties` <br/> Required | Array of [rule property definitions](#rule-property-definition) | List of properties associated with the rule's event along with the validation rules for the Tracking Plan. |

#### Rule property definition

| Property | Type | Description |
| :----| :-----| :------|
| `property` <br/> Required | String | URN reference to an existing property definition. <br /><br />See [Reference catalog resources](#reference-catalog-resources) for more information on how to work with references. |
| `required` | Boolean | Validation rule that determines whether the property should always be present in the RudderStack event. <br /><br />**Default value**: `false` |
| `properties` <br/> Applicable only for properties of `object` type | Array of [rule property definitions](#rule-property-definition) | Defines which [nested properties](https://www.rudderstack.com/docs/rudder-cli/data-catalog-and-tracking-plans/tracking-plans/create/#nested-properties) should be included when this property is used in the Tracking Plan. |

### Example {#tracking-plan-example}

```yaml
version: rudder/v1
kind: tracking-plan
metadata:
  name: ecommerce_tracking_plan
spec:
  id: ecommerce_tracking_plan
  display_name: "E-commerce Tracking Plan"
  description: "Tracking plan for an e-commerce application."
  rules:
    - type: event_rule
      id: product_viewed_rule
      event: "#event:product_viewed"
      additional_properties: false
      properties:
        - property: "#property:product_id"
          required: true
        - property: "#property:product_name"
          required: true
        - property: "#property:product_price"
          required: true
        - property: "#property:product_category"
          required: false
```

### Tracking Plan validation rules

<div class="vr-explorer vr-explorer--filtered" data-vr-explorer data-vr-instance="1">
<div class="vr-explorer__toolbar">
<div class="vr-explorer__toolbar-row">
<div class="vr-explorer__search-wrap">
<label class="vr-explorer__search-label" for="vr-rules-search-1">Search rules</label>
<input id="vr-rules-search-1" class="vr-explorer__search" type="search" placeholder="Search rules…" data-vr-search autocomplete="off">
</div>
<div class="vr-explorer__spec-wrap">
Spec version
<div class="vr-explorer__spec-toggle">
<button type="button" class="vr-explorer__spec-btn is-active" data-vr-spec="v1">v1</button>
<button type="button" class="vr-explorer__spec-btn" data-vr-spec="legacy">v0.1</button>
</div>
</div>
</div>
<div class="vr-explorer__toolbar-row vr-explorer__toolbar-row--filters">
<div class="vr-explorer__phase">
Filter by phase
<button type="button" class="vr-explorer__phase-btn is-active" data-vr-phase="all">All</button>
<button type="button" class="vr-explorer__phase-btn" data-vr-phase="syntactic">Syntactic</button>
<button type="button" class="vr-explorer__phase-btn" data-vr-phase="semantic">Semantic</button>
</div>
<p class="vr-explorer__count" data-vr-count data-vr-total="5">Showing <strong>5</strong> of 5 rules</p>
</div>
</div>
<div class="vr-explorer__rules"><div class="vr-rule" id="vr-rule-1-datacatalog-tracking-plans-semantic-valid-v1" data-vr-rule data-phase="semantic" data-spec-version="v1" data-section="filtered-1" data-search="datacatalog/tracking-plans/semantic-valid tracking plan references must resolve to existing resources semantic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">Tracking Plan references must resolve to existing resources</h4>
<div class="vr-rule__meta">
semantic
error</div>
<p class="vr-rule__id">Rule ID: <code>datacatalog/tracking-plans/semantic-valid</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-datacatalog-tracking-plans-semantic-valid-v1-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-tracking-plans-semantic-valid-v1-valid">

✓
Valid

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-datacatalog-tracking-plans-semantic-valid-v1-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-tracking-plans-semantic-valid-v1-invalid">

✕
Invalid

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-datacatalog-tracking-plans-semantic-valid-v1">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-datacatalog-tracking-plans-semantic-valid-v1-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Tracking Plan with unique display_name (v1)</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: tracking-plan
metadata:
  name: my-tracking-plan
spec:
  id: my_tp
  display_name: My Tracking Plan
  rules:
    - id: signup_rule
      type: event_rule
      event: &#34;#event:signup&#34;</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-datacatalog-tracking-plans-semantic-valid-v1-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Duplicate Tracking Plan display_name across files (v1)</h4><p class="vr-example__desc">Duplicate Tracking Plan display_name values in the resource graph fail validation.</p><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: tracking-plan
metadata:
  name: my-tracking-plan-2
spec:
  id: my_tp_2
  display_name: My Tracking Plan
  rules:
    - id: page_rule
      type: event_rule
      event: &#34;#event:page_view&#34;</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
spec.yaml
<code class="vr-diagnostics__ref">/display_name</code>
duplicate display_name &#39;My Tracking Plan&#39; within kind &#39;tracking-plan&#39;
</li></ul>
</div></div></div>
</div></div></div>
<div class="vr-rule" id="vr-rule-1-datacatalog-tracking-plans-semantic-valid-legacy" data-vr-rule data-phase="semantic" data-spec-version="legacy" data-section="filtered-1" data-search="datacatalog/tracking-plans/semantic-valid tracking plan references must resolve to existing resources semantic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">Tracking Plan references must resolve to existing resources</h4>
<div class="vr-rule__meta">
semantic
error</div>
<p class="vr-rule__id">Rule ID: <code>datacatalog/tracking-plans/semantic-valid</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-datacatalog-tracking-plans-semantic-valid-legacy-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-tracking-plans-semantic-valid-legacy-valid">

✓
Valid

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-datacatalog-tracking-plans-semantic-valid-legacy-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-tracking-plans-semantic-valid-legacy-invalid">

✕
Invalid

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-datacatalog-tracking-plans-semantic-valid-legacy">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-datacatalog-tracking-plans-semantic-valid-legacy-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Tracking Plan with unique display_name (legacy)</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/0.1
kind: tp
metadata:
  name: my-tracking-plan
spec:
  id: my_tp
  display_name: My Tracking Plan
  rules:
    - id: signup_rule
      type: event_rule
      event:
        $ref: &#34;#/events/user-events/signup&#34;</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-datacatalog-tracking-plans-semantic-valid-legacy-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Duplicate Tracking Plan display_name across files (legacy)</h4><p class="vr-example__desc">Duplicate Tracking Plan display_name values in the resource graph fail validation.</p><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/0.1
kind: tp
metadata:
  name: my-tracking-plan-2
spec:
  id: my_tp_2
  display_name: My Tracking Plan
  rules:
    - id: page_rule
      type: event_rule
      event:
        $ref: &#34;#/events/user-events/page_view&#34;</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
spec.yaml
<code class="vr-diagnostics__ref">/display_name</code>
duplicate display_name &#39;My Tracking Plan&#39; within kind &#39;tp&#39;
</li></ul>
</div></div></div>
</div></div></div>
<div class="vr-rule" id="vr-rule-1-datacatalog-tracking-plans-spec-syntax-valid-v1" data-vr-rule data-phase="syntactic" data-spec-version="v1" data-section="filtered-1" data-search="datacatalog/tracking-plans/spec-syntax-valid tracking plan spec syntax must be valid syntactic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">Tracking Plan spec syntax must be valid</h4>
<div class="vr-rule__meta">
syntactic
error</div>
<p class="vr-rule__id">Rule ID: <code>datacatalog/tracking-plans/spec-syntax-valid</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-datacatalog-tracking-plans-spec-syntax-valid-v1-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-tracking-plans-spec-syntax-valid-v1-valid">

✓
Valid

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-datacatalog-tracking-plans-spec-syntax-valid-v1-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-tracking-plans-spec-syntax-valid-v1-invalid">

✕
Invalid

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-datacatalog-tracking-plans-spec-syntax-valid-v1">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-datacatalog-tracking-plans-spec-syntax-valid-v1-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Valid Tracking Plan spec</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: tracking-plan
metadata:
  name: my-tracking-plan
spec:
  id: my_tp
  display_name: My Tracking Plan
  rules:
    - id: signup_rule
      type: event_rule
      event: &#34;#event:signup&#34;
      properties:
        - property: &#34;#property:user_id&#34;
          required: true</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-datacatalog-tracking-plans-spec-syntax-valid-v1-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Tracking Plan rule missing event field</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: tracking-plan
metadata:
  name: my-tracking-plan
spec:
  id: my_tp
  display_name: My Tracking Plan
  rules:
    - id: no_event_rule
      type: event_rule
      properties:
        - property: &#34;#property:user_id&#34;
          required: true</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
spec.yaml
<code class="vr-diagnostics__ref">/rules/0/event</code>
&#39;event&#39; is required
</li></ul>
</div></div></div>
</div></div></div>
<div class="vr-rule" id="vr-rule-1-datacatalog-tracking-plans-spec-syntax-valid-legacy" data-vr-rule data-phase="syntactic" data-spec-version="legacy" data-section="filtered-1" data-search="datacatalog/tracking-plans/spec-syntax-valid tracking plan spec syntax must be valid syntactic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">Tracking Plan spec syntax must be valid</h4>
<div class="vr-rule__meta">
syntactic
error</div>
<p class="vr-rule__id">Rule ID: <code>datacatalog/tracking-plans/spec-syntax-valid</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-datacatalog-tracking-plans-spec-syntax-valid-legacy-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-tracking-plans-spec-syntax-valid-legacy-valid">

✓
Valid

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-datacatalog-tracking-plans-spec-syntax-valid-legacy-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-datacatalog-tracking-plans-spec-syntax-valid-legacy-invalid">

✕
Invalid

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-datacatalog-tracking-plans-spec-syntax-valid-legacy">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-datacatalog-tracking-plans-spec-syntax-valid-legacy-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Valid legacy Tracking Plan spec</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/0.1
kind: tp
metadata:
  name: my-tracking-plan
spec:
  id: my_tp
  display_name: My Tracking Plan
  rules:
    - id: signup_rule
      type: event_rule
      event:
        $ref: &#34;#/events/user-events/signup&#34;
      properties:
        - $ref: &#34;#/properties/common/user_id&#34;
          required: true</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-datacatalog-tracking-plans-spec-syntax-valid-legacy-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Legacy Tracking Plan rule missing event field</h4><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/0.1
kind: tp
metadata:
  name: my-tracking-plan
spec:
  id: my_tp
  display_name: My Tracking Plan
  rules:
    - id: no_event_rule
      type: event_rule
      properties:
        - $ref: &#34;#/properties/common/user_id&#34;
          required: true</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
spec.yaml
<code class="vr-diagnostics__ref">/rules/0/event</code>
&#39;event&#39; is required
</li></ul>
</div></div></div>
</div></div></div>
<div class="vr-rule" id="vr-rule-1-project-duplicate-urn-all" data-vr-rule data-phase="syntactic" data-spec-version="all" data-section="filtered-1" data-search="project/duplicate-urn urns must be unique across the project syntactic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">URNs must be unique across the project</h4>
<div class="vr-rule__meta">
syntactic
errorAll spec versions</div>
<p class="vr-rule__id">Rule ID: <code>project/duplicate-urn</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-project-duplicate-urn-all-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-project-duplicate-urn-all-valid">

✓
Valid

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-project-duplicate-urn-all-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-project-duplicate-urn-all-invalid">

✕
Invalid

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-project-duplicate-urn-all">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-project-duplicate-urn-all-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Distinct URNs across files</h4><p class="vr-example__desc">Each spec declares a different resource, so URNs do not collide.</p><div class="rs-code">
<div class="rs-code__head">
a.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: events-a
spec:
  events:
    - id: order_completed
      name: Order Completed</code></pre></div>
</div><div class="rs-code">
<div class="rs-code__head">
b.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: events-b
spec:
  events:
    - id: cart_viewed
      name: Cart Viewed</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-project-duplicate-urn-all-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Same URN declared in two files</h4><p class="vr-example__desc">Both files declare the same event ID, which resolves to one URN. The rule flags each occurrence.</p><div class="rs-code">
<div class="rs-code__head">
a.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: events-a
spec:
  events:
    - id: order_completed
      name: Order Completed</code></pre></div>
</div><div class="rs-code">
<div class="rs-code__head">
b.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: events-b
spec:
  events:
    - id: order_completed
      name: Order Completed (duplicate)</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
a.yaml
<code class="vr-diagnostics__ref">/spec/events/0/id</code>
duplicate URN &#39;event:order_completed&#39;
</li><li class="vr-diagnostics__item">
b.yaml
<code class="vr-diagnostics__ref">/spec/events/0/id</code>
duplicate URN &#39;event:order_completed&#39;
</li></ul>
</div></div></div>
</div></div></div>
<div class="vr-rule" id="vr-rule-1-project-manifest-inline-conflict-all" data-vr-rule data-phase="syntactic" data-spec-version="all" data-section="filtered-1" data-search="project/manifest-inline-conflict a (workspace_id, urn) must not be defined in both an import-manifest and inline metadata.import with differing remote_ids syntactic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">A (workspace_id, urn) must not be defined in both an import-manifest and inline metadata.import with differing remote_ids</h4>
<div class="vr-rule__meta">
syntactic
errorAll spec versions</div>
<p class="vr-rule__id">Rule ID: <code>project/manifest-inline-conflict</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-project-manifest-inline-conflict-all-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-project-manifest-inline-conflict-all-valid">

✓
Valid

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-project-manifest-inline-conflict-all-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-project-manifest-inline-conflict-all-invalid">

✕
Invalid (2 examples)

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-project-manifest-inline-conflict-all">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-project-manifest-inline-conflict-all-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Manifest and inline metadata import distinct resources</h4><p class="vr-example__desc">One resource is imported via the manifest, a different one via inline metadata. No URN appears in both, so the project is valid.</p><div class="rs-code">
<div class="rs-code__head">
events.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: events
  import:
    workspaces:
      - workspace_id: &#34;ws-1&#34;
        resources:
          - urn: &#34;event:cart_viewed&#34;
            remote_id: &#34;remote_b&#34;
spec:
  events:
    - id: order_completed
      name: Order Completed
    - id: cart_viewed
      name: Cart Viewed</code></pre></div>
</div><div class="rs-code">
<div class="rs-code__head">
import-manifest.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: import-manifest
metadata:
  name: import-manifest
spec:
  workspaces:
    - workspace_id: &#34;ws-1&#34;
      resources:
        - urn: &#34;event:order_completed&#34;
          remote_id: &#34;remote_a&#34;</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-project-manifest-inline-conflict-all-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Same URN imported by both a manifest and inline metadata</h4><p class="vr-example__desc">The URN event:order_completed is declared in both the manifest and an inline metadata.import block — an ambiguous double import. The rule flags both locations; remove one.</p><div class="rs-code">
<div class="rs-code__head">
events.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: events
  import:
    workspaces:
      - workspace_id: &#34;ws-1&#34;
        resources:
          - urn: &#34;event:order_completed&#34;
            remote_id: &#34;remote_b&#34;
spec:
  events:
    - id: order_completed
      name: Order Completed</code></pre></div>
</div><div class="rs-code">
<div class="rs-code__head">
import-manifest.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: import-manifest
metadata:
  name: import-manifest
spec:
  workspaces:
    - workspace_id: &#34;ws-1&#34;
      resources:
        - urn: &#34;event:order_completed&#34;
          remote_id: &#34;remote_a&#34;</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
import-manifest.yaml
<code class="vr-diagnostics__ref">/spec/workspaces/0/resources/0/urn</code>
URN &#39;event:order_completed&#39; is defined in both an import-manifest and inline metadata
</li><li class="vr-diagnostics__item">
events.yaml
<code class="vr-diagnostics__ref">/metadata/import/workspaces/0/resources/0/urn</code>
URN &#39;event:order_completed&#39; is defined in both an import-manifest and inline metadata
</li></ul>
</div></div><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Manifest URN overlaps a legacy rudder/0.1 inline local_id import</h4><p class="vr-example__desc">The events spec uses the legacy rudder/0.1 format, whose inline imports reference resources by local_id &#43; remote_id. The local_id order_completed resolves to the URN event:order_completed — the same URN the manifest imports. Legacy specs are still subject to the conflict rule, so both locations are flagged; remove the inline metadata entry.</p><div class="rs-code">
<div class="rs-code__head">
events.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/0.1
kind: events
metadata:
  name: events
  import:
    workspaces:
      - workspace_id: &#34;ws-1&#34;
        resources:
          - local_id: order_completed
            remote_id: &#34;remote_b&#34;
spec:
  events:
    - id: order_completed
      name: Order Completed</code></pre></div>
</div><div class="rs-code">
<div class="rs-code__head">
import-manifest.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: import-manifest
metadata:
  name: import-manifest
spec:
  workspaces:
    - workspace_id: &#34;ws-1&#34;
      resources:
        - urn: &#34;event:order_completed&#34;
          remote_id: &#34;remote_a&#34;</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
import-manifest.yaml
<code class="vr-diagnostics__ref">/spec/workspaces/0/resources/0/urn</code>
URN &#39;event:order_completed&#39; is defined in both an import-manifest and inline metadata
</li><li class="vr-diagnostics__item">
events.yaml
<code class="vr-diagnostics__ref">/metadata/import/workspaces/0/resources/0/urn</code>
URN &#39;event:order_completed&#39; is defined in both an import-manifest and inline metadata
</li></ul>
</div></div></div>
</div></div></div>
<div class="vr-rule" id="vr-rule-1-project-metadata-syntax-valid-all" data-vr-rule data-phase="syntactic" data-spec-version="all" data-section="filtered-1" data-search="project/metadata-syntax-valid metadata syntax must be valid syntactic">
<div class="vr-rule__head">
<h4 class="vr-rule__title">Metadata syntax must be valid</h4>
<div class="vr-rule__meta">
syntactic
errorAll spec versions</div>
<p class="vr-rule__id">Rule ID: <code>project/metadata-syntax-valid</code></p>
</div><div class="vr-examples vr-examples--full-border">
<h4 class="vr-examples__heading">Examples</h4><nav>
<div class="nav nav-tabs vr-examples__tabs">
<a class="nav-item nav-link active vr-examples__tab vr-examples__tab--valid" id="nav-vr-tab-vr-rule-1-project-metadata-syntax-valid-all-valid" data-toggle="tab" href="#vr-tab-vr-rule-1-project-metadata-syntax-valid-all-valid">

✓
Valid (2 examples)

</a>
<a class="nav-item nav-link vr-examples__tab vr-examples__tab--invalid" id="nav-vr-tab-vr-rule-1-project-metadata-syntax-valid-all-invalid" data-toggle="tab" href="#vr-tab-vr-rule-1-project-metadata-syntax-valid-all-invalid">

✕
Invalid (2 examples)

</a>
</div>
</nav>
<div class="tab-content vr-examples__panels" id="nav-tab-content-vr-tab-vr-rule-1-project-metadata-syntax-valid-all">
<div class="tab-pane fade show active vr-examples__panel vr-examples__panel--valid" id="vr-tab-vr-rule-1-project-metadata-syntax-valid-all-valid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Metadata with only the required name</h4><p class="vr-example__desc">Minimal valid metadata: a name only.</p><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: my-events
spec:
  events: []</code></pre></div>
</div></div><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Metadata with a well-formed import block</h4><p class="vr-example__desc">An import block where each workspace declares workspace_id and each resource references a URN in the spec body.</p><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: my-events
  import:
    workspaces:
      - workspace_id: ws-123
        resources:
          - urn: &#34;event:order_completed&#34;
            remote_id: ev-remote-456
spec:
  events:
    - id: order_completed
      name: Order Completed</code></pre></div>
</div></div></div>
<div class="tab-pane fade vr-examples__panel vr-examples__panel--invalid" id="vr-tab-vr-rule-1-project-metadata-syntax-valid-all-invalid"><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Metadata missing required name</h4><p class="vr-example__desc">Every spec metadata block must declare a name.</p><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  import:
    workspaces:
      - workspace_id: ws-123
spec:
  events: []</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
spec.yaml
<code class="vr-diagnostics__ref">/metadata/name</code>
&#39;name&#39; is required
</li></ul>
</div></div><div class="vr-example__item">
<h4 class="vr-examples__heading vr-examples__heading--example">Import workspace missing required workspace_id</h4><p class="vr-example__desc">Each import workspace entry must declare a workspace_id.</p><div class="rs-code">
<div class="rs-code__head">
spec.yaml
yaml
<button class="rs-code__copy" type="button">

Copy
</button>
</div>
<div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">version: rudder/v1
kind: events
metadata:
  name: my-events
  import:
    workspaces:
      - resources:
          - urn: &#34;event:order_completed&#34;
            remote_id: ev-remote-456
spec:
  events:
    - id: order_completed
      name: Order Completed</code></pre></div>
</div><div class="vr-diagnostics">
<div class="vr-diagnostics__label">Diagnostics</div>
<ul class="vr-diagnostics__list"><li class="vr-diagnostics__item">
spec.yaml
<code class="vr-diagnostics__ref">/metadata/import/workspaces/0/workspace_id</code>
&#39;workspace_id&#39; is required
</li></ul>
</div></div></div>
</div></div></div>
</div>
</div>

## Reference Catalog resources

Definitions in a YAML file can refer to definitions in other files by using URN reference strings — this is useful while defining resources like Tracking Plans which need to be associated with events and properties defined in other files.

References use the format `#<type>:<id>`, where `type` is the resource kind and `id` is the unique resource identifier.

For example:

```yaml
# Reference to an event
event: "#event:example_id"

# Reference to a property
property: "#property:example_property_id"

# Reference to a custom type
type: "#custom-type:example_type_id"

# Reference to a category
category: "#category:example_category_id"

# Reference to a Tracking Plan (for example, from Event Stream source governance)
tracking_plan: "#tracking-plan:example_tracking_plan_id"
```

## Import metadata {#import-metadata}

When you import resources from a workspace using the [`import workspace`](https://www.rudderstack.com/docs/rudder-cli/import-resources/) command, the generated YAML files contain special import metadata that tells Rudder CLI how to link local resources to workspace resources.

### Structure

The import metadata is located in the `metadata.import` section of the YAML file:

```yaml
version: rudder/v1
kind: "categories"
metadata:
  import:
    workspaces:
      - workspace_id: "3NrueK2Hu7ooXVQqQJhKqKlnofE"
        resources:
          - local_id: "abc"
            remote_id: "cat_343HNkcWRt8YXHphthHwa8QEdXE"
          - local_id: "webapp"
            remote_id: "cat_2ohsVV9iKuw7GfLFITwsVLn6Nhy"
  name: "categories"
spec:
  categories:
    - id: "abc"
      name: "ABC"
    - id: "webapp"
      name: "Webapp"
```

### Properties

The `metadata.import` section contains the following properties:

| Property | Type | Description |
| :----| :-----| :------|
| `workspaces` <br/> Required | Array | Array of workspace import configurations. Each workspace configuration contains the workspace ID and resource mappings. |

#### Workspace configuration

Each workspace configuration in the `workspaces` array has the following structure:

| Property | Type | Description |
| :----| :-----| :------|
| `workspace_id` <br/> Required | String | The ID of the workspace where resources were imported from. |
| `resources` <br/> Required | Array | Array of mappings between local resource IDs and their corresponding workspace IDs. |

#### Resource mapping

Each resource mapping in the `resources` array has the following structure:

| Property | Type | Description |
| :----| :-----| :------|
| `local_id` <br/> Required | String | The local resource ID used within your CLI project. This corresponds to the `id` field in the resource definition. |
| `remote_id` <br/> Required | String | The remote resource ID from the workspace where the resource was imported from. |

**Info**

The import metadata serves two key purposes:

- **Resource linking**: Enables Rudder CLI to link local resource definitions to existing workspace resources when you run the [`apply`](https://www.rudderstack.com/docs/rudder-cli/import-resources/#apply-imported-resources) command.
- **Workspace-aware operations**: Tracks which workspace resources were imported from, allowing you to apply the same project to different workspaces. When you apply a project to a workspace different from the one specified in `workspace_id`, resources are treated as new resources to be created rather than imported.

See [Manage Workspaces](https://www.rudderstack.com/docs/rudder-cli/import-resources/manage-workspaces/) for more information about how to use import metadata in workspace management workflows.

