> ## 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.

# Create a link

> How a governed short link is created — destination, UTM parameters, short code, domain and campaign — and what the workspace's rules check before the link exists.

A UTMKit link is a short address that sends a visitor to a destination with the UTM parameters already applied. Before it exists, the workspace's rules look at every UTM value and a safety check looks at the destination. A link that fails either is never created.

## From the console

New links are created from the assistant. Say what you want in your own words — "shorten [https://example.com/spring](https://example.com/spring) with utm\_source newsletter and utm\_medium email, under the Spring campaign". When it refuses, it says why. Owners, admins and members can create links; viewers only see them. Every link then appears at [https://app.utmkit.co/links](https://app.utmkit.co/links), reading **Not live yet** until the edge confirms it, then **Live**.

### What a link is made of

* **A destination**, starting with `http://` or `https://`. For WhatsApp, give the phone number and the message and the address is composed for you. A link can also carry iOS and Android destinations — see [deep links](/en/links/deep-links).
* **UTM parameters**: `utm_source`, `utm_medium`, `utm_campaign`, `utm_term` and `utm_content`. The assistant sets only the ones you asked for and never invents a value.
* **A short code.** A generated code is exactly 7 characters. A code you choose must be 8 to 64 characters — letters, numbers, hyphens and underscores, starting with a letter or a number. The two lengths never overlap, so your code can never collide with a generated one. If it is already taken on that domain, the refusal suggests free alternatives.
* **A short domain**: the shared UTMKit domain, unless your organization has connected its own. With more than one choice, the assistant asks which to use rather than picking; say "shared" for the shared one. See [custom domains](/en/links/custom-domains).
* **A campaign.** Name an existing one and the link is grouped under it. Without a `utm_campaign` of your own, one is derived from the campaign's name, written as your convention wants; a `utm_campaign` you give always wins. See [campaigns](/en/campaigns).

### What the rules check

Before saving, the workspace's [convention](/en/rules/the-convention) is consulted: casing and separator, required parameters, [approved values](/en/rules/approved-values), [dependency rules](/en/rules/dependency-rules) and any parameter [locked](/en/rules/member-locks) for your seat. It also warns when Google Analytics 4 would file a medium under an unexpected channel.

A refusal is one plain sentence naming the parameter, the value and what to use instead: *utm\_source 'Newsletter' is not approved in this workspace. The approved values are: 'newsletter', 'partner'.* In **block** mode nothing is created until you fix it; in **warn** mode the link is created and carries the warning.

### The destination is checked first

A destination that is not a public address — a private network, a machine name — is refused. So is one listed as malware or phishing by a reputation authority, and the refusal says what it is listed as. A bad destination never becomes a link.

<Note>
  If the safety check cannot answer at that moment, the link is not created either. Try again in a few minutes — your address is not being called dangerous.
</Note>

### One tagged URL, one link

If the workspace already has a link with the same destination and the same five UTM values, the new one is refused and the refusal names the existing link: two codes for one tagged URL split its clicks. The domain does not matter, and a link with no UTM parameters at all is not subject to this rule.

Link creation is rate-limited per workspace to protect the safety check: 300 new links a day, the same on every plan. Past it, the refusal says when to try again.

## From the API and the MCP

`POST /api/v1/links` creates a link with exactly the same checks; `create_link` is the MCP tool that does the same. Both require a token carrying `links:write`; listing and reading links needs `links:read`. A duplicate is answered with a conflict, and a rule or safety refusal with the sentence the console would show. The reference owns the parameters.
