Developers
API usage
kna.sh exposes a JSON HTTP API so you can create short links, manage keys and users, generate QR codes, and review click data from your own apps and scripts.
Base URL
Production API host:
https://api.kna.sh
All managed endpoints are under /api/v1/….
Send Content-Type: application/json on requests that include a body.
Authentication
Most endpoints require authentication as a member of your organization.
API key (recommended for scripts)
Create a key in the console under API keys, then send it as a Bearer token:
Authorization: Bearer kna_…your_secret…
The full secret is shown only once when the key is created. Store it securely.
Keys are scoped by the roles you assign; they cannot use the admin role
(user management stays in the console or session auth).
Browser session
The web console signs in with email/password (or a passkey) and uses an HTTP-only session cookie. That is the usual path for interactive use; API keys are preferred for automation.
Roles & permissions
Users and API keys hold one or more roles. Effective access is the union of those roles’ permissions.
| Role | Permissions |
|---|---|
viewer |
urls:read — list links and click data |
editor |
urls:read, urls:write — create and update links |
api_manager |
apikeys:read, apikeys:write — manage API keys |
admin |
All of the above plus users:manage (users and account branding) |
API keys may use viewer, editor, and/or
api_manager. They cannot be granted admin.
Quickstart
Create a short link with an API key that has the editor role (or equivalent write access):
curl -sS -X POST https://api.kna.sh/api/v1/links \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com/page","title":"Example"}'
A successful response is 201 with JSON including id,
short_url, auto_short_url, destination url, and hit counters.
Compatibility alias (same body and auth as create link):
POST /api/v1/shorten
Links
Requires urls:read or urls:write as noted.
| Method | Path | Permission | Description |
|---|---|---|---|
| GET | /api/v1/links |
urls:read |
List all links for your account |
| POST | /api/v1/links |
urls:write |
Create a short link |
| GET | /api/v1/links/check-slug |
urls:write |
Check vanity path availability on go.kna.sh |
| GET | /api/v1/links/{id} |
urls:read |
Get one link |
| PATCH | /api/v1/links/{id} |
urls:write |
Update destination, title, slug, or status |
| DELETE | /api/v1/links/{id} |
urls:write |
Delete a link |
Create body
{
"url": "https://example.com/destination",
"title": "Optional title",
"custom_slug": "optional-vanity-path"
}
url— required; must behttporhttpstitle— optional, up to 200 characters-
custom_slug— optional vanity path onhttps://go.kna.sh/{slug}(1–64 characters; letters, digits,._-)
Update body (all fields optional)
{
"url": "https://example.com/new",
"title": "Updated title",
"custom_slug": "new-path",
"enabled": true,
"active": true
}
enabled: false— link returns not found to visitorsactive: false— link is treated as gone for visitors
Slug check
curl -sS "https://api.kna.sh/api/v1/links/check-slug?slug=promo" \ -H "Authorization: Bearer YOUR_API_KEY"
Optional query exclude_link_id when editing an existing link so its own slug
still counts as available.
QR codes
GET
/api/v1/links/{id}/qrcode
— requires urls:read. Returns a PNG or SVG of the short URL.
Useful query parameters:
format—png(default) orsvgscale— pixel scale (default8)border— quiet zone modulescolor/light— foreground / background colorserror— error correctionL,M,Q, orH-
url_kind—auto(ID-based short URL) orcustom(vanity path on go.kna.sh, when set) download=true— attachment disposition
curl -sS -o link.png \ "https://api.kna.sh/api/v1/links/LINK_ID/qrcode?format=png&scale=10" \ -H "Authorization: Bearer YOUR_API_KEY"
Clicks & reports
Requires urls:read.
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/clicks |
Recent click events |
| GET | /api/v1/clicks/report |
Aggregates plus recent events |
Query parameters for both:
link_id— optional filter to one linklimit— 1–1000 (default 200)
Report JSON includes totals and breakdowns by region, city, device type, and link, plus the underlying click list (region, device, timestamps, and related fields).
curl -sS "https://api.kna.sh/api/v1/clicks/report?limit=100" \ -H "Authorization: Bearer YOUR_API_KEY"
API keys
Requires apikeys:read / apikeys:write.
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/api-keys |
List keys (secret never returned) |
| POST | /api/v1/api-keys |
Create key; response includes key once |
| GET | /api/v1/api-keys/{id} |
Get one key metadata |
| PATCH | /api/v1/api-keys/{id} |
Rename, change roles, or revoke |
| DELETE | /api/v1/api-keys/{id} |
Delete permanently |
Create body
{
"name": "CI pipeline",
"roles": ["editor"]
}
Default role list is ["editor"]. Allowed roles on keys:
viewer, editor, api_manager.
Users
Requires users:manage (the admin role). Typically used with a
browser session rather than an API key.
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/users |
List members of your account |
| POST | /api/v1/users |
Invite / create a user |
| GET | /api/v1/users/{id} |
Get one user |
| PATCH | /api/v1/users/{id} |
Update name, email, password, roles, or active |
| DELETE | /api/v1/users/{id} |
Remove a user (optional cascade on their links) |
Create body
{
"name": "Alex",
"email": "alex@example.com",
"password": "at-least-8-chars",
"roles": ["editor"]
}
Account branding
| Method | Path | Permission | Description |
|---|---|---|---|
| GET | /api/v1/customer |
urls:read |
Organization name and branding |
| PATCH | /api/v1/customer |
users:manage |
Update name, branded hostname, path prefix |
Update body (all optional)
{
"name": "Acme Co",
"hostname": "acme",
"path_prefix": "promo",
"custom_domain": "go.mydomain.com"
}
-
hostname— label under*.g.kna.sh(e.g.acme→https://acme.g.kna.sh/…). Empty string clears. -
path_prefix— unique claimed prefix for short links onhttps://kna.sh/{prefix}/{id}(1–12 characters: letters, digits,._~-; profanity filtered; cannot match reserved SPA/system paths such asloginorabout). Empty string clears. Case-insensitive uniqueness across organizations. -
custom_domain— bring-your-own host (e.g.go.mydomain.com). Create a DNS CNAME tocd.kna.sh, then callPOST /api/v1/customer/custom-domain/verify. Short links use the custom domain only after verification succeeds.
Session auth
These endpoints power the console (cookies after login). Useful if you build a custom UI; for server automation prefer API keys.
| Method | Path | Description |
|---|---|---|
| POST | /api/v1/auth/signup |
Create organization + first admin user |
| POST | /api/v1/auth/login |
Email + password; sets session cookie |
| POST | /api/v1/auth/logout |
Clear session |
| GET | /api/v1/auth/me |
Current user, customer, permissions |
| GET | /api/v1/auth/roles |
Role catalog (public) |
| POST | /api/v1/auth/verify-email |
Confirm email with code |
| POST | /api/v1/auth/resend-verification |
Resend confirmation code |
| POST | /api/v1/auth/forgot-password |
Request password reset email |
| POST | /api/v1/auth/reset-password |
Set password with reset token |
Passkeys (WebAuthn) are available under
/api/v1/auth/passkey/… for register, list, delete, and login flows in supporting browsers.
Bootstrap config (hosts and session idle TTL):
GET
/api/v1/config
Errors & conventions
- JSON error bodies typically look like
{"detail": "…"}. 401— missing or invalid credentials403— authenticated but missing permission404— resource not found (or wrong account)409— conflict (e.g. email or hostname already taken)422— validation error on the request body or query
Link IDs use the form AAAAAAAA.AAAA (hex + separator). Paths are case-insensitive
for resolution; vanity slugs are compared case-insensitively.
Interactive OpenAPI
Machine-readable schema and an interactive explorer are served on the API host:
- https://api.kna.sh/docs — Swagger UI
- https://api.kna.sh/redoc — ReDoc
- https://api.kna.sh/openapi.json — OpenAPI JSON
Prefer this guide and the endpoints above for account automation. The OpenAPI surface may list additional internal paths; stick to the customer endpoints documented here for stable integrations.