Smart links
A smart link is a regular link with a targeting_rules array attached.
At redirect time the edge evaluates the rules in order and the first
match wins; if nothing matches, the request falls through to the
link’s variant rotation (if any) or its default destination_url.
Rules are evaluated at the edge POP, not at origin, so they cost nothing on top of a normal cache-hit redirect.
Anatomy of a rule
{
"destination_url": "https://example.com/default",
"targeting_rules": [
{
"label": "EU mobile in business hours",
"match": {
"countries": ["DE", "FR", "IT", "ES", "NL"],
"devices": ["mobile", "tablet"],
"languages": ["de", "fr", "it", "es", "nl"],
"time_start": "09:00",
"time_end": "18:00",
"timezone": "Europe/Berlin",
"days_of_week": [1, 2, 3, 4, 5]
},
"destination_url": "https://example.com/eu-mobile"
},
{
"label": "iOS users",
"match": { "os": ["ios"] },
"destination_url": "https://apps.apple.com/app/id123"
}
]
}Each rule has a match object, a destination_url, and an optional
label. All conditions in match must hold (AND); within a single
condition any value matches (OR). An empty field is a wildcard.
Match conditions
| Field | Values | Source |
|---|---|---|
countries | ISO-3166-1 alpha-2, e.g. ["US", "CA"] | CDN geoip header |
devices | mobile, tablet, desktop | User-Agent |
os | ios, android, macos, windows, linux | User-Agent |
browsers | chrome, safari, firefox, edge | User-Agent |
languages | ISO 639-1, e.g. ["en", "de"] | Accept-Language |
user_agent_regex | Go regex, ≤256 chars | User-Agent |
time_start / time_end | HH:MM, 24-hour, inclusive on both ends | edge clock |
timezone | IANA name (America/New_York) | configured per rule |
days_of_week | 0–6 where 0 = Sunday | edge clock |
A few notes:
- Time-window wrap. If
time_startis later thantime_end(22:00→02:00), the rule fires on either side of midnight. days_of_weekevaluates against the rule’stimezone, not UTC.- Multi-value vs. legacy single-value. The collection forms
(
countries,devices,os,browsers,languages) are AND-ed with the older singletons (country,device,browser) if both are set; prefer the collection forms.
Click cap
Independent of targeting, a link can have a hard ceiling on total clicks before it stops resolving:
{ "max_clicks": 10000 }When max_clicks > 0 the edge increments a Redis counter on every
click and 410-Gones the request once the cap is reached. Set to 0
or omit to disable.
Rotation mode
Links with variants[] (A/B testing) pick a variant per request. The
strategy is configurable:
rotation_mode | Behaviour |
|---|---|
weighted (default) | Random selection proportional to weight on each variant |
round_robin | Atomic Redis counter cycles variants[counter % N] |
Round-robin is the right pick for small samples where weighted selection’s variance is too noisy to read. If Redis is briefly unavailable, the edge transparently degrades to weighted random.
Update a link
curl -X PATCH \
https://api.elido.app/v1/workspaces/1/links/42 \
-H "Authorization: Bearer $ELIDO_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"targeting_rules": [
{ "match": { "os": ["ios"] }, "destination_url": "https://apps.apple.com/app/id123" },
{ "match": { "os": ["android"] }, "destination_url": "https://play.google.com/store/apps/details?id=com.x" }
]
}'The dashboard editor lives at Links → ⋯ → Targeting.