QR codes had a moment during the pandemic. Suddenly every restaurant had them, every business card, every vaccine certificate. And then... people kept using them.
Turns out encoding arbitrary data into a scannable square is genuinely useful. Not just for restaurant menus, but for onboarding, payments, authentication, inventory, and dozens of other applications you probably haven't thought of yet.
Let me show you what's actually possible.
More Than Just URLs
Most people think QR codes are for links. They are, but that's like saying email is for sending letters. Technically true, missing the point.
A QR code can encode any text up to about 4,000 characters. Which means it can encode:
- URLs — The obvious one
- WiFi credentials — Scan to connect, no password typing
- Contact cards (vCard) — Scan to add someone to your contacts
- Email addresses — Pre-populated compose window
- Phone numbers — Tap to call
- SMS templates — Pre-filled text messages
- Calendar events — Add to calendar with one scan
- Payment requests — Bitcoin addresses, PayPal links, etc.
- App deep links — Open directly to a specific screen
- Plain text — Any arbitrary data
The phone's camera app is surprisingly smart about these. Scan a WiFi QR code and it offers to connect. Scan a vCard and it offers to save the contact. The format matters.
Generating QR Codes
const response = await fetch('https://api.apiverve.com/v1/qrcodegenerator', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': 'YOUR_API_KEY'
},
body: JSON.stringify({
value: 'https://example.com',
format: 'png',
margin: 1
})
});
const { data } = await response.json();
console.log(data.downloadURL);
// Returns a URL to the generated PNG image
You send content, you get back a URL to a PNG. The URL is signed and temporary—download it or redirect users directly to it.
WiFi Sharing: The Hidden Killer Feature
This is criminally underused.
Every office, Airbnb, coffee shop, and guest room has the same problem: "What's the WiFi password?" People ask. You spell it out. They type it wrong. You spell it again. Everyone wastes time.
Or you print a QR code:
const wifiQR = await fetch('https://api.apiverve.com/v1/qrcodegenerator', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': process.env.APIVERVE_KEY
},
body: JSON.stringify({
value: 'WIFI:T:WPA;S:MyNetworkName;P:MySecurePassword123;;',
format: 'png'
})
});
The format is: WIFI:T:<security>;S:<ssid>;P:<password>;;
- Security types:
WPA,WPA2,WEP, ornopassfor open networks - SSID is your network name
- Password is... the password
Print it. Frame it. Stick it on the wall. Guests scan it with their phone camera and tap "Join Network." No spelling, no typos, no "wait is it a zero or an O?"
For Airbnb hosts: This is a 5-star review detail. Nobody mentions it explicitly, but smooth WiFi setup contributes to that "everything just worked" feeling.
For offices: Put one in the lobby, one in each conference room. Visitors connect in seconds instead of bothering the receptionist.
Contact Cards That Actually Get Saved
Business cards are dying, but the need to share contact info isn't.
The vCard format lets you encode a complete contact:
const vcard = `BEGIN:VCARD
VERSION:3.0
FN:Alex Johnson
ORG:TechStartup Inc.
TITLE:Senior Developer
TEL;TYPE=WORK:+1-555-123-4567
TEL;TYPE=CELL:+1-555-987-6543
EMAIL:alex@techstartup.io
URL:https://alexjohnson.dev
ADR;TYPE=WORK:;;123 Innovation Way;San Francisco;CA;94107;USA
END:VCARD`;
const contactQR = await fetch('https://api.apiverve.com/v1/qrcodegenerator', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': process.env.APIVERVE_KEY
},
body: JSON.stringify({
value: vcard,
format: 'png',
margin: 2
})
});
When someone scans this, their phone offers to add the contact with all fields pre-populated. No manual typing. No "send me your info" followups.
Conference speakers: Put your contact QR code on your last slide. Interested people scan it while you're still on stage. Way better conversion than "find me at the booth later."
Sales reps: Same idea. End every presentation with a scannable contact.
Email signatures: Some people include a tiny QR code in their email signature. Unusual, but memorable.
Event Tickets and Access Control
QR codes are already the standard for event tickets, but you might not realize how simple this is to implement yourself.
// Generate a ticket with a unique ID
const ticketId = 'EVT-2026-001234-A12';
const ticketUrl = `https://yoursite.com/tickets/verify/${ticketId}`;
const ticketQR = await generateQR(ticketUrl);
At the door, staff scan the QR code. Your server:
- Receives the verification request
- Looks up the ticket
- Checks if it's already been used
- Marks it as used
- Returns valid/invalid
No special hardware. Any phone with a camera works as a scanner. You can build a basic ticket system for a local event in an afternoon.
For recurring access (gyms, coworking spaces):
// Generate a member QR that includes member ID and a rotating token
const token = generateDailyToken(memberId, secretKey);
const accessCode = `ACCESS:${memberId}:${token}`;
The token rotates daily (or hourly, or per-visit), so a screenshot of someone else's QR code doesn't work for long.
Reading QR Codes
The QR Code Reader API goes the other direction—you upload an image containing a QR code, and it extracts the content.
const formData = new FormData();
formData.append('image', imageFile);
const response = await fetch('https://api.apiverve.com/v1/qrcodereader', {
method: 'POST',
headers: {
'x-api-key': 'YOUR_API_KEY'
},
body: formData
});
const { data } = await response.json();
console.log(data.text);
// Whatever was encoded in the QR code
When would you need this?
Document processing: Extracting order numbers, tracking codes, or IDs from uploaded documents or photos.
User uploads: "Upload a screenshot of your QR code" is easier for some users than typing a 20-character code.
Inventory systems: Take a photo of a shelf, extract all the product QR codes automatically.
Legacy systems: Reading QR codes from scanned paper documents or old photos.
Long URLs Are a Problem
QR codes have a physical constraint: more data = more complex pattern = harder to scan.
A simple URL like https://example.com generates a clean, easily-scannable QR code.
A URL like https://yoursite.com/campaigns/2026-spring-launch/landing-page?utm_source=billboard&utm_medium=outdoor&utm_campaign=spring2026&utm_content=downtown_location_a generates a dense mess that fails to scan from across a room.
Solution: Shorten first.
async function generateSmartQR(url) {
// Step 1: Shorten the URL
const shortRes = await fetch(
`https://api.apiverve.com/v1/urlshortener?url=${encodeURIComponent(url)}`,
{ headers: { 'x-api-key': process.env.APIVERVE_KEY } }
);
const shortUrl = (await shortRes.json()).data.shortenedURL;
// Step 2: Generate QR code with short URL
const qrRes = await fetch('https://api.apiverve.com/v1/qrcodegenerator', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': process.env.APIVERVE_KEY
},
body: JSON.stringify({
value: shortUrl,
format: 'png',
margin: 2
})
});
return (await qrRes.json()).data.downloadURL;
}
The URL Shortener API turns your tracking-parameter-laden URL into something like https://short.io/abc123. That generates a simpler, more scannable QR code.
Bonus: The short link gives you click tracking, which most QR code implementations lack.
Print Quality Matters
If you're printing QR codes for physical use (signs, product packaging, business cards), a few things matter:
Size: The minimum scannable size depends on distance. Rules of thumb:
- Business cards (scanning from hand distance): 0.8" x 0.8" minimum
- Table tents (arm's length): 1.5" x 1.5" minimum
- Posters (across a room): 4" x 4" or larger
- Billboards (really far away): Do the math, but think big
Margin: The white space around the QR code (called the "quiet zone") matters. Without it, the pattern bleeds into the background and scanners get confused. Use margin: 2 or higher for print.
Format: PNG is lossless—no compression artifacts to confuse scanners. Never use JPEG for QR codes.
Contrast: Black on white works best. Light patterns on dark backgrounds scan poorly. If you must use colors, keep high contrast.
Testing: Always scan your printed QR codes before mass production. Different phones have different cameras. Test on at least 3 devices, from a realistic distance.
Batch Generation
Need QR codes for 1,000 products? Don't do it one at a time in a loop.
async function generateBatch(items, concurrency = 10) {
const results = [];
// Process in chunks to respect rate limits
for (let i = 0; i < items.length; i += concurrency) {
const chunk = items.slice(i, i + concurrency);
const chunkResults = await Promise.all(
chunk.map(async (item) => {
const response = await fetch('https://api.apiverve.com/v1/qrcodegenerator', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': process.env.APIVERVE_KEY
},
body: JSON.stringify({
value: item.value,
format: 'png'
})
});
const { data } = await response.json();
return {
id: item.id,
value: item.value,
qrUrl: data.downloadURL
};
})
);
results.push(...chunkResults);
// Brief pause between chunks
if (i + concurrency < items.length) {
await new Promise(r => setTimeout(r, 100));
}
}
return results;
}
// Generate QR codes for all products
const products = [
{ id: 'SKU001', value: 'https://store.com/p/SKU001' },
{ id: 'SKU002', value: 'https://store.com/p/SKU002' },
// ... more products
];
const qrCodes = await generateBatch(products);
This processes 10 at a time in parallel, respects rate limits, and finishes way faster than sequential processing.
Real-World Implementation: Table Ordering
Let me walk through a complete example. You're building a restaurant ordering system. Each table gets a QR code that links to the menu.
async function setupTableQRCodes(restaurantId, tableCount) {
const tables = [];
for (let tableNum = 1; tableNum <= tableCount; tableNum++) {
// Each table gets a unique URL with the table number
const menuUrl = `https://order.yourrestaurant.com/${restaurantId}/table/${tableNum}`;
const response = await fetch('https://api.apiverve.com/v1/qrcodegenerator', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': process.env.APIVERVE_KEY
},
body: JSON.stringify({
value: menuUrl,
format: 'png',
margin: 2
})
});
const { data } = await response.json();
tables.push({
tableNumber: tableNum,
menuUrl,
qrCodeUrl: data.downloadURL,
printUrl: `${data.downloadURL}&download=true` // For downloading
});
}
return tables;
}
// Generate codes for 20 tables
const tables = await setupTableQRCodes('acme-diner', 20);
// Now you have URLs for each table's QR code
// Print them on table tents or laminated cards
When a customer scans the QR code:
- They hit your ordering page
- The URL tells you which table they're at
- No asking "what table are you?" at checkout
- Kitchen knows exactly where to deliver
QR codes are bridges between physical and digital. They turn "type this complicated URL" into "point your camera here." They turn "what's the WiFi password?" into a one-tap connection.
The QR Code Generator and QR Code Reader handle the encoding and decoding. You focus on what the codes actually do.
Get your API key and start generating. The free tier is plenty to prototype whatever you're building.
Originally published at APIVerve Blog
Top comments (0)