Skip to content

JavaScript / TypeScript

The official INBIO SDK for Node.js, browsers, and edge runtimes.

Updated View as Markdown

Full TypeScript types, zero runtime dependencies, dual ESM + CJS. Uses the global fetch — Node.js ≥ 18, browsers, and edge runtimes all work.

npm install inbio-sdk

Shorten a URL (no account)

import { shorten } from "inbio-sdk";

const link = await shorten("https://example.com/very/long/url");
console.log(link.short_url); // https://in.bio/a8K2p

Authenticated client

Pass a token or set INBIO_API_TOKEN in the environment:

import Inbio from "inbio-sdk";

const client = new Inbio({ token: process.env.INBIO_API_TOKEN });

const created = await client.links.create({
  destinationUrl: "https://example.com/sale",
  slug: "spring-sale",
  tags: ["marketing"],
  utm: { source: "newsletter", medium: "email" },
});

Request options are camelCase (folderId, perPage, clickLimit); response models keep the exact API field names (short_url, total_clicks).

Everything else

// List with filters, or iterate every page automatically
const page = await client.links.list({ status: "active", perPage: 50 });
for await (const link of client.links.iterate({ tag: "marketing" })) {
  console.log(link.slug, link.total_clicks);
}

// Update, toggle, delete
await client.links.update(42, { title: "Renamed" });
await client.links.disable(42);
await client.links.enable(42);
await client.links.delete(42);

// QR code bytes → file
import { writeFile } from "node:fs/promises";
const qr = await client.links.qr(42, { format: "png", size: 1024 });
await writeFile("qr.png", qr);

// Analytics, folders, tags, usage
const stats = await client.links.analytics(42, { from: "2026-06-01" });
const folders = await client.folders.list();
const tags = await client.tags.list();
const usage = await client.account.usage();

Errors

import { RateLimitError, ValidationError } from "inbio-sdk";

try {
  await client.links.create({ destinationUrl: url });
} catch (err) {
  if (err instanceof ValidationError) console.log(err.errors);
  if (err instanceof RateLimitError) console.log(err.retryAfter);
}

AuthenticationError (401), AccessError (403, plan or scope), NotFoundError, ValidationError, EntitlementError, StateConflictError (409), RateLimitError (429), ServerError — all extend InbioError. GET requests and Retry-After 429s are retried automatically with backoff.

Webhooks

Verification lives in a separate Node-only entry so the core client stays browser-safe:

import { verify } from "inbio-sdk/webhooks";

// e.g. in an Express handler with the raw body
const event = verify(rawBody, req.headers["x-inbio-signature"], secret);
if (event.event === "link.clicked") {
  /* ... */
}

Signatures are checked with a constant-time comparison and a 5-minute replay-protection window. See Webhooks for the payload format.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close