b59.link API

A simple REST API for shortening URLs, generating QR codes, and reading click stats. No API key required — anyone can use it. If you sign up, your links are tracked to your account.

Base URL

https://b59.link/api

All endpoints accept and return JSON. Errors follow a standard { detail: string } shape.

Authentication

All endpoints work without authentication. Links created anonymously are public and permanent. Sign in with your b59.link account to associate links with your profile and manage them from the dashboard.

POST/api/shorten

Shorten a long URL. Omit slug to get suggestions; include slug to create the link immediately.

Request body

{
  "url": "https://example.com/very/long/url",
  "slug": "my-link"   // optional
}

Response

// Without slug — returns suggestions:
{ "suggestions": ["cool-jump", "fast-fly", "slim-run"] }

// With slug — creates the link:
{
  "slug": "my-link",
  "short_url": "https://b59.link/my-link"
}

Code sample

// Shorten a URL
const res = await fetch("https://b59.link/api/shorten", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    url: "https://example.com/very/long/path",
    slug: "my-link",   // optional
  }),
});
const data = await res.json();
console.log(data.short_url); // https://b59.link/my-link
console.log(data.slug);      // my-link
POST/api/qr

Generate a QR code for a URL. Also creates a short link in one call. Returns a base64-encoded PNG.

Request body

{
  "url": "https://example.com"
}

Response

{
  "slug": "cool-jump",
  "short_url": "https://b59.link/cool-jump",
  "qr_code_data": "<base64 PNG>"
}

Code sample

// Generate a QR code (also creates a short link)
const res = await fetch("https://b59.link/api/qr", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ url: "https://example.com" }),
});
const data = await res.json();
// data.qr_code_data is a base64-encoded PNG
const img = document.createElement("img");
img.src = `data:image/png;base64,${data.qr_code_data}`;
document.body.appendChild(img);
GET/api/stats/{identifier}

Get click stats for a link. Pass either a slug or the original URL as the identifier.

Request body

GET /api/stats/my-link
// or
GET /api/stats/https%3A%2F%2Fexample.com

Response

{
  "slug": "my-link",
  "original_url": "https://example.com/...",
  "short_url": "https://b59.link/my-link",
  "qr_code_data": "<base64 PNG or null>",
  "total_hits": 42,
  "hits": [
    {
      "timestamp": "2025-05-19T10:00:00",
      "ip_address": "1.2.3.4",
      "referer": "https://instagram.com",
      "user_agent": "Mozilla/5.0 ..."
    }
  ]
}

Code sample

// Get stats by slug or original URL
const slug = "my-link";
const res = await fetch(`https://b59.link/api/stats/${slug}`);
const data = await res.json();
console.log(data.total_hits);   // 42
console.log(data.original_url); // https://example.com/...

// You can also pass the original URL as the identifier
const res2 = await fetch(
  `https://b59.link/api/stats/${encodeURIComponent("https://example.com")}`
);
GET/api/links/lookup

Check if a URL already has a b59.link. Automatically tries http/https, www, and trailing-slash variations.

Request body

GET /api/links/lookup?url=https%3A%2F%2Fexample.com

Response

// Found:
{
  "found": true,
  "slug": "cool-jump",
  "short_url": "https://b59.link/cool-jump",
  "stats_url": "https://b59.link/stats/cool-jump",
  "qr_code_data": "<base64 PNG or null>"
}

// Not found:
{ "found": false }

Code sample

// Check if a URL already has a b59 link (handles http/https/www variations)
const url = "https://example.com";
const res = await fetch(
  `https://b59.link/api/links/lookup?url=${encodeURIComponent(url)}`
);
const data = await res.json();
if (data.found) {
  console.log(data.short_url);   // https://b59.link/cool-jump
  console.log(data.stats_url);   // https://b59.link/stats/cool-jump
  // data.qr_code_data — base64 PNG if QR exists
} else {
  console.log("No link yet — create one with POST /qr");
}

Error responses

All errors return a JSON body with a detail field.

StatusMeaning
400Bad request — invalid slug format
404Link not found
409Conflict — URL or slug already exists
422Validation error — missing required field
500Internal server error