API v1 reference

Authenticate with a workspace API key (Pro). Keys are shown once at creation; only a SHA-256 hash is stored.

Authentication

Authorization: Bearer lt_<secret>

Create a key from the Dashboard (Pro) or via POST /api/workspace/api-keys with your Clerk session.

List links

GET /api/v1/links
Authorization: Bearer lt_...

200{ "links": [ ... ] }(full link rows for the key's workspace, newest first). Each link includes clickCount (human clicks, same as the dashboard).

Get one link

GET /api/v1/links/{id}
Authorization: Bearer lt_...

200{ "link": { ... , "clickCount": 0 } }. 404 if the id is not in your workspace.

Create link

POST /api/v1/links
Authorization: Bearer lt_...
Content-Type: application/json

{
  "destinationUrl": "https://example.com/page",
  "quickShorten": true
}

Quick shorten with URL cloaking (address bar stays on the short link):

{
  "destinationUrl": "https://example.com/page",
  "quickShorten": true,
  "urlCloaking": true
}

Or full preview fields (same as app API):

{
  "destinationUrl": "https://example.com/page",
  "botTitle": "Title for crawlers",
  "botDescription": "Description for crawlers",
  "ogImageUrl": "https://cdn.example.com/card.png",
  "campaign": "spring",
  "utmSource": "newsletter",
  "utmMedium": "email",
  "utmCampaign": "apr",
  "expiresAt": "2026-12-31T23:59:59.000Z",
  "isActive": true,
  "humanBufferPage": false,
  "urlCloaking": false
}

200 { "id", "slug", "shortUrl", "botTitle", "botDescription", "ogImageUrl", "humanBufferPage", "urlCloaking" }. Subject to rate limits.

humanBufferPage — optional interstitial with countdown before redirect. urlCloaking — load the destination in a full-page frame so the browser address bar keeps the short URL. Both apply to human visitors only; preview bots always receive OG HTML. See Link previews & social cards.

Update link

PATCH /api/v1/links/{id}
Authorization: Bearer lt_...
Content-Type: application/json

{
  "botTitle": "New title",
  "isActive": false,
  "humanBufferPage": true,
  "urlCloaking": true
}

Updatable fields mirror the session API: destination, bot meta, image, campaign, notes, utm_*, isActive, expiresAt, humanBufferPage, urlCloaking. Response includes clickCount.

Delete link

DELETE /api/v1/links/{id}
Authorization: Bearer lt_...

Click analytics

GET /api/v1/links/{id}/clicks?limit=50&offset=0
Authorization: Bearer lt_...

200 { "linkId", "clickCount", "summary": { "byCountry", "topReferrers" }, "clicks": [ ... ], "pagination": { "limit", "offset", "hasMore" } }. Same shape on the session API at GET /api/links/{id}/clicks. See Clicks & campaign links.

Bulk create

POST /api/v1/links/batch
Authorization: Bearer lt_...
Content-Type: application/json

{
  "urls": ["https://example.com/a", "https://example.com/b"],
  "urlCloaking": false
}

200 { "results": [ ... ], "quota": { ... }, "created", "failed" }. Accepts urls (array) or text (newline-separated). Max 100 URLs per request.

OpenAPI

Machine-readable spec: OpenAPI specification (download YAML).

Error responses

  • 401 — missing or invalid Bearer token.
  • 429 — rate limit.
  • 404 — link id not in workspace.