kna.sh

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

QR codes

GET /api/v1/links/{id}/qrcode — requires urls:read. Returns a PNG or SVG of the short URL.

Useful query parameters:

  • formatpng (default) or svg
  • scale — pixel scale (default 8)
  • border — quiet zone modules
  • color / light — foreground / background colors
  • error — error correction L, M, Q, or H
  • url_kindauto (ID-based short URL) or custom (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 link
  • limit — 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. acmehttps://acme.g.kna.sh/…). Empty string clears.
  • path_prefix — unique claimed prefix for short links on https://kna.sh/{prefix}/{id} (1–12 characters: letters, digits, . _ ~ -; profanity filtered; cannot match reserved SPA/system paths such as login or about). Empty string clears. Case-insensitive uniqueness across organizations.
  • custom_domain — bring-your-own host (e.g. go.mydomain.com). Create a DNS CNAME to cd.kna.sh, then call POST /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 credentials
  • 403 — authenticated but missing permission
  • 404 — 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:

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.