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

# Dependency rules

> Narrow one UTM parameter by the value of another, as in "when utm_source is google, utm_medium may only be cpc or display".

The [convention](/en/rules/the-convention) and the [approved values](/en/rules/approved-values)
judge each parameter on its own. A dependency rule judges a pair: **when** one parameter has a
particular value, **then** another parameter may only be one of a short list. `newsletter` as a
source only ever goes with `email` as a medium; `google` goes with `cpc` or `display`, never
`social`.

The rules live on the Rules page, [https://app.utmkit.co/rules](https://app.utmkit.co/rules), under "Dependency rules", each one
written as the sentence it means rather than the four columns it is stored as. Owners and admins
add and remove them; members and viewers can read them.

## Adding a rule

<Steps>
  <Step title="Choose Add a rule">
    The form has four parts: when this parameter, is this value, then this parameter, may only be.
    The last one is a list separated by commas.
  </Step>

  <Step title="Record the rule">
    The values must follow the convention's format, and the two parameters must differ. The page
    confirms with the sentence it recorded: "when utm\_source is google, utm\_medium may be cpc,
    display."
  </Step>
</Steps>

Recording a rule only ever adds. Recording `display` for a pair that already allows `cpc` widens
the list; it never withdraws what the pair already allowed. Recording a value that is already
there changes nothing.

## How a rule is applied

A rule wakes up when the driving value is present on a link **and is itself clean**: it passes
the format and, if its parameter has approved values, is one of them. Narrowing on a value that
is itself wrong would report the problem at the wrong end.

When a rule matches, its list **replaces** the general approved list for the target parameter.
Specific beats general: `cpc` need not be in `utm_medium`'s library to be allowed under
`utm_source=google`. The format still applies, because a rule narrows which values are legal, not
what a value may look like. If several rules match one link, every one of them must hold.
Matching does not depend on case.

## How a violation reads

A link with `utm_source=google` and `utm_medium=social` is refused in block mode, or created and
flagged in warn mode, with both ends of the pair in the sentence: *utm\_medium 'social' is not
allowed when utm\_source is 'google'. Under that rule, utm\_medium must be one of: 'cpc',
'display'.* The fix is either end, so both are named.

## Removing a rule

Each allowed value under a pair has a **Remove** control. A removal is one value under one
condition, never the whole set, so the page cannot remove more than you pointed at. Removing the
last value under a pair means that condition stops constraining the target parameter at all; the
confirmation says so. Links already created are untouched either way.

<Note>
  Retiring a value from the general library does not touch a rule that names it. See
  [Approved values](/en/rules/approved-values).
</Note>

## From the API and the MCP

`GET /api/v1/rules/dependencies` lists the rules, one row per allowed value under a driving pair;
`POST /api/v1/rules/dependencies` allows values for a target under a pair (additive); and
`DELETE /api/v1/rules/dependencies/{id}` removes one allowed value, not the whole set. Reads need
`rules:read`, writes `rules:write` plus an owner or admin behind the token. The MCP tools are
`list_dependency_rules`, `add_dependency_rule` and `remove_dependency_rule`, under the same
permissions.
