Complete guide to integrating with the Linkbreakers API - create QR codes, manage links, customize designs, track analytics, and automate workflows programmatically.
Building QR code functionality shouldn't mean starting from scratch. The Linkbreakers API transforms complex QR code operations into simple HTTP requests that integrate seamlessly with any technology stack.
Whether you're automating marketing campaigns, building customer-facing tools, or integrating QR codes into existing products, our REST API provides the building blocks you need. Think of it as having Linkbreakers' full feature set available as programmable components.
Every API endpoint returns consistent JSON responses with comprehensive error handling. Authentication uses standard bearer tokens. Rate limits are generous enough for production workloads while preventing abuse.
Most constructions of Linkbreakers can be built via the Linkbreakers API. Full documentation is available at https://linkbreakers.com/help/api
Before making API calls, you'll need a workspace token that identifies your account and provides access to your resources. These tokens act like API keys but with better security and audit capabilities.
Navigate to Workspace tokens in your dashboard. Click "Create Token" and provide a descriptive name that identifies its purpose.
Common token names include:
The platform generates a JWT token that appears only once during creation. Store this token securely - you can't retrieve it again after the creation dialog closes.
Include your token in the Authorization header for every API request:
curl -H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
https://api.linkbreakers.com/v1/links
Tokens remain valid indefinitely unless explicitly revoked. However, you can monitor usage and revoke tokens through the dashboard if they're compromised or no longer needed.
Store tokens as environment variables rather than hardcoding them in source code. Use different tokens for different environments to limit blast radius if one gets compromised.
For production systems, consider rotating tokens periodically even if not compromised. The dashboard tracks token usage so you can verify expected activity patterns.
Links are the foundation of Linkbreakers functionality. Every QR code, short URL, or interactive workflow starts with a link resource that defines the destination and behavior.
Create a simple link with just a destination URL:
const response = await fetch('https://api.linkbreakers.com/v1/links', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_JWT_TOKEN',
'Content-Type': 'application/json'
},
body: JSON.stringify({
destination: 'https://example.com/landing-page',
name: 'Product Launch Campaign'
})
});
const { link } = await response.json();
console.log(`Created link: ${link.entrypoint}`);
This creates a link with an auto-generated shortlink that redirects to your destination. The response includes the complete link object with generated fields like entrypoint and qrcode_signed_url.
Specify custom shortlinks for memorable URLs that reinforce your brand:
const brandedLink = await fetch('https://api.linkbreakers.com/v1/links', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_JWT_TOKEN',
'Content-Type': 'application/json'
},
body: JSON.stringify({
destination: 'https://example.com/special-offer',
name: 'Holiday Promotion',
shortlink: 'holiday-2024',
custom_domain_id: 'your-custom-domain-uuid'
})
});
Custom shortlinks must be unique within your workspace or custom domain. The platform validates availability and returns errors for conflicts.
Include metadata, tags, and lead scoring parameters for sophisticated campaign management:
const advancedLink = await fetch('https://api.linkbreakers.com/v1/links', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_JWT_TOKEN',
'Content-Type': 'application/json'
},
body: JSON.stringify({
destination: 'https://example.com/webinar-registration',
fallback_destination: 'https://example.com/webinar-info',
name: 'Q4 Webinar Series',
shortlink: 'webinar-q4',
metadata: {
campaign: 'Q4-2024',
channel: 'email',
audience: 'enterprise'
},
tags: ['webinar', 'lead-gen', 'q4-campaign'],
lead_goal_definition: 'Generate qualified leads for enterprise sales',
lead_target_definition: 'Decision makers with 100+ employees'
})
});
Metadata accepts string key-value pairs with a maximum of 50 keys. Tags help organize campaigns and enable filtered dashboard views. Lead scoring parameters train the AI to identify high-value prospects.
Fetch existing links with optional relationship data:
// Get a specific link with related data
const linkResponse = await fetch(
`https://api.linkbreakers.com/v1/links/${linkId}?include=qrcodeDesign,tags,customDomain`,
{
headers: {
'Authorization': 'Bearer YOUR_JWT_TOKEN'
}
}
);
// List all links with pagination
const linksResponse = await fetch(
'https://api.linkbreakers.com/v1/links?page_size=50&include=qrcodeDesign',
{
headers: {
'Authorization': 'Bearer YOUR_JWT_TOKEN'
}
}
);
const { links, next_page_token } = await linksResponse.json();
The include parameter loads related resources in a single request, reducing the number of API calls needed for complete data.
Link updates use PATCH requests to modify specific fields without affecting others:
const updateResponse = await fetch(`https://api.linkbreakers.com/v1/links/${linkId}`, {
method: 'PATCH',
headers: {
'Authorization': 'Bearer YOUR_JWT_TOKEN',
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'Updated Campaign Name',
tags: ['updated', 'active', 'priority']
})
});
QR code designs control the visual appearance of generated codes, from colors and shapes to logos and export formats. The design system separates visual styling from link functionality.
Generate QR code designs with specific branding requirements:
// Upload logo as base64 for central image
const logoBase64 = await fileToBase64(logoFile);
const designResponse = await fetch('https://api.linkbreakers.com/v1/qrcode-designs', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_JWT_TOKEN',
'Content-Type': 'application/json'
},
body: JSON.stringify({
output_file_format: 'OUTPUT_FILE_FORMAT_PNG',
width: 500,
height: 500,
central_image_data: logoBase64,
central_image_size: 0.3,
dots_options: {
color: '#2563eb',
type: 'rounded'
},
corners_square_options: {
color: '#1e40af',
type: 'extra-rounded'
},
background_options: {
color: '#ffffff'
},
shape: 'SHAPE_SQUARE',
error_correction_level: 'M',
hide_background_dots: true
})
});
const { qrcode_design } = await designResponse.json();
Design options provide granular control over every visual element. Color options support hex codes or gradient definitions. Shape options include traditional squares or modern circular modules.
Create sophisticated designs with gradient fills and custom styling:
const gradientDesign = {
dots_options: {
gradient: JSON.stringify({
type: 'linear',
rotation: 45,
colorStops: [
{ offset: 0, color: '#3b82f6' },
{ offset: 1, color: '#8b5cf6' }
]
}),
type: 'dots'
},
corners_square_options: {
color: '#1e293b',
type: 'square'
},
background_options: {
gradient: JSON.stringify({
type: 'radial',
colorStops: [
{ offset: 0, color: '#f8fafc' },
{ offset: 1, color: '#e2e8f0' }
]
})
}
};
Gradient definitions use the qr-code-styling library format for maximum compatibility. This enables sophisticated visual effects while maintaining scanning reliability.
Create reusable design templates for consistent branding across campaigns:
// Create a template design
const templateDesign = await fetch('https://api.linkbreakers.com/v1/qrcode-designs', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_JWT_TOKEN',
'Content-Type': 'application/json'
},
body: JSON.stringify({
// ... design specifications
})
});
// Apply template to new link
const linkWithTemplate = await fetch('https://api.linkbreakers.com/v1/links', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_JWT_TOKEN',
'Content-Type': 'application/json'
},
body: JSON.stringify({
destination: 'https://example.com',
name: 'Branded Campaign',
qrcode_design_id: templateDesign.qrcode_design.id
})
});
Design templates enable brand consistency across different team members and campaigns. Update template designs to refresh all associated QR codes simultaneously.
Event data provides insights into QR code performance, visitor behavior, and campaign effectiveness. The events API enables both real-time monitoring and historical analysis.
Query events with flexible filtering options:
const eventsResponse = await fetch(
'https://api.linkbreakers.com/v1/events/list?' +
new URLSearchParams({
start_date: '2024-01-01T00:00:00Z',
end_date: '2024-01-31T23:59:59Z',
link_id: 'specific-link-uuid',
page_size: '100',
include: 'visitor,device,link,leadScore'
}),
{
headers: {
'Authorization': 'Bearer YOUR_JWT_TOKEN'
}
}
);
const { events, total_count, has_more, next_page_token } = await eventsResponse.json();
Events include comprehensive metadata about each scan: device information, geographic location, visitor profiles, and lead scores. Filter by date ranges, specific links, or other criteria.
Export large datasets for analysis in spreadsheet applications or business intelligence tools:
const csvResponse = await fetch(
'https://api.linkbreakers.com/v1/events/list?' +
new URLSearchParams({
start_date: '2024-01-01T00:00:00Z',
end_date: '2024-01-31T23:59:59Z',
response_format: 'RESPONSE_FORMAT_CSV'
}),
{
headers: {
'Authorization': 'Bearer YOUR_JWT_TOKEN'
}
}
);
const csvData = await csvResponse.text();
// Save to file or process directly
CSV exports include all event fields with human-readable headers. Large exports use pagination to manage memory usage and transfer times.
For real-time analytics or automation, consider using webhooks instead of polling the events API. Webhooks deliver events as they occur with lower latency.
Create multiple links efficiently using concurrent requests:
const destinations = [
'https://example.com/product1',
'https://example.com/product2',
'https://example.com/product3'
];
const linkPromises = destinations.map(async (destination, index) => {
return fetch('https://api.linkbreakers.com/v1/links', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_JWT_TOKEN',
'Content-Type': 'application/json'
},
body: JSON.stringify({
destination,
name: `Product ${index + 1} Campaign`,
tags: ['bulk-created', 'product-campaign']
})
});
});
const responses = await Promise.all(linkPromises);
const links = await Promise.all(
responses.map(response => response.json())
);
Rate limits accommodate reasonable bulk operations. For very large batches, implement exponential backoff and respect rate limit headers.
Generate personalized QR codes based on customer data or campaign parameters:
const customers = [
{ id: 'cust1', name: 'Acme Corp', tier: 'enterprise' },
{ id: 'cust2', name: 'Beta LLC', tier: 'professional' }
];
const personalizedLinks = await Promise.all(
customers.map(async customer => {
return fetch('https://api.linkbreakers.com/v1/links', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_JWT_TOKEN',
'Content-Type': 'application/json'
},
body: JSON.stringify({
destination: `https://example.com/welcome?customer=${customer.id}`,
name: `Welcome - ${customer.name}`,
shortlink: `welcome-${customer.id}`,
metadata: {
customer_id: customer.id,
customer_name: customer.name,
tier: customer.tier
},
tags: ['personalized', customer.tier]
})
});
})
);
Personalized campaigns increase engagement by delivering relevant experiences. Use metadata fields to track personalization parameters for analysis.
Connect Linkbreakers with existing marketing tools using webhook notifications:
// Configure webhook endpoint to receive events
const webhookResponse = await fetch('https://api.linkbreakers.com/v1/webhooks', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_JWT_TOKEN',
'Content-Type': 'application/json'
},
body: JSON.stringify({
url: 'https://your-system.com/linkbreakers-webhook',
events: ['link.scanned', 'form.submitted'],
active: true
})
});
// Process webhook events in your system
app.post('/linkbreakers-webhook', (req, res) => {
const { event_type, data } = req.body;
switch (event_type) {
case 'link.scanned':
// Trigger marketing automation
await addToEmailSequence(data.visitor.email);
break;
case 'form.submitted':
// Add to CRM
await createCRMLead(data.form_responses);
break;
}
res.status(200).send('OK');
});
Webhooks enable real-time integration with CRM systems, email platforms, and analytics tools. Configure multiple webhooks for different event types or destinations.
The API returns structured error information for troubleshooting:
try {
const response = await fetch('https://api.linkbreakers.com/v1/links', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_JWT_TOKEN',
'Content-Type': 'application/json'
},
body: JSON.stringify({
destination: 'invalid-url'
})
});
if (!response.ok) {
const errorData = await response.json();
console.error('API Error:', errorData.message);
console.error('Error Code:', errorData.code);
console.error('Details:', errorData.details);
}
} catch (error) {
console.error('Network Error:', error.message);
}
Error responses include HTTP status codes, error messages, and contextual details. Common error codes include validation failures (400), authentication issues (401), and rate limits (429).
Implement exponential backoff for resilient integrations:
async function apiCallWithRetry(url, options, maxRetries = 3) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
try {
const response = await fetch(url, options);
if (response.status === 429) {
// Rate limited - wait and retry
const retryAfter = response.headers.get('Retry-After') || Math.pow(2, attempt);
await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
continue;
}
return response;
} catch (error) {
if (attempt === maxRetries) throw error;
// Exponential backoff for network errors
await new Promise(resolve =>
setTimeout(resolve, Math.pow(2, attempt) * 1000)
);
}
}
}
Rate limits are per-workspace and reset every minute. Respect Retry-After headers for optimal performance. Most applications won't hit rate limits with normal usage patterns.
Validate data before API calls to catch issues early:
function validateLinkData(linkData) {
const errors = [];
if (!linkData.destination) {
errors.push('Destination is required');
} else if (!isValidURL(linkData.destination)) {
errors.push('Destination must be a valid URL');
}
if (linkData.metadata && Object.keys(linkData.metadata).length > 50) {
errors.push('Maximum 50 metadata keys allowed');
}
if (linkData.shortlink && !/^[a-zA-Z0-9_-]+$/.test(linkData.shortlink)) {
errors.push('Shortlink contains invalid characters');
}
return errors;
}
// Use before API calls
const validationErrors = validateLinkData(linkData);
if (validationErrors.length > 0) {
console.error('Validation errors:', validationErrors);
return;
}
Client-side validation prevents unnecessary API calls and provides immediate feedback. However, always handle server-side validation errors as the authoritative source.
const express = require('express');
const fetch = require('node-fetch');
const app = express();
app.use(express.json());
const LINKBREAKERS_TOKEN = process.env.LINKBREAKERS_TOKEN;
const API_BASE = 'https://api.linkbreakers.com/v1';
// Create QR code endpoint
app.post('/create-qr', async (req, res) => {
try {
const { destination, name } = req.body;
const response = await fetch(`${API_BASE}/links`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${LINKBREAKERS_TOKEN}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ destination, name })
});
if (!response.ok) {
throw new Error(`API error: ${response.status}`);
}
const { link } = await response.json();
res.json({
qr_url: link.qrcode_signed_url,
short_url: link.entrypoint
});
} catch (error) {
res.status(500).json({ error: error.message });
}
});
import requests
import os
from flask import Flask, request, jsonify
app = Flask(__name__)
LINKBREAKERS_TOKEN = os.environ['LINKBREAKERS_TOKEN']
API_BASE = 'https://api.linkbreakers.com/v1'
@app.route('/create-qr', methods=['POST'])
def create_qr():
try:
data = request.json
response = requests.post(
f'{API_BASE}/links',
headers={
'Authorization': f'Bearer {LINKBREAKERS_TOKEN}',
'Content-Type': 'application/json'
},
json={
'destination': data['destination'],
'name': data['name']
}
)
response.raise_for_status()
link = response.json()['link']
return jsonify({
'qr_url': link['qrcode_signed_url'],
'short_url': link['entrypoint']
})
except requests.exceptions.RequestException as e:
return jsonify({'error': str(e)}), 500
import { useState } from 'react';
function QRCodeGenerator() {
const [formData, setFormData] = useState({ destination: '', name: '' });
const [qrCode, setQrCode] = useState(null);
const [loading, setLoading] = useState(false);
const handleSubmit = async (e) => {
e.preventDefault();
setLoading(true);
try {
const response = await fetch('/api/create-qr', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(formData)
});
if (!response.ok) throw new Error('Failed to create QR code');
const result = await response.json();
setQrCode(result);
} catch (error) {
console.error('Error:', error);
} finally {
setLoading(false);
}
};
return (
<form onSubmit={handleSubmit}>
<input
type="url"
placeholder="Destination URL"
value={formData.destination}
onChange={(e) => setFormData({...formData, destination: e.target.value})}
required
/>
<input
type="text"
placeholder="Campaign Name"
value={formData.name}
onChange={(e) => setFormData({...formData, name: e.target.value})}
required
/>
<button type="submit" disabled={loading}>
{loading ? 'Creating...' : 'Create QR Code'}
</button>
{qrCode && (
<div>
<img src={qrCode.qr_url} alt="Generated QR Code" />
<p>Short URL: <a href={qrCode.short_url}>{qrCode.short_url}</a></p>
</div>
)}
</form>
);
}
Test endpoints quickly using curl commands:
# Create a test link
curl -X POST https://api.linkbreakers.com/v1/links \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"destination": "https://example.com",
"name": "Test Link"
}'
# Get link details
curl -H "Authorization: Bearer YOUR_TOKEN" \
https://api.linkbreakers.com/v1/links/LINK_UUID
# List recent events
curl -H "Authorization: Bearer YOUR_TOKEN" \
"https://api.linkbreakers.com/v1/events/list?page_size=10"
Create Postman collections for team API testing:
api_base_url and auth_tokenUse environment variables for configuration:
// .env file
LINKBREAKERS_TOKEN=your_development_token
LINKBREAKERS_API_BASE=https://api.linkbreakers.com/v1
NODE_ENV=development
// Configuration
const config = {
token: process.env.LINKBREAKERS_TOKEN,
apiBase: process.env.LINKBREAKERS_API_BASE,
isDevelopment: process.env.NODE_ENV === 'development'
};
Separate development and production tokens to prevent accidental data mixing.
The API allows 1000 requests per minute per workspace token. Rate limit headers in responses show current usage and reset times.
No, QR codes are generated as part of link creation. However, you can create links with the sole purpose of generating QR codes and ignore the shortlink functionality.
Webhook payloads include signatures for verification. Use the shared secret from your webhook configuration to validate incoming requests.
Deleting a link immediately stops QR code functionality. Existing QR code images continue working until their signed URLs expire, but scanning will show errors.
Yes, update link destinations through the API. Existing QR codes automatically redirect to new destinations without physical regeneration.
Use workflow integration to create custom conversion events, or connect webhook data to your analytics platform for advanced tracking.
Use your regular workspace with test tokens and non-production destinations for safe testing. Mark test resources with tags for easy identification and cleanup.
Central images have a 3MB file size limit. Use optimized PNG or JPEG formats for best results. The API automatically handles image processing and optimization.
The Linkbreakers API transforms complex QR code operations into straightforward HTTP requests that integrate with any development workflow. Start with basic link creation, then explore advanced features like custom designs and webhook integration as your needs evolve.
Focus on building reliable error handling and respecting rate limits. The API grows with your requirements while maintaining simplicity for routine operations.
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.
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.
Transform Linkbreakers into your own QR code platform with white label capabilities - custom domains, API integration, unlimited scaling, and complete branding control for resellers.
Can't find what you're looking for? Get in touch with our support team.
Contact Support