shorten.dev/docs
shorten.dev/docs
Getting StartedAuthentication
OverviewTypeScript
SDKs

TypeScript

Official TypeScript SDK for the Shorten.dev API.

Installation

npm install @shorten-dev/sdk

Requires Node.js 18+ (or any runtime with global fetch). No external dependencies.

Quick start

import { Shorten } from "@shorten-dev/sdk";

const shorten = new Shorten("sk_your_api_key");

// Create a short link
const { link, short_url } = await shorten.links.create({
  destination_url: "https://example.com",
  tags: ["demo"],
});
console.log(short_url); // https://r.shorten.dev/abc1234

// List your links
const { data: links } = await shorten.links.list({
  status: "active",
  limit: 20,
});

// Get analytics
const analytics = await shorten.analytics.get("abc1234", {
  period: "30d",
});
console.log(analytics.total_clicks);

Configuration

const shorten = new Shorten("sk_your_api_key", {
  // Base URL (default: https://shorten.dev/api/v1)
  baseUrl: "https://shorten.dev/api/v1",

  // Request timeout in ms (default: 30000)
  timeout: 30_000,

  // Max retries on 429/5xx (default: 3)
  maxRetries: 3,

  // Custom fetch implementation (for testing or alt runtimes)
  fetch: customFetch,
});

API reference

Links

shorten.links.create(body)

Create a shortened link.

const { link, short_url, warning } = await shorten.links.create({
  destination_url: "https://example.com",
  custom_slug: "my-link",  // optional
  tags: ["docs", "v2"],    // optional, max 3
});

shorten.links.list(params?)

List links with optional filters.

const result = await shorten.links.list({
  page: 1,           // default: 1
  limit: 20,         // default: 10, max: 50
  sort: "created_at", // or "updated_at"
  order: "desc",     // or "asc"
  status: "active",  // "active" | "flagged" | "revoked"
  search: "example", // search slug and URL
  tag: "docs",       // filter by tag
});

for (const link of result.data) {
  console.log(link.slug, link.destination_url);
}

shorten.links.get(slug)

Get a single link by slug.

const link = await shorten.links.get("abc1234");

shorten.links.revoke(slug)

Permanently revoke a link. The short URL stops redirecting immediately.

const link = await shorten.links.revoke("abc1234");
// link.status === "revoked"

shorten.links.bulkCreate(body)

Create up to 500 links in one request. Each link counts toward your rate limit.

const result = await shorten.links.bulkCreate({
  links: [
    { destination_url: "https://example.com/a" },
    { destination_url: "https://example.com/b", custom_slug: "b" },
  ],
});
console.log(result.total_created); // 2

Analytics

shorten.analytics.get(slug, params?)

Get click analytics for a link.

const analytics = await shorten.analytics.get("abc1234", {
  period: "30d", // "7d" | "30d" | "90d" (default: "7d")
});

console.log(analytics.total_clicks);
console.log(analytics.unique_visitors);
console.log(analytics.top_countries);  // [{ country: "US", count: 100 }, ...]
console.log(analytics.top_referrers);  // [{ referrer: "google.com", count: 50 }, ...]
console.log(analytics.top_devices);    // [{ device: "macOS", count: 80 }, ...]
console.log(analytics.top_browsers);   // [{ browser: "Chrome", count: 90 }, ...]
console.log(analytics.time_series);    // [{ date: "2026-01-01", clicks: 10 }, ...]

Usage

shorten.usage.get()

Get your current rate-limit usage.

const usage = await shorten.usage.get();
console.log(`${usage.remaining}/${usage.limit} remaining`);
console.log(`Resets at ${usage.reset_at}`);

Error handling

The SDK throws typed errors for API failures and network issues.

import { Shorten, ShortenApiError, NetworkError } from "@shorten-dev/sdk";

try {
  await shorten.links.create({ destination_url: "https://example.com" });
} catch (err) {
  if (err instanceof ShortenApiError) {
    console.error(err.status);       // 409
    console.error(err.body.error);   // "conflict"
    console.error(err.body.message); // "Slug already taken"
  } else if (err instanceof NetworkError) {
    console.error(err.url);   // The URL that failed
    console.error(err.cause); // The underlying fetch error
  }
}

Rate limiting

The SDK automatically retries on 429 Too Many Requests with exponential backoff and jitter. After each request, you can inspect the rate-limit headers:

await shorten.links.list();

const rateLimit = shorten.lastRateLimit;
if (rateLimit) {
  console.log(rateLimit.limit);  // 300
  console.log(rateLimit.used);   // 42
  console.log(rateLimit.reset);  // Unix timestamp
}

TypeScript types

All request/response types are exported for convenience:

import type {
  Link,
  LinkStatus,
  CreateLinkRequest,
  CreateLinkResponse,
  BulkCreateLinksRequest,
  BulkCreateLinksResponse,
  AnalyticsResponse,
  AnalyticsPeriod,
  UsageResponse,
  PaginatedResponse,
  ApiError,
  ListLinksParams,
  GetAnalyticsParams,
} from "@shorten-dev/sdk";

Overview

Official TypeScript SDK for the Shorten.dev API.

Overview

Shorten URLs from your terminal with the shorten CLI.

On this page

InstallationQuick startConfigurationAPI referenceError handlingRate limitingTypeScript types