Skip to main content
View as Markdown

Link Actions

The link family creates a tracked short link while a workflow is running, and hands its address to the next step. A campaign link for a product that did not exist at deploy time cannot be declared in configuration; this is how one gets made. Three operators.

Operator Props Description
create slug, destination, title?, tags?, notes?, utm? Mint a link and return its address.
update slug, plus any of destination, title, tags, notes, utm Re-point or re-label an existing link. Omitted props are left unchanged.
delete slug Retire a link. Soft — the click history survives.
app.yaml
# Announce a product the moment it is created
- name: mint
  type: link
  operator: create
  props:
    slug: 'product-{{trigger.record.handle}}'
    destination: 'https://example.com/products/{{trigger.record.handle}}'
    title: '{{trigger.record.name}} — launch'
    utm: { source: newsletter, medium: email, campaign: launch }

# Send it
- name: announce
  type: email
  operator: send
  props:
    to: '{{trigger.record.owner_email}}'
    subject: 'Your link is live'
    body: '{{steps.mint.result.shortUrl}}'

The Address a Later Step Receives

create and update return four fields; delete returns slug and changed.

Field Value
slug The resolved slug, after templates.
destination Where the link now points.
shortUrl The absolute address, e.g. https://app.example.com/l/product-atlas.
qrUrl The absolute QR code, e.g. https://app.example.com/l/product-atlas.svg.

Templates Are Resolved First, Then Checked

Every string prop is a template. slug, destination, title, notes and each entry of tags and utm are interpolated against the trigger and earlier steps, and the resolved value is what gets validated.

That ordering is what makes the action safe to template freely. A slug is checked against the slug rules after {{trigger.record.handle}} has become atlas, so a record whose handle is Not A Slug! fails the step instead of storing an address nobody can reach. A destination is checked the same way: the resolved value must be a root-relative path or an absolute http(s) URL, so a javascript: or data: value arriving through a record field is refused rather than minted.

Two Slugs an Automation May Never Take

Both refusals fail the step with the reason named, so a failed run says which of the two happened.

Refusal Meaning
LINK_IS_CONFIG_DECLARED The slug is declared in links[]. Edit the configuration file.
LINK_SLUG_TAKEN A live link already holds it. Pick another slug.

The first is the important one. Configuration is the source of truth for the links it declares, and an automation that could mint over one would be config mutation through a data-shaped side door. update and delete refuse a config-declared slug for the same reason — they can only ever touch links created at runtime.

LINK_SLUG_TAKEN is a refusal, not an overwrite: minting the same slug twice keeps the first link. Re-pointing an address people have already shared, and re-attributing the clicks it has already earned, is not something a repeated trigger should do by accident. Use update when re-pointing is what you mean.

Add continueOnError: true to the step if a refused mint should not stop the workflow.

Delete Keeps the History

delete is soft. The link stops resolving and answers 404, and every click it already earned stays in analytics, reported under the same slug. A hard delete would destroy the campaign record along with the link.

Deleting twice is a success, not a failure — the second call reports changed: false, so a workflow that runs again does not break. A retired slug can be minted again later.

There is no rename. The slug is the address every share already carries and the key every click is recorded under, so changing it would break the shares and orphan the history in one move. Mint a new link instead.

  • Short Links — declaring links in configuration, and how they resolve.
  • Actions Overview — the action model and the base props every action accepts.
  • Analytics — where the clicks these links earn are reported.
  • Email & Notifications — the step that usually sends the minted address.

Last updated September 1, 2026

This documentation was written with AI, so errors or outdated content are possible. Sovrium is in beta. Contributions and corrections are welcome.

Built with Sovrium