Short links, and the story of every click
Put a link on your own domain, then see what happened after it: country, device, referrer, campaign. Kept for as long as the link exists.
Five links free, no card. Analytics on every plan.
- Analytics
- Full, every plan
- History
- Kept, any range
- Your domain
- Live in minutes
- Interfaces
- Web, REST, MCP
go.example.com/spring
LiveEvents
48,204
Clicks
41,867
QR scans
6,337
Visitors
29,512
Countries
- United States14,203
- Brazil9,841
- Germany6,120
- United Kingdom4,877
- Japan3,106
Referrers
- instagram.com12,408
- Direct9,932
- newsletter7,215
- x.com4,180
Browsers
- Chrome18,902
- Safari12,744
- Firefox4,318
- Edge2,903
Links on your domain
A CNAME and a certificate. Every link wears your name, and keeps working if you ever change providers.
How it worksAnalytics that do not expire
Country, region, city, device, browser, referrer and UTM, over any range. On every plan, free included.
See what is recordedAn API and an MCP server
Every action the screens do, reachable over REST, and an assistant that can drive it directly.
Built for developersHow it works
Three steps, and the third is the point
- 01
Point a domain at Lua
A CNAME, and a certificate that issues in minutes. A subdomain of a domain you already own works, so go.example.com costs nothing extra. Skip it and links work on the shared domain from the start.
- 02
Shorten and publish
Paste the destination, pick the back-half, tag it. Every link gets a QR code, and can carry an expiry date, a password, or separate iOS and Android destinations.
- 03
Read what happened
Every click becomes a row: country, region and city, device, browser and OS, referrer, and any UTM parameters. Filter by any of it, over any range.
Shorten
A link people will actually click
A short link hides its destination, so the domain is the only signal the reader gets. Yours says who is asking; a stranger's says nothing, and gets filtered as a category.
How that compares with BitlyDestination
https://example.com/collections/spring-2026?variant=42
Short link
go.example.com/spring
CopiedEvery link has a QR code
Scans are counted apart from clicks, so print and screen never end up in the same number.
What you get
The whole product, not a trial of it
Your domain, not ours
Point a domain at Lua and every link wears your name. It is configuration, not the tier you upgrade to.
Every click, kept
Country, region, city, device, browser, OS, referrer and UTM — over any date range, not a window that quietly drops last year.
QR codes that count
Every link has one, and scans are counted apart from clicks, so print and screen never share a number.
Expiry and passwords
Retire a link on a date, or put a password in front of it. Send people somewhere else on iOS and Android.
Tags and workspaces
Group links by campaign or client, and give a team its own workspace with its own domains.
An API that does everything
The REST API reaches every action the screen does, because both call the same code. Nothing is dashboard-only.
Built for agents
An MCP server ships with it, so an assistant can create a link, tag it and read its analytics with no scraping layer in between.
Run it yourself
Open source and self-hostable. If the record of who clicked what should never leave your infrastructure, it does not have to.
Build on it
Nothing is dashboard-only
The REST API reaches every action the screens do, because both call the same code underneath. An MCP server ships with it, so an assistant can do the same in words.
What developers getcurl -X POST https://lua.sh/api/links \
-H "Authorization: Bearer $LUA_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"domain": "go.example.com",
"key": "spring",
"url": "https://example.com/collections/spring-2026",
"utm_source": "newsletter",
"utm_medium": "email"
}'The difference
Rented links, or links you own
Most of what separates one shortener from another comes down to who holds the domain.
On somebody else's domain
- The domain belongs to somebody else, and so does the trust it carries
- Analytics stop at whatever window your tier pays for
- A branded domain is the upgrade, so the link a reader recognises costs extra
- If the service closes, every link you printed closes with it
- Generic shortener domains get filtered as a category, not judged one by one
On yours, with Lua
- The domain is yours, and the mapping is data you hold
- Every field, every date range, on every plan including free
- A domain is configuration, not a tier
- Change providers and every published link keeps resolving
- Your own domain carries your own reputation, which you can manage
It turns a long URL into a short one on a domain you control, then records what happens when someone opens it: which country, which device, which browser, which referrer, and any UTM parameters on the link. The short link is the mechanism. The record is the product.
No. Links work on the shared domain from the moment you sign up. A domain of your own is worth adding when you start publishing links somewhere permanent, because a branded link gets clicked more often and keeps working if you ever change providers.
No. Every field and every date range is on every plan, the free one included. Plans differ on five numbers only: links, click events a month, custom domains, tags and team members.
Because browsers increasingly send no referrer. A link opened inside an app, typed, pasted, or scanned from a QR code has no referring page at all, and most sites now send only their domain rather than the page. Direct is the absence of a source, not a source. Tag links with UTM parameters when the answer matters: those travel in the URL, where nothing strips them.
Yes. It is open source, and self-hosting is the only way to guarantee the click record never reaches anyone else's infrastructure. It runs on PostgreSQL or MySQL.
Make your first link in a minute
Sign up, paste a URL, and watch the clicks arrive. Bring a domain whenever you are ready.
