Skip to Content
Elido is in closed beta — APIs are stable but rate-limits and quotas may change before GA. Request access →
GuidesUTM templates

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:

  1. Define a workspace template (your sane defaults).
  2. Optionally layer a campaign template on top (overrides + extras).
  3. Create links — Elido fills in the utm_* query string before the short link is published.
  4. 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

PlaceholderSourceNotes
{{ channel }}channel field on POST /v1/linksRequired when used
{{ medium }}medium field on POST /v1/links
{{ campaign }}campaign field, or campaign nameFalls back to campaign
{{ creative }}creative field, or CSV column creative
{{ audience.segment }}Klaviyo / Mailchimp segment idOptional
{{ audience.locale }}Browser-style language tag, e.g. de-DE
{{ link.tag.<name> }}Per-link tag valueE.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_v2

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

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 bulk endpoint accepts pre-tagged URLs as-is; the template is only applied to columns the CSV doesn’t already supply.

See also