Appearance
Advanced Examples
Complex use cases and patterns for QR Code API.
Dynamic QR Codes with Analytics
Track how many people scan your QR codes:
javascript
class QRTracker {
constructor(apiKey) {
this.apiKey = apiKey;
this.baseUrl = 'https://www.qrcodeapi.io/api';
}
async createTrackedQR(name, targetUrl, options = {}) {
// 1. Create a dynamic link
const linkRes = await fetch(`${this.baseUrl}/links`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ name, targetUrl })
});
const link = await linkRes.json();
// 2. Generate QR code for the short URL
const params = new URLSearchParams({
data: `https://www.qrcodeapi.io/r/${link.shortCode}`,
size: options.size || 400,
color: options.color || '000000',
background: options.background || 'ffffff',
errorCorrection: options.logo ? 'H' : 'M'
});
if (options.logo) {
params.append('logo', options.logo);
}
const qrRes = await fetch(`${this.baseUrl}/generate?${params}`, {
headers: { 'Authorization': `Bearer ${this.apiKey}` }
});
return {
link,
qrBlob: await qrRes.blob(),
shortUrl: `https://www.qrcodeapi.io/r/${link.shortCode}`
};
}
async getStats(linkId) {
const res = await fetch(
`${this.baseUrl}/analytics?linkId=${linkId}`,
{ headers: { 'Authorization': `Bearer ${this.apiKey}` } }
);
return res.json();
}
}
// Usage
const tracker = new QRTracker(process.env.API_KEY);
const campaign = await tracker.createTrackedQR(
'Summer Sale 2024',
'https://shop.com/summer-sale',
{ size: 500, color: '22c55e' }
);
// Save the QR code
const buffer = Buffer.from(await campaign.qrBlob.arrayBuffer());
fs.writeFileSync('summer-sale-qr.png', buffer);
// Later: check stats
const stats = await tracker.getStats(campaign.link.id);
console.log(`Total scans: ${stats.analytics.totalScans}`);Batch Generation with Progress
Generate multiple QR codes with progress tracking:
javascript
async function batchGenerateWithProgress(items, options = {}) {
const results = [];
const total = items.length;
let completed = 0;
// Process in parallel batches of 5
const batchSize = 5;
for (let i = 0; i < total; i += batchSize) {
const batch = items.slice(i, i + batchSize);
const promises = batch.map(async (item) => {
const params = new URLSearchParams({
data: item.data,
size: options.size || 300,
color: options.color || '000000'
});
const response = await fetch(
`https://www.qrcodeapi.io/api/generate?${params}`,
{ headers: { 'Authorization': `Bearer ${API_KEY}` } }
);
completed++;
console.log(`Progress: ${completed}/${total} (${Math.round(completed/total*100)}%)`);
return {
...item,
blob: await response.blob()
};
});
results.push(...await Promise.all(promises));
}
return results;
}
// Usage
const products = [
{ id: 1, data: 'https://shop.com/product/1' },
{ id: 2, data: 'https://shop.com/product/2' },
// ... more products
];
const qrCodes = await batchGenerateWithProgress(products, {
size: 400,
color: '1e40af'
});QR Code with Retry Logic
Handle rate limits and errors gracefully:
javascript
class ResilientQRGenerator {
constructor(apiKey, maxRetries = 3) {
this.apiKey = apiKey;
this.maxRetries = maxRetries;
}
async generate(data, options = {}, attempt = 1) {
try {
const params = new URLSearchParams({ data, ...options });
const response = await fetch(
`https://www.qrcodeapi.io/api/generate?${params}`,
{ headers: { 'Authorization': `Bearer ${this.apiKey}` } }
);
if (response.status === 429) {
const error = await response.json();
const waitTime = error.retryAfter || Math.pow(2, attempt);
if (attempt < this.maxRetries) {
console.log(`Rate limited. Waiting ${waitTime}s...`);
await this.sleep(waitTime * 1000);
return this.generate(data, options, attempt + 1);
}
throw new Error('Max retries exceeded');
}
if (!response.ok) {
const error = await response.json();
throw new Error(error.message);
}
return response.blob();
} catch (error) {
if (attempt < this.maxRetries && this.isRetryable(error)) {
const waitTime = Math.pow(2, attempt);
console.log(`Error: ${error.message}. Retrying in ${waitTime}s...`);
await this.sleep(waitTime * 1000);
return this.generate(data, options, attempt + 1);
}
throw error;
}
}
isRetryable(error) {
return error.message.includes('network') ||
error.message.includes('timeout');
}
sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
}
// Usage
const generator = new ResilientQRGenerator(API_KEY);
const qr = await generator.generate('https://example.com', { size: 500 });Real-time QR Code Generator (React)
jsx
import { useState, useCallback, useEffect } from 'react';
import debounce from 'lodash/debounce';
function QRGenerator() {
const [data, setData] = useState('');
const [options, setOptions] = useState({
size: 300,
color: '000000',
background: 'ffffff'
});
const [qrUrl, setQrUrl] = useState('');
const [loading, setLoading] = useState(false);
const [error, setError] = useState('');
const generateQR = useCallback(
debounce(async (data, options) => {
if (!data) {
setQrUrl('');
return;
}
setLoading(true);
setError('');
try {
const params = new URLSearchParams({
data,
...options
});
const response = await fetch(
`https://www.qrcodeapi.io/api/generate?${params}`,
{ headers: { 'Authorization': `Bearer ${API_KEY}` } }
);
if (!response.ok) {
const err = await response.json();
throw new Error(err.message);
}
const blob = await response.blob();
setQrUrl(URL.createObjectURL(blob));
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
}, 300),
[]
);
useEffect(() => {
generateQR(data, options);
}, [data, options, generateQR]);
return (
<div className="qr-generator">
<div className="controls">
<input
type="text"
value={data}
onChange={e => setData(e.target.value)}
placeholder="Enter text or URL"
/>
<label>
Size:
<input
type="range"
min="100"
max="1000"
value={options.size}
onChange={e => setOptions({...options, size: e.target.value})}
/>
{options.size}px
</label>
<label>
Color:
<input
type="color"
value={`#${options.color}`}
onChange={e => setOptions({...options, color: e.target.value.slice(1)})}
/>
</label>
<label>
Background:
<input
type="color"
value={`#${options.background}`}
onChange={e => setOptions({...options, background: e.target.value.slice(1)})}
/>
</label>
</div>
<div className="preview">
{loading && <div className="spinner">Loading...</div>}
{error && <div className="error">{error}</div>}
{qrUrl && !loading && (
<img src={qrUrl} alt="QR Code" />
)}
</div>
</div>
);
}QR Code PDF Generator
Generate a PDF with multiple QR codes:
javascript
import { PDFDocument, rgb } from 'pdf-lib';
async function generateQRPDF(items) {
const pdfDoc = await PDFDocument.create();
const page = pdfDoc.addPage([612, 792]); // Letter size
const qrSize = 150;
const margin = 50;
const cols = 3;
for (let i = 0; i < items.length; i++) {
// Generate QR code
const response = await fetch(
`https://www.qrcodeapi.io/api/generate?data=${encodeURIComponent(items[i].data)}&size=${qrSize}`,
{ headers: { 'Authorization': `Bearer ${API_KEY}` } }
);
const imageBytes = await response.arrayBuffer();
const image = await pdfDoc.embedPng(imageBytes);
// Calculate position
const col = i % cols;
const row = Math.floor(i / cols);
const x = margin + col * (qrSize + margin);
const y = 792 - margin - (row + 1) * (qrSize + 50);
// Draw QR code
page.drawImage(image, {
x,
y,
width: qrSize,
height: qrSize
});
// Add label
page.drawText(items[i].label, {
x: x + qrSize / 2 - items[i].label.length * 3,
y: y - 15,
size: 10
});
}
const pdfBytes = await pdfDoc.save();
return pdfBytes;
}
// Usage
const items = [
{ data: 'https://shop.com/p/1', label: 'Product 1' },
{ data: 'https://shop.com/p/2', label: 'Product 2' },
{ data: 'https://shop.com/p/3', label: 'Product 3' },
];
const pdfBytes = await generateQRPDF(items);
fs.writeFileSync('qr-codes.pdf', pdfBytes);QR Code Caching Layer
Implement caching to reduce API calls:
javascript
const NodeCache = require('node-cache');
class CachedQRGenerator {
constructor(apiKey, ttlSeconds = 3600) {
this.apiKey = apiKey;
this.cache = new NodeCache({ stdTTL: ttlSeconds });
}
getCacheKey(data, options) {
return `qr:${data}:${JSON.stringify(options)}`;
}
async generate(data, options = {}) {
const cacheKey = this.getCacheKey(data, options);
// Check cache
const cached = this.cache.get(cacheKey);
if (cached) {
console.log('Cache hit');
return cached;
}
console.log('Cache miss, generating...');
// Generate new QR code
const params = new URLSearchParams({ data, ...options });
const response = await fetch(
`https://www.qrcodeapi.io/api/generate?${params}`,
{ headers: { 'Authorization': `Bearer ${this.apiKey}` } }
);
const buffer = Buffer.from(await response.arrayBuffer());
// Store in cache
this.cache.set(cacheKey, buffer);
return buffer;
}
}
// Usage
const generator = new CachedQRGenerator(API_KEY);
// First call: cache miss, API call made
const qr1 = await generator.generate('https://example.com', { size: 300 });
// Second call: cache hit, no API call
const qr2 = await generator.generate('https://example.com', { size: 300 });Webhook Handler (Express)
Process real-time scan notifications:
javascript
const express = require('express');
const crypto = require('crypto');
const app = express();
// Store for deduplication
const processedEvents = new Set();
app.post('/webhooks/qr', express.raw({ type: 'application/json' }), async (req, res) => {
// Verify signature
const signature = req.headers['x-signature'];
const expectedSig = crypto
.createHmac('sha256', process.env.WEBHOOK_SECRET)
.update(req.body)
.digest('hex');
if (signature !== expectedSig) {
return res.status(401).json({ error: 'Invalid signature' });
}
const event = JSON.parse(req.body);
// Deduplicate
if (processedEvents.has(event.id)) {
return res.json({ status: 'already_processed' });
}
processedEvents.add(event.id);
// Respond immediately
res.json({ received: true });
// Process asynchronously
try {
switch (event.type) {
case 'scan.created':
await handleScan(event.data);
break;
case 'link.updated':
await handleLinkUpdate(event.data);
break;
}
} catch (error) {
console.error('Webhook processing error:', error);
}
});
async function handleScan(data) {
console.log(`New scan on ${data.shortCode} from ${data.scan.country}`);
// Send notification, update analytics dashboard, etc.
await sendSlackNotification(`🔔 QR scan from ${data.scan.city}, ${data.scan.country}`);
}
async function handleLinkUpdate(data) {
console.log(`Link ${data.link.shortCode} updated to ${data.link.targetUrl}`);
}
app.listen(3000);Related
- Basic Examples - Simple examples
- Framework Integrations - React, Vue, etc.
- Webhooks Guide - Real-time notifications