UTM templates
A UTM template is a named set of utm_* defaults attached to a
workspace or to a single campaign. Every link created in that scope
inherits the template’s variables; per-link overrides are allowed and
audit-logged. Template variables resolve at link creation, not at
click time, so what lands in your analytics tool is always what was
intended.
The flow is:
- Define a workspace template (your sane defaults).
- Optionally layer a campaign template on top (overrides + extras).
- Create links — Elido fills in the
utm_*query string before the short link is published. - Override per link when reality demands; the diff is captured in the audit log.
1. Define the workspace template
curl -X PUT \
https://api.elido.app/v1/workspaces/1/utm-template \
-H "Authorization: Bearer $ELIDO_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"utm_source": "{{ channel }}",
"utm_medium": "{{ medium }}",
"utm_campaign": "{{ campaign }}",
"utm_content": "{{ creative }}",
"utm_term": "{{ audience.segment }}"
}'A literal value ("utm_medium": "email") is fixed for every link.
A placeholder ({{ … }}) is filled in from the link create payload
or the bulk-import column with the matching name.
Unknown placeholders fail fast — the API returns 422 with the
unresolved variable name.
2. Layer a campaign template
Campaign templates inherit from the workspace template and can replace any subset of variables. Useful when one team’s campaigns follow a different naming convention than the rest of the org.
curl -X POST \
https://api.elido.app/v1/campaigns \
-H "Authorization: Bearer $ELIDO_TOKEN" \
-d '{
"name": "Spring 2026 — DACH",
"utm_template": {
"utm_campaign": "spring_2026_dach",
"utm_term": "{{ audience.locale }}"
}
}'Anything not set on the campaign falls through to the workspace defaults.
3. Variables
| Placeholder | Source | Notes |
|---|---|---|
{{ channel }} | channel field on POST /v1/links | Required when used |
{{ medium }} | medium field on POST /v1/links | — |
{{ campaign }} | campaign field, or campaign name | Falls back to campaign |
{{ creative }} | creative field, or CSV column creative | — |
{{ audience.segment }} | Klaviyo / Mailchimp segment id | Optional |
{{ audience.locale }} | Browser-style language tag, e.g. de-DE | — |
{{ link.tag.<name> }} | Per-link tag value | E.g. {{ link.tag.team }} |
Custom keys ({{ link.tag.* }}) read whatever you set on the link’s
tags array — convenient for multi-tenant agencies that need to
embed a client identifier in every URL.
4. Apply on bulk import
Templates apply automatically to bulk imports. The CSV column names must match the placeholder names (case-insensitive); columns Elido doesn’t recognise are dropped with a warning rather than silently copied.
destination_url,channel,medium,creative
https://shop.example.com/de,newsletter,email,hero_a
https://shop.example.com/fr,newsletter,email,hero_a
https://shop.example.com/de,paid_social,meta,carousel_v2POST it as multipart/form-data:
curl -X POST \
https://api.elido.app/v1/links/bulk \
-H "Authorization: Bearer $ELIDO_TOKEN" \
-F "csv=@launch_q2.csv" \
-F "campaign_id=cmp_8a2f"The endpoint validates every row before committing — a single bad row aborts the whole upload and returns the offending line numbers plus reason. No partial commits.
5. Per-link overrides
Any utm_* field on POST /v1/links overrides the resolved
template for that single link. The override is recorded with actor,
timestamp, and the resolved-vs-final diff in the audit log so you
can trace divergence weeks later.
curl -X POST \
https://api.elido.app/v1/links \
-H "Authorization: Bearer $ELIDO_TOKEN" \
-d '{
"destination_url": "https://shop.example.com/de/launch",
"campaign_id": "cmp_8a2f",
"utm_content": "hero_a_OVERRIDE_for_test"
}'In the dashboard, overridden fields render with a small ⤴ marker and the original template value in the tooltip.
6. Edge cases
- Existing
?utm_*in the destination URL — preserved. Elido never overwrites parameters you put in the destination yourself. The template only fills in the missing fields. - Repeating campaigns — clone a campaign and bump
utm_campaign’s suffix. Old links keep their original UTM, new links get the new value. - Migrations from other shorteners — the
bulkendpoint accepts pre-tagged URLs as-is; the template is only applied to columns the CSV doesn’t already supply.
See also
- Campaigns & A/B — group templates with variant rotation
- Conversion tracking — close the loop on the click → revenue join
- Conversion forwarding — server-side CAPI / GA4 / Mixpanel echo for the same UTMs