ShortLink
Developer Platform

ShortLink Developer API

The ShortLink REST API allows you to programmatically create short URLs, configure custom branded domains, query real-time analytics, and stream event notifications via authenticated webhooks.

Base URLhttp://localhost:3000/api/v1

Authentication

Authenticate your API requests by including your secret API key in the Authorization HTTP header using the Bearer scheme:

Authorization: Bearer sl_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxx

You can generate API keys inside your Dashboard → API Keys page. Remember that your secret key is only displayed once upon creation.

Scopes & Least Privilege

ShortLink enforces fine-grained scopes to protect against credential misuse:

ScopeDescription
links:readList and inspect user short links
links:writeCreate and update link destinations and rules
links:deleteArchive or permanently delete short links
analytics:readAccess click timeseries, geo, and device analytics
bulk:writeBatch create links programmatically
webhooks:writeCreate, update, and test webhook endpoints

Webhooks Architecture

ShortLink delivers webhook payloads asynchronously using an event envelope. Deliveries are never performed synchronously inside visitor redirect paths, guaranteeing sub-millisecond edge latency.

Supported Event Types
  • link.created: New link added
  • link.updated: Destination or rules edited
  • link.archived: Link moved to archive
  • link.expired: UTC expiration reached
  • link.limit_reached: Max clicks exhausted
  • domain.verified: Branded DNS confirmed

HMAC-SHA256 Signature Verification

To guarantee that incoming requests originate from ShortLink and haven't been tampered with, every delivery includes:

  • X-ShortLink-Signature: Hex-encoded HMAC-SHA256 hash of timestamp + "." + rawBody
  • X-ShortLink-Timestamp: UTC timestamp in seconds
  • X-ShortLink-Delivery: Unique delivery UUID
verify-webhook.ts
import crypto from "crypto";

export function verifyShortLinkWebhook(
  rawBody: string,
  signatureHeader: string,
  timestampHeader: string,
  secret: string
): boolean {
  // 1. Defend against replay attacks: reject events older than 5 minutes (300s)
  const eventTime = parseInt(timestampHeader, 10);
  const currentTime = Math.floor(Date.now() / 1000);
  if (Math.abs(currentTime - eventTime) > 300) {
    return false;
  }

  // 2. Compute expected HMAC-SHA256 signature
  const expectedSignature = crypto
    .createHmac("sha256", secret)
    .update(`${timestampHeader}.${rawBody}`)
    .digest("hex");

  // 3. Constant-time comparison prevents timing attacks
  return crypto.timingSafeEqual(
    Buffer.from(signatureHeader, "hex"),
    Buffer.from(expectedSignature, "hex")
  );
}

Rate Limits & Headers

API request quotas are enforced per API key according to your account subscription tier:

Free Tier60 req/min
Pro Tier300 req/min
Business Tier1,000 req/min

Standard Error Codes

HTTP StatusCodeMeaning
400VALIDATION_ERRORPayload failed schema or SSRF checks
401UNAUTHORIZEDMissing or invalid Bearer API key
403FORBIDDENInsufficient scope or plan quota exceeded
404NOT_FOUNDRequested link or endpoint does not exist
429RATE_LIMIT_EXCEEDEDToo many requests. Check Retry-After header