API & MCP

KooLink exposes a small REST API plus an MCP server so users and AI agents can shorten links programmatically. All programmatic shortening is authenticated with an API key (a bearer token), not an OAuth session.

Get an API key

  1. Sign in → Dashboard → Settings → API Keys.
  2. Click Create key, optionally add a label (e.g. "My AI agent").
  3. Copy the key (kl_…) — it is shown once.

Revoke anytime from the same card. A revoked key returns 401 on the API.

POST /api/v1/shorten

Create a short link attributed to the key's owner (so it earns).

Headers

Authorization: Bearer kl_<your-key>
Content-Type: application/json

Body

{ "url": "https://example.com/some/long/path", "label": "optional" }

Response (200)

{
  "shortUrl": "https://kool.ink/abc123",
  "code": "abc123",
  "originalUrl": "https://example.com/some/long/path",
  "id": "cl…",
  "title": "Example Domain"
}

Errors

  • 401 — missing/invalid/revoked key.
  • 400 — unsupported URL scheme or blocked destination.
  • 429 — rate limited (per key).
  • 500 — creation failed.

The endpoint reuses the same pipeline as the in-app shortener: generateUniqueShortCodeparseDestinationUrlbasicSafetyCheckfetchDestinationTitleLink.create.

Manage keys (session auth)

GET/POST/DELETE /api/account/api-keys — session-cookie authenticated, mirrors the dashboard card. POST returns the raw token once; DELETE takes { id }.

MCP server

Two ways to let an agent shorten links:

  1. Hosted HTTP endpoint — kool.ink/mcp (recommended). Point any MCP client at the URL https://kool.ink/mcp. No install, no local process. Supports initialize, tools/list, and tools/call over JSON-RPC (Streamable HTTP transport, connectionless).
  2. Local stdio server — see mcp/README.md. Zero-dep node server.mjs exposing the same shorten_url tool; key via KOOLINK_API_KEY env var.

Both expose three tools:

ToolArgsReturns
shorten_urlurl (req), handle, labelshort URL (https://kool.ink/CODE), code, original URL
link_statscode (req)total vs valid views, by device / country / referrer, 7-day trend
list_linkslimit (opt, 1-100)the owner's links with valid view counts

Auth is optional

An API key is not required to use /mcp — an anonymous client can shorten links straight away (links are created ownerless, like the landing shortener), rate-limited per IP. Pass Authorization: Bearer *** (a key from Settings → API Keys) to **connect the session to your account**, which unlocks owner-scoped analytics: link_statsandlist_links` require a key and return a clear "API key required" error without one.

Analytics endpoints

GET /api/v1/links — the key owner's links (most recent first) with valid view counts. Optional ?limit=1..100 (default 20). Scoped to the key owner; never returns other users' links.

GET /api/v1/links/[code]/stats — aggregated analytics for one owned link: total vs valid (fraud-filtered) views, breakdowns by device / country / referrer, and a trailing-7-day trend. Returns 404 for a code that is unknown or belongs to another user (never reveals whether a code exists).

Both take Authorization: Bearer kl_…, support the same 401/429 errors as /api/v1/shorten, and are exactly what link_stats / list_links call under the hood.

Security notes

  • Tokens are stored as a SHA-256 hash; the raw value lives only in the create response. A DB leak can't mint keys.
  • lastUsedAt is stamped on use (best-effort).
  • The ApiKey table is created by a migration that applies on deploy. It is additive (new table, cascade delete) and does not alter existing data.
Need help?