api reference · v1
the docs.
Five endpoints, JSON everywhere, no SDK required. Base URL for everything: https://site-shortner.link/api/v1
authentication
Every request carries your key as a bearer token. Keys start with ssk_live_ and are issued by email while onboarding runs in batches — ask for one here. Treat it like a password; rotate it by asking for a new one.
endpoints
Create a link. The only required field is url; everything else has a sensible default.
| field | type | notes |
|---|---|---|
| url | string, required | Absolute http(s) destination. |
| slug | string | 3–24 chars, a-z 0-9 -. Omit for a random 5-char slug (lookalike characters excluded). |
| status | 301 | 307 | Defaults to 307. See redirect behavior before choosing 301. |
| expires_at | ISO 8601 | Optional. After this moment the link forwards to fallback_url. |
| fallback_url | string | Where expired hits go. Defaults to a plain "this link has ended" page. |
Fetch a link's current state — destination, status code, expiry, timestamps. Add ?list=1 on the bare /links path to page through everything on your key (cursor pagination, 100 per page).
The endpoint this whole service exists for. Change url, status, expires_at, or fallback_url — the edit is live on the very next request. No cache purge step, because 307s are never cached. That's not luck; that's the design.
Returns 204. The slug keeps answering with your fallback page for 30 days (so anything already shipped degrades politely), then it's released back to the pool.
Hit totals, a daily time series, coarse geo (country level), and device class. Numbers about requests, never identities — the privacy page spells out exactly what a hit records.
redirect behavior
Public hits on site-shortner.link/{slug} answer with the link's status code — 307 by default — and a Location header pointing at the current destination. We send cache-control: no-store on 307s so every hit re-checks, which is what makes edits instant. There are no interstitial pages, no frames, no link-wrapping: the visitor's address bar shows the real destination the moment they land.
- Choose 301 only for forever. Browsers may cache a 301 permanently and stop asking us — which means a 301'd link can't reliably be edited later. Great for SEO on a true permanent move; wrong for anything that might change. (The long version.)
- Unknown slugs return a plain 404 — never a parked-ad page.
- HEAD is supported, so monitoring tools and link checkers behave.
errors
| code | meaning | you'll see it when |
|---|---|---|
| 400 | bad request | Malformed JSON, missing url, non-http(s) scheme. |
| 401 | unauthorized | Missing or revoked key. |
| 404 | not found | No such slug on your key. |
| 409 | conflict | Slug already taken — pick another or omit it. |
| 422 | unprocessable | Slug has illegal characters, or expires_at is in the past. |
| 429 | rate limited | See below. Response includes retry-after. |
Every error body is {"error": {"code": "...", "message": "..."}} with a message written for humans, not lawyers.
rate limits
The management API allows 60 requests/minute per key — generous for anything short of a bulk migration (use the CLI's import for that; it paces itself). Redirects themselves are not rate-limited: a link that goes viral keeps answering, full stop.