QR codes seem simple until you need them at scale. Here's a deep dive into dynamic vs static QR codes, analytics, and best practices for production use.
Static vs Dynamic: The Core Difference
Static QR codes encode the destination URL directly in the pattern. Once generated, the destination can't change.
Dynamic QR codes encode a short redirect URL. The destination can be changed anytime without reprinting the QR code.
For product packaging, marketing materials, or anything printed: always use dynamic.
Generating QR Codes via API
import requests
# Static QR code
resp = requests.get("https://api.lazy-mac.com/qr-code/generate", params={
"data": "https://your-site.com/product/123",
"size": 300,
"format": "png",
"error_correction": "H" # High: survives 30% damage
})
# Returns PNG binary
# Dynamic QR code with analytics
resp = requests.post("https://api.lazy-mac.com/qr-code/dynamic", json={
"destination": "https://your-site.com/product/123",
"campaign": "print-q1-2026",
"track_scans": True
})
data = resp.json()
print(data['qr_url']) # The QR code image URL
print(data['short_url']) # The encoded short redirect
print(data['tracking_id']) # Use this to query scan analytics
Error Correction Levels
| Level | Data Recovery | Size Increase | Use Case |
|---|---|---|---|
| L | 7% | Minimal | Clean digital displays |
| M | 15% | Small | General use |
| Q | 25% | Medium | Industrial/outdoor |
| H | 30% | Large | Printed materials, stickers |
Always use H for anything printed. Scratches, folds, and dirt happen.
Best Practices
- Minimum size: 2cm × 2cm for phone scanning. Larger for distance scanning.
- Quiet zone: Leave white border of at least 4 modules around the code.
- Contrast: Black on white is most reliable. Colored QR codes need testing.
- Test before printing: Scan with 3 different phones before finalizing.
- Dynamic for campaigns: Track scan counts, locations, and time-of-day.
Top comments (0)