Create short links in GitHub Actions
, updated
Install the flared CLI in the job, give it an API token in FLARED_TOKEN, and run flared link create URL --json. The workflow
below makes a short link for each GitHub release, tags it with UTM parameters, and adds it to the release notes.
What you need
- A Flared account. Free works and includes the API and the CLI.
- An API token. In the dashboard, open Connections, API tokens, and create one with the
links:writescope. Adddomains:readif links go on your own domain. - The token as a repository secret named
FLARED_TOKEN, under Settings, Secrets and variables, Actions.
The workflow
Save this as .github/workflows/release-link.yml:
name: Release short link
on:
release:
types: [published]
permissions:
contents: write
jobs:
link:
runs-on: ubuntu-latest
steps:
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm install -g @flaredlink/cli
- name: Create the short link
id: link
env:
FLARED_TOKEN: ${{ secrets.FLARED_TOKEN }}
TAG: ${{ github.event.release.tag_name }}
URL: ${{ github.event.release.html_url }}
run: |
slug="release-$(echo "$TAG" | tr '[:upper:]' '[:lower:]' | tr -c 'a-z0-9\n' '-')"
short=$(flared link create "$URL" --slug "$slug" \
--idempotency-key "release-${{ github.event.release.id }}" \
--utm-source github --utm-medium release --utm-campaign "$slug" \
--json | jq -r '.link.shortUrl')
echo "url=$short" >> "$GITHUB_OUTPUT"
echo "Short link: $short" >> "$GITHUB_STEP_SUMMARY"
- name: Add it to the release notes
env:
GH_TOKEN: ${{ github.token }}
TAG: ${{ github.event.release.tag_name }}
run: |
notes=$(gh release view "$TAG" --repo "$GITHUB_REPOSITORY" --json body -q .body)
gh release edit "$TAG" --repo "$GITHUB_REPOSITORY" \
--notes "$notes"$'\n\n'"Share this release: ${{ steps.link.outputs.url }}" When you publish a release such as v2.4.0, the job:
- Installs the CLI (
npm install -g @flaredlink/cli), which needs Node.js 20 or later. - Makes a slug from the tag,
release-v2-4-0: Flared slugs use lowercase letters, digits, and hyphens. - Creates the link to the release page, with
utm_source=github,utm_medium=release, and the slug asutm_campaignon the destination. - Reads the short address from the JSON output, writes it to the job summary, and appends it to the release notes with the GitHub CLI.
Re-runs do not make a second link
A job that fails after the create step will run again, and a create that runs twice must not
fail on its own slug. The --idempotency-key option handles this: for 24 hours, a create
with the same key and the same input returns the link from the first run instead of a new one. The
key here is the release ID, which stays the same across re-runs.
After 24 hours, a second create with the same slug fails with SLUG_TAKEN and exit code
6. Flared keeps every slug reserved, even after you turn a link off, so an old short address never
points somewhere new.
Exit codes for your scripts
The CLI returns stable exit codes, so a step can react to the reason for a failure: 0 success,
3 not signed in, 4 not allowed, 6 rejected input such as a taken slug, 7 plan limit, 8 rate
limited, and 9 service unavailable. With --json, the error goes to standard error
as {"error": {"code", "message", "requestId"}}.
Use your own domain
Add --domain with a subdomain that you set up in Flared, such as go.example.com. The CLI checks that the domain is active before it creates the
link, which needs the domains:read scope on the token.
flared link create "$URL" --slug "$slug" --domain go.example.com --json See custom domains for the CNAME record. Free includes 5 custom domains.
Other ways to call Flared
- Without Node.js, call the REST API with
curl. Send anIdempotency-Keyheader; the API requires one on every create. - Read clicks from the same job with
flared analytics release-v2-4-0 --json. - For a self-hosted Flared, set
FLARED_API_URLto its API address, such ashttps://links.example.com/v1. - To ask for links in a chat instead, connect an AI assistant to the MCP server.