Incy Links

User guide

Incy Links is a multi-tenant URL shortener. This guide covers every feature in the dashboard and the API. The little i icons scattered around the app open a short version of the relevant section right where you're working — click any of them to see.

Quick start — your first link in 60 seconds

  1. Sign up at incy.my/signup (or sign in if you've already got an account).
  2. Click New link in the top nav.
  3. Paste a long URL into Destination URL.
  4. Optional: pick a domain from the dropdown (the shared incy.my by default, or your own custom domain if you've added one).
  5. Click Create link. You get back a short URL with an auto-generated 6-character code.

Done. Your short URL is live. Copy it from the dashboard with the copy button and share. Click Stats on the link for clicks, top referrers, country breakdown, and a downloadable QR code.

What Incy Links is

A branded URL shortener built for teams. Use the shared incy.my pool out of the box, or bring your own domain (Pro+) for fully branded links. Shorten long URLs to short auto-generated codes (or your own custom slug), track clicks, generate QR codes, manage your team, and integrate via REST API (Enterprise tier). Common uses:

  • Branded, memorable links for LinkedIn, email signatures, sales decks, printed material
  • "Dynamic" links — change the destination after sharing, the short URL stays the same
  • Click tracking with referrer + country breakdowns (no third-party analytics)
  • QR codes that encode the short URL — re-point the destination and the same QR keeps working
  • Team workspace — invite users, share link ownership, audit who created what
  • API access so other tools (Zapier, scripts, your own apps) can mint links programmatically

Signing up & signing in

New here? Visit incy.my/signup. You'll need:

  • Your name, work email, and a password (min 10 characters)
  • An organisation name (e.g. "Acme Inc")

You're logged in automatically and land on your fresh dashboard with a 14-day free trial running.

Already have an account? Sign in at incy.my/login. Forgot your password? Ask an admin in your org to reset it from /admin/users, or if you are the admin and you've forgotten yours, contact support.

Trial & subscription

Every new org starts on a 14-day free trial of the Lite plan — no card required. The blue banner at the top of every page shows days remaining.

During the trial you can use everything in the Lite tier (1 user, 100 new links/month, shared incy.my namespace). To upgrade earlier (or just to set up billing before the trial ends), head to /admin/billing.

When the trial ends:

  • If you've subscribed: nothing visible changes. You're on the plan you picked.
  • If you haven't subscribed: the dashboard locks (you'll see a red banner). Existing short links keep redirecting — your customers see no disruption — but you can't create / edit until you subscribe. Just visit /admin/billing and pick a plan to unlock.

Plans & billing

Pick the plan that fits at /admin/billing. Compare on the pricing page.

Lite — $10/mo1 user, 100 new links/mo, shared incy.my namespace, 30-day click history.
Pro — $25/mo5 users, 500 new links/mo, 10 custom domains, 1-year click history, email support.
Enterprise — customUnlimited users / links / domains / clicks, SSO, REST API, white-label QR, priority support.

Annual plans save you 2 months — choose at checkout.

Self-service: click Manage billing in Stripe from /admin/billing to change cards, switch between monthly and annual, view invoices, or cancel. Cancellation takes effect at the end of your paid period — you keep access until then.

Usage: the same page shows X/Y bars for users, links/month, custom domains, and tracked clicks/month. The bar goes amber at 80% and red at 100%. When you hit a cap, the relevant "Create" button in the dashboard becomes a "🔒 Upgrade" link that takes you here.

Creating a shortlink

  1. Click New link in the top nav (or on the dashboard).
  2. Paste the long URL into Destination URL. Must start with http:// or https://.
  3. Optional: pick which domain to use (if your org has more than one).
  4. Optional: pick a custom slug (the bit after /), click 🎲 Suggest for a random one, or leave it blank to auto-generate on save.
  5. Optional: add a title so you can find the link later by searching.
  6. Optional: pick a folder and any tags.
  7. Optional: expand UTM parameters or Expiry & password protection.
  8. Click Create link.

Quick-add bookmarklet

For the fastest path — shorten the page you're currently looking at, without copy-pasting URLs — drag this button to your bookmark bar:

+ Incy this

  1. Show your bookmark bar if hidden: Cmd/Ctrl + Shift + B in Chrome, Edge, Firefox; View → Show Favourites Bar in Safari.
  2. Drag the purple "+ Incy this" button above up to your bookmark bar and drop it.
  3. On any web page, click + Incy this — a small window opens with the URL and page title pre-filled. Pick folder/tags/bio if you want, hit Save, done.

Uses your existing logged-in session — no API key needed, works on every plan. Doesn't work on browser internal pages like chrome://settings.

Custom slugs vs auto

Slugs are 1–63 characters, must start with a letter or digit, and can contain letters, digits, -, and _.

Reserved slugs. A small set of names collide with routes on the shared incy.my namespace — things like admin, api, login, help, pricing, blog, about, etc. You can't claim these on incy.my/{slug}, but you can claim them on your own custom domain — your domain doesn't serve those routes, so links.yourbrand.com/help just becomes a regular short link. Only health is reserved everywhere (it's a built-in uptime endpoint).

Profanity and slurs are blocked with common leet variations (so 5h1t doesn't slip through). If you hit the blocklist on an innocent word (the Scunthorpe problem), pick a different slug or hit 🎲 Suggest.

If you don't supply a slug, you'll get an auto-generated 6-character one like k7Qn2b — case-mixed, avoiding ambiguous characters (no 0/O, 1/l/I), and guaranteed to mix letters with digits so it can never accidentally spell a real word. Click 🎲 Suggest next to the slug field to preview one; click again to roll another.

Device-specific destinations

One short link can route to different destinations depending on the visitor's device — perfect for app-install links where you want iPhone visitors to land on the App Store, Android on Play, and desktop on a web page.

On the new-link form (and edit page), expand Device-specific destinations and fill in the iOS and/or Android URLs. Either is optional — leave blank to send those visitors to the main destination above.

VisitorLands at
iPhone / iPaddestination_ios if set, else main
Android phone / tabletdestination_android if set, else main
Desktop / anything elseMain destination

Stats roll up to the single short link regardless of which destination served the click — but you can see per-device breakdown on the link's Stats page.

Link-in-bio page

Each org can publish a public landing page at incy.my/@{org-slug} listing your selected links. Designed for the single URL slot on Instagram, TikTok, LinkedIn, etc. — visitors land on a clean mobile-first card with your headline and a tappable list of links.

  1. Admin: go to /admin/bio, tick Publish bio page, write a headline and (optional) intro, save.
  2. On any link's new/edit form, tick Feature on bio page. The link's title becomes the bio entry label, so write titles that read well publicly.
  3. Share the URL incy.my/@{your-slug} as your bio link.

Inactive, expired, or unfeatured links don't appear. Toggling the bio off makes the URL return 404 immediately — your links keep working as direct short URLs.

UTM parameters

Expand the UTM parameters section on the New link form to attach campaign tracking before shortening. Filled-in fields get appended to your destination URL as ?utm_source=…&utm_medium=… before the link is saved.

Common combos:

LinkedIn postsource=linkedin medium=social
Email signaturesource=email medium=signature
Newsletter blastsource=newsletter medium=email campaign=q2-launch
Sales deck QRsource=deck medium=qr campaign=acme-pitch

UTM presets

If you find yourself typing the same UTM combos over and over, save them at /admin/utm-presets. Each preset has a name plus any combination of the 5 UTM fields. On the new-link form, the Apply preset dropdown above the UTM inputs auto-fills them with one click — you can still tweak after applying.

Expiry & password protection

Expiry: set a date/time (UTC). After that moment, the short link shows a friendly "this one's past its bedtime" page instead of redirecting. Useful for time-boxed promos. Bump the date to revive.

Password: type a password. Visitors hitting the short link land on a gate page that asks for the password before redirecting. Stored as a bcrypt hash — nobody can read it out of the database, including admins.

When editing a password-protected link, leave the password field blank to keep the current one. Tick Remove password protection to clear it.

301 vs 302 redirects

When creating or editing a link, expand Redirect behaviour:

  • 302 Temporary (default) — the browser refetches every time, so changing the destination takes effect immediately. Use this for marketing links you might re-point later.
  • 301 Permanent — aggressively cached by browsers and treated as canonical by search engines. Use only when the short URL is the permanent address (e.g. an alias you'll never change). 301s show a 301 badge in the dashboard status column.

If you change a 301 link's destination, in-the-wild caches will keep going to the old place until they expire. Stick to 302 unless you have a reason.

Tags

Tags are flat labels you can multi-assign to links. Manage them at /admin/tags. Each tag has a colour for visual scanning on the dashboard.

  • Names are lowercased and stripped to a-z 0-9 - _. Spaces become hyphens.
  • From the new/edit form you can pick existing tags or type new ones in the "add new tags" box (comma-separated) — new ones are created on the fly.
  • Deleting a tag doesn't delete the links — they just lose that one tag.
  • Click any tag chip on the dashboard or in a link row to filter the dashboard by that tag.

The dashboard

The home view at /admin shows every team link. Controls at the top:

  • Search — matches slug, destination URL, or title (case-insensitive substring).
  • Tag filter — show only links with a specific tag.
  • All / Mine — toggle between all team links and only your own.

Status column:

  • active — live, redirecting
  • disabled — owner toggled "Active" off; returns 404
  • expired — past its expiry date; returns 410
  • 🔒 — password protected

The copy button next to each short URL puts it on your clipboard.

Bulk actions

On the dashboard, tick the checkbox in front of any link rows you want to act on. A blue action bar appears at the top with options:

  • Disable / Enable — toggle whether the link redirects or 404s
  • Add tag / Remove tag — pick a tag from the dropdown, applies to all selected
  • Delete — permanent, deletes the links and their click history

For non-admins, bulk actions only apply to links you own — others are silently skipped. Admins can act on anyone's links. The flash banner after the action shows how many were processed vs skipped.

Editing & ownership

Every link has an owner — the user who created it. You can see all team links and their stats, but only the owner (or an admin via bulk actions) can edit the destination, title, tags, expiry, password, or delete the link. Non-owners see a read-only view with the same info plus stats.

You can change the slug on the edit page if you really need to — but anyone who already has the old short URL will get a 404 once you save. Avoid it unless the link hasn't been shared anywhere.

Stats & QR codes

Click Stats on any link to see:

  • Total clicks
  • Daily clicks over the last 30 days (bar chart)
  • Top referrer hosts
  • Top countries (looked up from IP via ipapi.co, cached server-side)
  • A downloadable QR code, generated via the Stacksy QR API
  • The click trail — the last 100 raw clicks with timestamp, country, IP, referrer, and user agent

The QR encodes the short URL (not the destination) — change the destination later and the same QR keeps working.

Link previews (OG)

When you create a link, the system fetches the destination URL and pulls out its Open Graph metadata (og:title, og:description, og:image) so you have a snapshot of what's at the other end. It shows up:

  • Under the destination URL on the dashboard (just the title)
  • As a full card with image on the edit page

The fetch is best-effort with a 3-second timeout. If a site blocks bots or returns no OG tags, you'll just see no preview — everything else still works. On the edit page (owner only), Refresh preview re-fetches.

Bulk import / export

Import/admin/import. Upload a .csv file or paste CSV text. The first row must be a header. Recognised columns:

  • destination_url — required
  • slug — optional, auto-generated if blank
  • title — optional
  • tags — optional, semicolon-separated (e.g. launch;q2;linkedin). New tags are created on the fly.
  • expires_at — optional, format YYYY-MM-DD HH:MM:SS (UTC)
  • password — optional

Every imported link gets an auto-generated short slug. You'll get a report showing how many were created, how many skipped, and any per-line errors.

Export — click Export CSV on the dashboard for a download of every link visible to you (slug, short URL, destination, tags, click count, owner, etc.).

API access

For Zapier, scripts, internal tools.

Get a key: /admin/api-keys → name it (e.g. "Zapier") → click Generate. Copy the secret immediately — it's only shown once.

Base URL: https://incy.my/api/v1

Auth: Authorization: Bearer stk_xxxxxxxx…

Endpoints

GET /meWho am I (auth check)
GET /linksList all links (params: search, tag_id)
POST /linksCreate a link
GET /links/{id}Fetch one
PATCH /links/{id}Update (owner only)
DELETE /links/{id}Delete (owner only)
GET /links/{id}/statsClick stats payload
GET /tagsList tags
POST /tagsCreate a tag

Create link example

curl -X POST https://incy.my/api/v1/links \
  -H "Authorization: Bearer stk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "destination_url": "https://example.com/some/page",
    "title": "Spring launch",
    "tags": ["launch", "q2"],
    "utm": { "utm_source": "linkedin", "utm_medium": "social" },
    "expires_at": "2026-12-31 23:59:00"
  }'

Slugs are always auto-generated server-side. Read short_url from the response to know where the link lives.

Response (201):

{ "data": {
    "id": 42,
    "slug": "k7Qn2b",
    "short_url": "https://yourdomain.com/k7Qn2b",
    "destination_url": "https://example.com/some/page?utm_source=linkedin&utm_medium=social",
    "title": "Spring launch",
    "tags": [{"id": 3, "name": "launch"}, {"id": 4, "name": "q2"}],
    "owner": {"id": 1, "name": "Kristen Britz"},
    ...
} }

List links example

curl -H "Authorization: Bearer stk_YOUR_KEY" \
  "https://incy.my/api/v1/links?search=launch&tag_id=3"

Revoking keys

From the API keys page, hit Revoke on any active key. It stops working immediately. The page shows last-used timestamp and prefix so you can identify which integration each key belongs to.

Custom domains

You have two ways to get short links on a host you control:

1. The shared incy.my pool

Everyone on every plan can mint links at incy.my/{slug}. First-come-first-served slug pool. Brand-protected names (google, paypal, etc.) are blocked. Good for one-off links; not great when you want consistent branding.

2. Your own custom domain (Pro and above)

Bring go.yourcompany.com or similar. Admins add it at /admin/domains. We give you DNS instructions; you point an A record at us; we auto-issue Let's Encrypt SSL. Once live, anyone in the org can create links on it.

Adding a domain — the easy path

  1. Click Add domain, type the hostname.
  2. Add an A record at your DNS provider pointing the hostname to 2.24.83.238.
  3. Walk away. A background job checks every 5 minutes; as soon as DNS resolves to us, it auto-issues the cert and flips the domain to active. Typical end-to-end time: 5–10 minutes after you set the DNS record.

Adding a domain — the manual path

If you don't want to wait for the next cron tick (or if auto-issue isn't running for some reason):

  1. After the DNS record is set, click Check DNS on the domain detail page — green tick means our resolver sees it pointing at us.
  2. Click Issue / renew SSL. Takes 5–10 seconds. Domain flips to active immediately.

The manual buttons are also useful when something goes wrong — the issuance output is shown in full on the detail page (and tee'd to storage/logs/cert.log on the server).

What this gives you

  • Branded short URLs — go.example.com/launch instead of stksy.me/launch
  • Per-domain slug namespaces — the same slug can exist on multiple domains independently
  • Per-domain stats — each link's stats are scoped to that link, no cross-domain bleed
  • QR codes generated against the custom host (not stksy.me)

Disabling / deleting

Disable a domain to instantly make all its links return 404 — useful if a customer offboards or a domain expires. Re-enable any time.

Delete is only allowed if zero links exist on the domain. The cert keeps the domain in its SAN list until next renewal; harmless but a small footprint cleanup we can do later.

Cloudflare-fronted setup (advanced)

If your customer wants their domain behind Cloudflare (e.g. they already use CF for their main site and want consistency):

  1. In Cloudflare DNS, add an A record for the hostname pointing at 2.24.83.238. Leave the orange proxy cloud ON.
  2. In Cloudflare SSL/TLS settings, set encryption mode to Full (strict). CF terminates with its managed cert at the edge; the connection back to us is over HTTPS using our cert.
  3. In our dashboard, add the domain at /admin/domains/new.
  4. Skip the auto-issue path — it'll never trigger because Check DNS resolves to Cloudflare's IPs (not ours). Just click Issue / renew SSL manually. Certbot's HTTP-01 challenge still works because Cloudflare proxies the request through to us.

The result: CF serves the public-facing cert; our origin also has a valid cert for the same hostname so CF's "strict" mode is satisfied. Two certs, both legit.

Limitations

  • Only admins can add/manage domains.
  • Both the slug and the domain can be changed on the edit page. Changing the slug breaks any old shared URLs (they'll 404); changing the domain preserves the slug but requires it to be free on the target. Move links between domains via the Domain picker on the edit page.
  • Auto-issue won't fire for Cloudflare-fronted domains — DNS resolves to CF, not us. Use the manual Issue SSL button.

User management

Admins can manage the team from /admin/users. (Non-admins see no Users link in the top nav.)

Roles

  • Admin — can create, deactivate, promote/demote, reset passwords, and (with no owned links) delete other users. Can also bulk-act on any link in the system. The first user (you) is admin by default.
  • Member — can do everything in the rest of the app, but doesn't see the Users page. Can manage their own profile and password.

Adding a teammate

From /admin/users/new:

  1. Enter their email and name.
  2. Leave "Auto-generate password" ticked (recommended) — you'll get a strong temporary password shown once.
  3. Optionally tick "Grant admin role".
  4. Send them their email + temporary password through any channel. They'll be forced to change it on first login.

Deactivate vs delete

Deactivate blocks login and active sessions immediately, but keeps the user's links and stats intact with their name attached. This is the right choice for an offboarding.

Delete is only available for inactive users who own zero links. If they have links, transfer or reassign first (currently a manual SQL update — easy to add a UI later if needed).

Promote / demote / reset password

All on the users list page. Promote/demote toggles the admin role. Reset password generates a new temporary password (shown once) and forces a reset on next login. The system won't let you demote yourself if you're the only admin.

Your profile

/admin/profile — change your display name and your password. Click your name in the top-right nav to get there.

Password changes require your current password. If an admin reset your password, you'll be redirected here on next login and forced to set a new one before doing anything else.

Locked out?

If you've forgotten your password and you're the only admin in your org, contact support and we'll reset it for you.

Gotchas & FAQ

My QR code download is broken

The QR API at qr.stacksy.com.au needs to be up. If it's down, the QR endpoint returns 502; everything else still works.

The country column shows ??

Either the IP couldn't be looked up (ipapi.co didn't answer in time — we cap lookups at 1 second), or the click came from a server-local IP. Future clicks from the same IP will use the cached value.

What happens to clicks if I disable a link?

Clicks already logged are kept. The link starts returning 404. Re-enabling it makes it live again with all its history.

What happens when a link expires?

It returns 410 Gone instead of redirecting — distinct from 404 so crawlers and clients can tell. The link still appears in the dashboard with an expired badge; bump the expiry date to bring it back.

Are passwords on links recoverable?

No — they're hashed with bcrypt. If you forget it, edit the link, set a new password, save.

Where does the click data live?

In our own MySQL database on the Hostinger VPS. Nothing leaves Stacksy infrastructure except the per-IP country lookup (to ipapi.co — IP only, no other context). No third-party analytics, no Bitly, no Google Analytics.

Why is my link preview blank?

The destination might not publish Open Graph tags, might block bots in robots.txt, or took longer than our 3-second fetch limit. The link still works — it just doesn't have a thumbnail. Owners can hit Refresh preview on the edit page to retry.

I'm an admin — can I edit someone else's link?

Not directly from the edit page (only the owner can use that form). But you can bulk-act on any link in the system — disable, tag, or delete — from the dashboard checkboxes.

What does the "pw reset" badge on a user mean?

An admin reset their password, so they're forced to set a new one before they can use the rest of the app. The badge clears as soon as they do.

I clicked Delete by accident. Can I undo?

No — delete is permanent and removes the click history too. The CSV export is your only backup; run it occasionally if you care about your data, especially before bulk operations.