From Short.io
Short.io’s strength is per-domain configuration — links, pixels, and white-label all live under a domain. Elido moves those to the workspace level and lets you opt links into specific behaviours individually. EU residency, native SCIM, and a transparent click cap round out the trade.
Before you start
| Item | Where |
|---|---|
| Short.io API secret key | Short.io → Integrations & API |
| Per-domain CSV export | Short.io → Domain → Links → Export |
| List of pixels per domain | Short.io → Domain → Settings → Pixels |
| List of webhooks | Short.io → Domain → Settings → Webhooks |
| Elido workspace + PAT | app.elido.app → Settings → API Tokens |
Short.io’s export columns: OriginalURL, Path, Title, Tags,
CreatedAt. The Path field is the slug; everything else maps
directly.
Bulk import
// scripts/import-shortio.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("shortio-export.csv"), { columns: true });
const batches = [];
for (let i = 0; i < rows.length; i += 100) batches.push(rows.slice(i, i + 100));
for (const batch of batches) {
const links = batch.map((r) => ({
destination_url: r.OriginalURL,
slug: r.Path,
title: r.Title,
tags: r.Tags,
}));
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 }),
}
);
console.log(await res.json());
}Things that don’t have a 1:1 mapping:
- Password protection — Short.io’s per-link password gate has no equivalent yet. If you used it for geo / device routing, port the rules to smart links. Pure password gates: use a smart-link rule that points at an interstitial you host.
- Cloaked links / iframe wrap — Elido does not iframe-cloak destinations. The destination URL is what the user lands on.
- Expiration date — port to
targeting_ruleswith a time window and a fallbackdestination_url.
Custom domain cutover
Short.io routes via CNAME → cname.short.io; Elido routes via
CNAME → edge.elido.me. Run them in parallel:
# 1. Register the domain in Elido
POST /v1/workspaces/1/domains
{ "hostname": "go.example.com" }
# 2. Verification TXT (Short.io still serving)
_elido-verify.go.example.com. TXT "verify=<token>"
# 3. After verified, flip
go.example.com. CNAME edge.elido.me. # was cname.short.io.Wildcard subdomains are an Enterprise add-on at Short.io and a Business-tier feature at Elido. Register the wildcard:
curl -X POST \
https://api.elido.app/v1/workspaces/1/domains \
-H "Authorization: Bearer $ELIDO_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "hostname": "*.example.com", "is_wildcard": true }'The TXT record sits at the parent (_elido-verify.example.com) and
the CNAME is *.example.com → edge.elido.me..
API mapping
Short.io scopes most operations to a domain ID; Elido scopes to a workspace.
| Short.io | Elido |
|---|---|
POST /links | POST /v1/workspaces/{ws}/links |
GET /links/{id} | GET /v1/workspaces/{ws}/links/{id} |
POST /links/bulk | POST /v1/workspaces/{ws}/links/bulk |
GET /links_by_url?originalURL=... | GET /v1/workspaces/{ws}/links?destination_url=... |
GET /statistics/link/{id} | GET /v1/analytics/workspaces/{ws}/timeseries?link_id=... |
GET /domains | GET /v1/workspaces/{ws}/domains |
POST /domains | (via dashboard / domain-manager) |
Authorization: <secret-key> | Authorization: Bearer pat_... |
The biggest shape change: Short.io’s domain ID disappears. In
Elido, a link doesn’t belong to a domain — the workspace owns
domains, and any link in the workspace can serve from any verified
hostname.
Pixels and tracking
Short.io configures pixels per-domain; Elido configures them
per-workspace and turns the splash interstitial on per-link via
show_splash. Migrate:
curl -X PUT \
https://api.elido.app/v1/workspaces/1/pixels \
-H "Authorization: Bearer $ELIDO_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"meta_pixel_id": "1234567890",
"google_id": "AW-1234567890",
"tiktok_id": "C4ABCDEF...",
"linkedin_id": "1234567"
}'Then flip the splash on the links you want pixels to fire on:
curl -X PATCH \
https://api.elido.app/v1/workspaces/1/links/42 \
-H "Authorization: Bearer $ELIDO_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "show_splash": true }'Full reference: Retargeting pixels. For order-level conversion attribution from Stripe / Shopify, see Conversion tracking.
Pricing parity
| Tier | Short.io | Elido |
|---|---|---|
| Free | 1k clicks / 1 domain | 50 links / 5k clicks |
| Personal | $20/mo — 5k clicks | Pro €9/mo — 100k clicks |
| Team | $40/mo — 10k clicks, 3 domains | Business €29/mo — 1M clicks, 5 domains |
| Enterprise | Quote-based | Quote-based |
Short.io meters by clicks-per-domain; Elido meters per workspace across all domains. For multi-domain setups, the math usually works out cheaper on Elido at the same throughput.
After cutover
- Update SDK base URLs (
api.short.io→api.elido.app). - Re-issue webhook secrets — Short.io signs with
X-Sign, Elido withX-Webhook-Signature: v1=...(HMAC-SHA256 ofts.body). - Migrate Smart Targets — Short.io’s per-link country / device
rules become
targeting_ruleson the Elido link. The condition vocabulary is broader (timezone, day-of-week, language) — see Smart links. - Archive the Short.io account at the end of the billing cycle.