Short answer
The Linkbreakers TypeScript SDK enables programmatic link management, visitor identification, and analytics access from your TypeScript and JavaScript applications. It supports two integration modes: frontend visitor tracking with publishable keys (safe for browsers) and backend operations with secret keys (server-side only). Install with npm install linkbreakers and choose the appropriate key type for your use case.
Installation
Install the SDK using your preferred package manager:
# Using pnpm (recommended)
pnpm add linkbreakers
# Using npm
npm install linkbreakers
# Using yarn
yarn add linkbreakers
Understanding API key types
Linkbreakers provides two types of API keys for different security contexts:
Publishable keys
Safe for frontend/browser use. These JWT tokens can be embedded in client-side code without security concerns.
What they allow:
- Identify visitors (associate user data with sessions)
- Track visitor behavior and attributes
- Read visitor profiles
What they DON'T allow:
- Create or manage links
- Access workspace-level data
- View analytics or metrics
- Modify workspace settings
When to use: Frontend applications, mobile apps, browser extensions, or any environment where the key could be exposed publicly.
Secret keys
Backend-only. These JWT tokens grant full API access and must never be exposed in client-side code.
What they allow:
- Everything publishable keys can do, plus:
- Create, update, and delete links
- Generate QR codes
- Access analytics and metrics
- Manage workspace resources
- Full API access
When to use: Server-side applications, API routes, serverless functions, CI/CD pipelines, or any secure backend environment.
Creating API keys
Create your API keys from the dashboard:
- Log in to app.linkbreakers.com
- Navigate to Dashboard → API Tokens
- Click Create API Token
- Choose the key type:
- Publishable Key for frontend visitor tracking
- Secret Key for backend link management
- Give it a descriptive name (e.g., "Production Frontend" or "Backend API")
- Copy the generated key immediately (you won't see it again)
Security best practice: Use environment variables for both key types. While publishable keys are safe to expose, storing them in env vars makes key rotation easier.
Frontend usage: Visitor tracking
Use publishable keys to identify visitors when they sign up, log in, or interact with your application.
Basic visitor identification
import { Configuration, VisitorsApi } from 'linkbreakers';
// ✅ SAFE FOR FRONTEND - Using publishable key (JWT token)
const config = new Configuration({
accessToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...', // Publishable JWT token
basePath: 'https://api.linkbreakers.com',
});
const visitorsApi = new VisitorsApi(config);
// Extract LBID from URL (comes from link clicks with conversion tracking)
const urlParams = new URLSearchParams(window.location.search);
const lbid = urlParams.get('lbid');
if (lbid) {
// Identify the visitor with their data
const response = await visitorsApi.visitorsServiceIdentify({
identifyRequest: {
lbid: lbid,
visitor: {
data: {
// System fields (prefixed with "$")
'$email': 'user@example.com',
'$phone': '+1234567890',
'$firstName': 'John',
'$lastName': 'Doe',
// Custom attributes (no "$" prefix)
'plan': 'premium',
'signupDate': '2024-01-15',
'company': 'Acme Corp'
}
},
setOnce: false // If true, only sets empty fields (preserves existing data)
}
});
console.log('New visitor profile:', response.created);
console.log('Visitor ID:', response.visitor?.id);
}
Understanding LBID (Linkbreakers ID)
When visitors click your Linkbreakers links with conversion tracking enabled, a query parameter ?lbid=... is automatically added to the destination URL. This LBID connects the click event to the visitor, enabling powerful attribution and analytics.
Where LBID comes from:
- Query parameter when users click your short links:
?lbid=abc123 - Tracking cookies set by Linkbreakers
- Webhook payloads for link interactions
Learn more in our What is LBID? guide.
Form submission example
Track users who fill out forms on your landing page:
// In your form handler
async function handleFormSubmit(formData) {
const config = new Configuration({
accessToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...', // Publishable JWT
basePath: 'https://api.linkbreakers.com',
});
const visitorsApi = new VisitorsApi(config);
const lbid = new URLSearchParams(window.location.search).get('lbid');
if (lbid) {
await visitorsApi.visitorsServiceIdentify({
identifyRequest: {
lbid: lbid,
visitor: {
data: {
'$email': formData.email,
'$firstName': formData.firstName,
'$lastName': formData.lastName,
'interest': formData.productInterest,
'source': 'landing-page-form'
}
}
}
});
}
}
Backend usage: Link management
Use secret keys on your backend to create and manage links programmatically.
Creating your first link
import { Configuration, LinksApi } from 'linkbreakers';
// ❌ NEVER USE IN FRONTEND - Secret key for backend only
const config = new Configuration({
accessToken: process.env.LINKBREAKERS_SECRET_KEY, // Secret JWT from env var
basePath: 'https://api.linkbreakers.com',
});
const linksApi = new LinksApi(config);
// Create a shortened link
const response = await linksApi.linksServiceCreate({
createLinkRequest: {
destination: 'https://example.com/product',
name: 'Product Launch Campaign',
tags: ['marketing', 'spring-2025']
}
});
console.log('Short URL:', response.link?.shortlink);
console.log('QR Code URL:', response.link?.qrcodeSignedUrl);
Advanced link creation
import { Configuration, LinksApi } from 'linkbreakers';
const config = new Configuration({
accessToken: process.env.LINKBREAKERS_SECRET_KEY,
basePath: 'https://api.linkbreakers.com',
});
const linksApi = new LinksApi(config);
// Create link with custom shortlink
const customLink = await linksApi.linksServiceCreate({
createLinkRequest: {
destination: 'https://example.com/docs',
shortlink: 'docs', // Creates lbr.ai/docs
name: 'Documentation Home',
tags: ['docs', 'internal'],
metadata: {
campaign_id: 'spring-2025',
department: 'engineering'
}
}
});
// Create link with QR code (wait for generation)
const qrLink = await linksApi.linksServiceCreate({
createLinkRequest: {
destination: 'https://example.com/event',
name: 'Conference Registration',
waitForQrcode: true, // Blocks until QR is ready
tags: ['event', 'qr-code']
}
});
console.log('Download QR:', qrLink.link?.qrcodeSignedUrl);
Managing links
import { Configuration, LinksApi } from 'linkbreakers';
const config = new Configuration({
accessToken: process.env.LINKBREAKERS_SECRET_KEY,
basePath: 'https://api.linkbreakers.com',
});
const linksApi = new LinksApi(config);
// List links with filtering
const listResponse = await linksApi.linksServiceList({
pageSize: 50,
tags: ['marketing'],
search: 'campaign',
sortBy: 'LINK_SORT_FIELD_UPDATED_AT',
sortDirection: 'SORT_DIRECTION_DESC'
});
for (const link of listResponse.links || []) {
console.log(`${link.name}: ${link.shortlink}`);
}
// Get specific link details
const linkResponse = await linksApi.linksServiceGet({
id: 'your-link-uuid',
include: ['tags', 'qrcodeSignedUrl']
});
// Update link
await linksApi.linksServiceUpdate({
id: linkResponse.link?.id,
updateLinkRequest: {
name: 'Updated Campaign Name',
tags: ['marketing', 'q2-2025']
}
});
// Delete link
await linksApi.linksServiceDelete({
id: linkResponse.link?.id
});
Bulk link creation
Efficiently create multiple links in one API call:
import { Configuration, LinksApi } from 'linkbreakers';
const config = new Configuration({
accessToken: process.env.LINKBREAKERS_SECRET_KEY,
basePath: 'https://api.linkbreakers.com',
});
const linksApi = new LinksApi(config);
const response = await linksApi.linksServiceCreateBulk({
createBulkLinksRequest: {
links: [
{
destination: 'https://example.com/product-1',
name: 'Product 1',
tags: ['catalog'],
metadata: { sku: 'PROD-001' }
},
{
destination: 'https://example.com/product-2',
name: 'Product 2',
tags: ['catalog'],
metadata: { sku: 'PROD-002' }
}
]
}
});
console.log(`Created ${response.links?.length} links`);
Accessing analytics
Retrieve events and metrics (requires secret key):
import { Configuration, EventsApi, MetricsApi } from 'linkbreakers';
const config = new Configuration({
accessToken: process.env.LINKBREAKERS_SECRET_KEY,
basePath: 'https://api.linkbreakers.com',
});
const eventsApi = new EventsApi(config);
const metricsApi = new MetricsApi(config);
// Get events for a specific link
const endDate = new Date();
const startDate = new Date();
startDate.setDate(startDate.getDate() - 30);
const eventsResponse = await eventsApi.eventsServiceList({
linkId: 'your-link-uuid',
startDate: startDate.toISOString(),
endDate: endDate.toISOString(),
pageSize: 100,
include: ['visitor', 'device']
});
// Get workspace metrics
const metrics = await metricsApi.metricsServiceGetWorkspaceMetrics();
console.log('Total clicks:', metrics.totalClicks);
Framework integration examples
Next.js (App Router)
Frontend visitor tracking:
// app/components/visitor-tracker.tsx
'use client';
import { Configuration, VisitorsApi } from 'linkbreakers';
import { useEffect } from 'react';
export function VisitorTracker({ userEmail }: { userEmail: string }) {
useEffect(() => {
const config = new Configuration({
accessToken: process.env.NEXT_PUBLIC_LINKBREAKERS_PK, // Publishable JWT
basePath: 'https://api.linkbreakers.com',
});
const visitorsApi = new VisitorsApi(config);
const lbid = new URLSearchParams(window.location.search).get('lbid');
if (lbid && userEmail) {
visitorsApi.visitorsServiceIdentify({
identifyRequest: {
lbid,
visitor: {
data: { '$email': userEmail }
}
}
});
}
}, [userEmail]);
return null;
}
Backend link creation:
// app/api/create-link/route.ts
import { Configuration, LinksApi } from 'linkbreakers';
import { NextResponse } from 'next/server';
export async function POST(request: Request) {
const config = new Configuration({
accessToken: process.env.LINKBREAKERS_SECRET_KEY, // Secret JWT
basePath: 'https://api.linkbreakers.com',
});
const linksApi = new LinksApi(config);
const { destination, name } = await request.json();
const response = await linksApi.linksServiceCreate({
createLinkRequest: { destination, name }
});
return NextResponse.json({ shortlink: response.link?.shortlink });
}
Node.js / Express
import express from 'express';
import { Configuration, LinksApi } from 'linkbreakers';
const app = express();
app.use(express.json());
const config = new Configuration({
accessToken: process.env.LINKBREAKERS_SECRET_KEY,
basePath: 'https://api.linkbreakers.com',
});
app.post('/api/create-link', async (req, res) => {
const linksApi = new LinksApi(config);
const response = await linksApi.linksServiceCreate({
createLinkRequest: {
destination: req.body.destination,
name: req.body.name
}
});
res.json({ shortlink: response.link?.shortlink });
});
app.listen(3000);
Security best practices
Environment variables
Store both key types in environment variables:
# .env file
LINKBREAKERS_SECRET_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3b3Jrc3BhY2VfaWQiOiIxMjM0IiwidHlwZSI6InNlY3JldCJ9...
NEXT_PUBLIC_LINKBREAKERS_PK=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3b3Jrc3BhY2VfaWQiOiIxMjM0IiwidHlwZSI6InB1Ymxpc2hhYmxlIn0...
Next.js note: Prefix publishable keys with NEXT_PUBLIC_ to make them available in the browser.
Key usage matrix
| Operation | Publishable Key | Secret Key |
|---|---|---|
| Identify visitors | ✅ Yes | ✅ Yes |
| Update visitor profiles | ✅ Yes | ✅ Yes |
| Create links | ❌ No | ✅ Yes |
| Delete links | ❌ No | ✅ Yes |
| View analytics | ❌ No | ✅ Yes |
| Access workspace metrics | ❌ No | ✅ Yes |
Common security mistakes
❌ DON'T:
- Use secret keys in frontend code
- Commit keys to version control
- Share keys in screenshots or documentation
- Use production keys in development
✅ DO:
- Use publishable keys for all frontend operations
- Store secret keys in environment variables
- Rotate keys if accidentally exposed
- Use test mode keys for development (check JWT claims to identify test vs production)
Frequently asked questions
Can I use one key for both frontend and backend?
No. Always use publishable keys (with limited scopes) for frontend and secret keys (with full access) for backend. Publishable keys have restricted permissions encoded in the JWT and cannot create links or access sensitive data.
How do I enable conversion tracking to get LBID in URLs?
In your link settings, enable "Conversion Tracking" on the redirect workflow step. This appends ?lbid=... to destination URLs, enabling visitor attribution.
Does the SDK work in the browser?
Yes, but only use it with publishable keys. Never expose secret keys in client-side code.
How do I handle rate limits?
The SDK will throw errors if you exceed rate limits. Implement retry logic with exponential backoff for production applications.
Can I use this with TypeScript?
Yes! The SDK is written in TypeScript and includes full type definitions for autocomplete and type safety.
What about test mode?
Create test mode API keys from your dashboard. Test keys operate on isolated test data that won't affect production analytics. You can identify test vs production keys by decoding the JWT and checking the environment claim.
Sources
- Linkbreakers TypeScript SDK GitHub Repository
- Linkbreakers TypeScript SDK on npm
- What is LBID?
- Linkbreakers API Documentation
Last reviewed
This article was last reviewed on March 20, 2025.
About the Author
Laurent Schaffner
Founder & Engineer at Linkbreakers
Passionate about building tools that help businesses track and optimize their digital marketing efforts. Laurent founded Linkbreakers to make QR code analytics accessible and actionable for companies of all sizes.
Related Articles
How to use the Linkbreakers API
Complete guide to integrating with the Linkbreakers API - create QR codes, manage links, customize designs, track analytics, and automate workflows programmatically.
Analytics API
Access comprehensive QR code and visitor analytics through the Linkbreakers API. Learn how to retrieve campaign performance data, visitor insights, and engagement metrics programmatically for business intelligence integration.
How to integrate Linkbreakers with existing tech stack
Integrate Linkbreakers with your CRM, marketing automation, analytics platforms, and business systems through APIs, webhooks, and direct integrations. Learn best practices for seamless tech stack integration.
On this page
Need more help?
Can't find what you're looking for? Get in touch with our support team.
Contact Support