> For the complete documentation index, see [llms.txt](https://docs.mediarithmics.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.mediarithmics.io/setup-and-monitor/collect-and-manage-your-data/collect-data-in-real-time/event-rules.md).

# Event rules

Reshape incoming events per channel: extract properties from URLs, fill the origin, derive identifiers.

## Your goal

Fix or enrich incoming events without changing your website code - by declaring rules on the channel that run on every event as it arrives.

## Expected outcome

Events stored in the shape your schema expects, even when the source could not send them that way.

## What an event rule is

**Every time an event is sent, the platform runs the event rules associated with its channel.** They are **predefined actions** that extract properties, reshape data, or identify a user from a property.

Rules are configured per channel: open the channel's settings, edit it, and scroll to the event rules section. See [Channels](/setup-and-monitor/plan-and-integrate/set-up-the-environment/set-up-channels.md).

Event rules run at **step 2** of the [processing pipeline](/setup-and-monitor/collect-and-manage-your-data/collect-data-in-real-time.md#the-processing-pipeline) - before activity analyzers, and before storage.

{% hint style="success" %}
If what you need is not possible with an event rule, look at [activity analyzers](/setup-and-monitor/collect-and-manage-your-data/collect-data-in-real-time/activity-analyzers.md) instead: a rule is declarative and limited, an analyzer runs your own code.
{% endhint %}

## The available rules

### Property to origin copy

Takes an existing property from an event and copies it into the [origin](/setup-and-monitor/collect-and-manage-your-data/collect-data-in-real-time.md#activity-origin) of the activity. You can copy:

* the URL of the event,
* the referrer of the event,
* any event property.

Useful when your marketing attribution needs an origin field that the tag does not fill on its own.

### URL match

Matches a **pattern** against the `$url` of incoming `$page_view` events, extracts values from the URL path and query string, and generates a new event from a template.

{% hint style="warning" %}
**URL match only works for `$page_view` events.** Any other event is not processed by this rule.

And remember that `$page_view` events themselves are deleted at the end of activity processing - the point of this rule is to turn them into an event that survives.
{% endhint %}

**When to use it.** When for technical or organisational reasons you cannot customise the tracking snippet on a page to read the data layer. You keep the default snippet, which tracks `$page_view` with the page URL, and extract the properties from the URL instead.

The rule takes two parameters.

{% tabs %}
{% tab title="The URL pattern" %}
A URL in which you can add:

* a **variable extraction rule** for path parameters, written `:variableName`
* a **wildcard**, written `*`

```
*//foo.bar/category/:categoryId/article/:articleId
```

* `*` at the start matches both `http` and `https`.
* `:categoryId` and `:articleId` extract values from the path, and because they are named they can be used in the generated event.

Wildcards can appear several times: `https://foo.bar/*.*` matches a route shaped like `https://foo.bar/a/b/c.xls`.

**Query string values are extracted automatically** into variables named after the parameter: `https://foo.bar/a/b/c?var=value&var2=value2` gives you `var` and `var2`.
{% endtab %}

{% tab title="The event template" %}
The template holds:

* the `$event_name` of the generated event, as a static string,
* a list of properties as key-value pairs, added to the event's properties.

A property value can be a static string, or `{{variableName}}`, which is replaced by a value extracted from the URL pattern.

| Property            | Value            |
| ------------------- | ---------------- |
| `article_id`        | `{{articleId}}`  |
| `category_id`       | `{{categoryId}}` |
| `visit_origin`      | `{{origin}}`     |
| `source_event_rule` | `1`              |

{% hint style="info" %}
If a variable used in the template is not extracted from the URL - neither from the path nor from the query string - its value in the generated event is the literal `{{variableName}}`.
{% endhint %}
{% endtab %}
{% endtabs %}

<details>

<summary>Worked examples, with the pattern and template above</summary>

**`https://foo.bar/category/0001/article/super-awesome-article?origin=email`** generates:

```json
{
    "$ts": 1568296040000,
    "$event_name": "article_view",
    "$properties": {
        "category": "0001",
        "article_id": "super-awesome-article",
        "visit_origin": "email",
        "source_event_rule": "1"
    }
}
```

**`http://foo.bar/category/0001/article/super-awesome-article`** generates the same event, but `visit_origin` is the unresolved `{{origin}}` because there is no `origin` query parameter:

```json
{
    "$ts": 1568296040000,
    "$event_name": "article_view",
    "$properties": {
        "category": "0001",
        "article_id": "super-awesome-article",
        "visit_origin": "{{origin}}",
        "source_event_rule": "1"
    }
}
```

**`https://oof.bar/category/0001/article/super-awesome-article`** generates **nothing** - the domain does not match the pattern.

**An event named `page_view` rather than `$page_view`** generates **nothing** - the rule only applies to `$page_view`.

</details>

### User identifier insertion

Extracts a property from an event and converts it into a **user identifier**, such as an email hash or a user account ID. A hash can be applied during the extraction.

Supported hash methods: `SHA_256`, `SHA_1`, `SHA_384`, `SHA_512`, `MD5`, `MD2`.

```json
{
    "$event_name": "PageView",
    "$properties": {
        "user_id": "<USER_ID>"
    }
}
```

With this rule, `user_id` above can be extracted and stored as a user account ID.

Useful when you do not want to pass an identifier as a global property of the activity, and would rather have the datamart compute it.

{% hint style="info" %}
If several values of an identifier are found within one activity, **only the last one is kept**.
{% endhint %}

### Contextual targeting extractor

Used for contextual targeting. Its configuration is covered in the `Audience & Activation` section, under contextual targeting setup.

## Choosing between a rule and an analyzer

|               | Event rule                                  | Activity analyzer                                           |
| ------------- | ------------------------------------------- | ----------------------------------------------------------- |
| What it is    | A predefined, declarative action            | A plugin running your own code                              |
| Scope         | One event                                   | The whole activity                                          |
| Configuration | Channel settings                            | A plugin instance, attached to the channel                  |
| Use it when   | The transformation is one of the ones above | You need logic, an external lookup, or arbitrary enrichment |

## What rules do not fit

{% hint style="danger" %}
Anything that must reach storage **exactly as pushed** must not pass through an event rule. [Edge](/setup-and-monitor/plan-and-integrate/set-up-advanced-features/edge.md) requires properties to be stored exactly as the tag sent them - no event rules, no visit analyzers.
{% endhint %}

## Verify

* The `EVENT_RULES` step in ingestion monitoring shows the number of events matching your rules. A count of zero means the rule never matches. See [Monitor data ingestion](/setup-and-monitor/operate-and-monitor/monitor-data-ingestion.md).
* A real activity shows the generated event with resolved property values - no leftover `{{variable}}`.
* Identifiers created by a rule appear on the UserPoint.

## Related pages

<table data-view="cards" data-search="false"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Activity analyzers</strong></td><td>When a rule is not enough.</td><td><a href="/setup-and-monitor/collect-and-manage-your-data/collect-data-in-real-time/activity-analyzers.md">Activity analyzers</a></td></tr><tr><td><strong>Channels</strong></td><td>Where rules are configured.</td><td><a href="/setup-and-monitor/plan-and-integrate/set-up-the-environment/set-up-channels.md">Channels</a></td></tr><tr><td><strong>Standard events</strong></td><td>The event names a rule should produce.</td><td><a href="/setup-and-monitor/collect-and-manage-your-data/design-your-data-model-and-schema/standard-events.md">Standard events</a></td></tr></tbody></table>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.mediarithmics.io/setup-and-monitor/collect-and-manage-your-data/collect-data-in-real-time/event-rules.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
