From Rebrandly
Rebrandly’s pitch is branded links per domain; Elido’s pitch is the same plus EU residency, transparent custom-domain pricing, and plain REST without the workspace-in-header workarounds. The migration is a CSV import plus a per-domain CNAME flip.
Before you start
| Item | Where |
|---|---|
| Rebrandly API key | Rebrandly → Account → API |
| Per-domain link export | Rebrandly → Domain → Links → Export CSV |
| List of custom domains | Rebrandly → Domains |
| List of teammates + roles | Rebrandly → Team |
| Elido workspace + PAT | app.elido.app → Settings → API Tokens |
Rebrandly’s export columns: slashtag, destination, domainName,
title, description, tags. The slashtag is the equivalent of
Elido’s slug — they import 1:1.
Bulk import
// scripts/import-rebrandly.mjs
import { readFileSync } from "node:fs";
import { parse } from "csv-parse/sync";
const WS = 1;
const TOKEN = process.env.ELIDO_TOKEN;
const rows = parse(readFileSync("rebrandly-export.csv"), { columns: true });
const chunks = [];
for (let i = 0; i < rows.length; i += 100) chunks.push(rows.slice(i, i + 100));
for (const chunk of chunks) {
const links = chunk.map((r) => ({
destination_url: r.destination,
slug: r.slashtag,
title: r.title,
description: r.description,
tags: r.tags, // comma-separated
}));
const res = await fetch(
`https://api.elido.app/v1/workspaces/${WS}/links/bulk`,
{
method: "POST",
headers: {
Authorization: `Bearer ${TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ links }),
}
);
const body = await res.json();
console.log(`batch ${chunk.length}: ${body.created} created, ${body.failed?.length ?? 0} failed`);
}Notes:
domainNameis dropped on import — Elido binds links to a workspace, not a hostname. After cutover (next section), the redirect host is whichever custom domain the workspace owns.- Slashtag → slug is exact. If a slashtag clashes with an
Elido-generated slug, the row fails with
slug_taken; rerun those withslugomitted.
Custom domain cutover
Rebrandly routes traffic via CNAME → rebrandlydata.com; Elido uses
CNAME → edge.elido.me. Run them in parallel until Elido is
verified.
# 1. Add domain in Elido
POST /v1/workspaces/1/domains
{ "hostname": "go.example.com" }
# 2. Verification TXT (Bitly is still serving)
_elido-verify.go.example.com. TXT "verify=<token>"
# 3. Flip when status = verified
go.example.com. CNAME edge.elido.me. # was rebrandlydata.com.
# 4. First request issues a Let's Encrypt cert via Caddy on-demand TLSWildcard subdomains are supported on Business — register
*.example.com and any sub-label resolves through the same cert.
API mapping
Rebrandly puts the API key in apikey header and the workspace ID in
workspace. Elido uses Bearer auth and puts the workspace in the URL
path.
| Rebrandly | Elido |
|---|---|
POST /v1/links | POST /v1/workspaces/{ws}/links |
GET /v1/links/{id} | GET /v1/workspaces/{ws}/links/{id} |
POST /v1/links/{id} (update) | PATCH /v1/workspaces/{ws}/links/{id} |
DELETE /v1/links/{id} | DELETE /v1/workspaces/{ws}/links/{id} |
GET /v1/links?orderBy=createdAt | GET /v1/workspaces/{ws}/links?sort=created_at |
GET /v1/links/{id}/clicks | GET /v1/analytics/workspaces/{ws}/timeseries?link_id=... |
GET /v1/domains | GET /v1/workspaces/{ws}/domains |
POST /v1/domains | (via dashboard / domain-manager) |
apikey: <key> | Authorization: Bearer pat_... |
The Rebrandly slashtag field maps to Elido’s slug. The
favourite flag has no equivalent — use tags: "favourite"
instead.
Workspaces and roles
Rebrandly has Manager / Member / Viewer; Elido has Owner / Admin / Editor / Viewer. Map them:
| Rebrandly | Elido |
|---|---|
| Manager | admin |
| Member | editor |
| Viewer | viewer |
| (account owner) | owner |
Re-invite via the API:
curl -X POST \
https://api.elido.app/v1/workspaces/1/invitations \
-H "Authorization: Bearer $ELIDO_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "email": "alice@example.com", "role": "editor" }'The invitee gets an email with a token — the same flow Elido uses for new sign-ups.
Pricing parity
| Tier | Rebrandly | Elido |
|---|---|---|
| Free | 500 links / 5k clicks (1-month retention) | 50 links / 5k clicks (90-day retention) |
| Starter | $29/mo — 5k clicks | Pro €9/mo — 100k clicks |
| Pro | $69/mo — 25k clicks | Business €29/mo — 1M clicks |
| Enterprise | Quote-based | Quote-based |
Rebrandly’s free tier is generous on link count but stingy on retention. Elido inverts that trade — fewer links free, but real analytics retention.
After cutover
- Update SDK base URLs in your backend (
api.rebrandly.com→api.elido.app). - Re-issue webhook secrets — Rebrandly’s webhooks are configured per-workspace; Elido’s per-endpoint. Decide whether one Elido endpoint is enough or you want one per integration.
- Archive the Rebrandly account at the end of the billing cycle. Keep the export CSV — it’s your only pre-cutover record.