git log --oneline, basically

changelog.

What shipped and when. We'd rather show you this than a roadmap — roadmaps are promises; changelogs are receipts.

v1.9.02026-10-14
  • newLink expiry with fallback_url — retire a link to a destination of your choosing instead of a dead end.
  • changeStats endpoint moved to cursor pagination; the old page params keep working until v2.
  • fixCLI: shortner stats sparkline rendered garbage on terminals without unicode block support; now falls back to ASCII.
v1.8.22026-08-30
  • fixPATCH responses could return the pre-edit status field for a few seconds after an edit. Cosmetic only — redirects themselves were always correct — but confusing, and now gone.
  • fixCLI exit codes: shortner rm on a missing slug now exits 1, not 0. Sorry to everyone's shell scripts.
v1.8.02026-07-22
  • newBulk import: shortner import links.csv creates a link per row and writes the short URLs back out beside your data. Paces itself under the rate limit; resumes if interrupted.
  • newReserved slug prefixes on team plans, so two people can't fight over launch.
v1.7.02026-05-11
  • newPer-link status choice: links can now answer 301 for true permanent moves. The default stays 307, for reasons we wrote down.
  • changeRandom slugs lengthened from 4 to 5 characters; the 4-char space was getting cozy.
v1.6.12026-04-02
  • fixSlugs with lookalike unicode characters are now rejected at create time instead of silently normalized. Clever, whoever tried that.
v1.5.02026-02-18
  • newStats endpoint: per-link totals, daily series, country-level geo, device class. Built privacy-first — see what a hit records.
  • newshortner stats in the CLI, with the sparkline everyone immediately screenshotted.
v1.2.02025-09-26
  • newThe CLI. One static binary, five commands, reads SHORTNER_KEY in CI.
  • changeHEAD supported on redirect paths so link checkers stop complaining.
v1.0.02025-03-07
  • newFirst keys outside the friends-circle. POST / GET / PATCH / DELETE on /links, 307s from day one, and a name we already knew was spelled wrong.