Skip to content

Python Guide

Complete guide to using QR Code API with Python.

Installation

bash
pip install requests

Or install our official SDK:

bash
pip install qrcodeapi

Quick Start

python
import requests
import os

API_KEY = os.environ.get('QRCODE_API_KEY')

def generate_qr(data, filename='qr.png'):
    response = requests.get(
        'https://www.qrcodeapi.io/api/generate',
        params={'data': data},
        headers={'Authorization': f'Bearer {API_KEY}'}
    )
    
    response.raise_for_status()
    
    with open(filename, 'wb') as f:
        f.write(response.content)
    
    print(f'Saved to {filename}')

# Usage
generate_qr('https://example.com')

Complete Examples

Generate with Custom Options

python
import requests

def generate_qr(data, **options):
    """Generate a QR code with custom options.
    
    Args:
        data: Content to encode
        size: Image size (50-2000)
        format: 'png' or 'svg'
        color: QR code color (hex without #)
        background: Background color (hex without #)
        error_correction: 'L', 'M', 'Q', or 'H'
        margin: Quiet zone margin (0-10)
    """
    params = {
        'data': data,
        'size': options.get('size', 300),
        'format': options.get('format', 'png'),
        'color': options.get('color', '000000'),
        'background': options.get('background', 'ffffff'),
        'errorCorrection': options.get('error_correction', 'M'),
        'margin': options.get('margin', 4)
    }
    
    response = requests.get(
        'https://www.qrcodeapi.io/api/generate',
        params=params,
        headers={'Authorization': f'Bearer {API_KEY}'}
    )
    
    response.raise_for_status()
    return response.content

# Usage
qr_image = generate_qr(
    'https://example.com',
    size=500,
    color='22c55e',
    format='svg'
)

with open('custom-qr.svg', 'wb') as f:
    f.write(qr_image)
python
import requests
import json

def create_dynamic_link(name, target_url):
    """Create a dynamic link that can be updated later."""
    response = requests.post(
        'https://www.qrcodeapi.io/api/links',
        json={'name': name, 'targetUrl': target_url},
        headers={
            'Authorization': f'Bearer {API_KEY}',
            'Content-Type': 'application/json'
        }
    )
    
    response.raise_for_status()
    return response.json()

# Usage
link = create_dynamic_link('My Campaign', 'https://example.com/landing')
print(f"Short URL: https://www.qrcodeapi.io/r/{link['shortCode']}")
print(f"Link ID: {link['id']}")
python
def update_dynamic_link(link_id, **updates):
    """Update a dynamic link's name or target URL."""
    payload = {}
    if 'name' in updates:
        payload['name'] = updates['name']
    if 'target_url' in updates:
        payload['targetUrl'] = updates['target_url']
    
    response = requests.put(
        f'https://www.qrcodeapi.io/api/links?id={link_id}',
        json=payload,
        headers={
            'Authorization': f'Bearer {API_KEY}',
            'Content-Type': 'application/json'
        }
    )
    
    response.raise_for_status()
    return response.json()

# Usage - Update the destination URL
update_dynamic_link(link['id'], target_url='https://example.com/new-landing')

Get Analytics

python
from datetime import datetime, timedelta

def get_analytics(link_id, start_date=None, end_date=None):
    """Get scan analytics for a dynamic link."""
    params = {'linkId': link_id}
    
    if start_date:
        params['startDate'] = start_date
    if end_date:
        params['endDate'] = end_date
    
    response = requests.get(
        'https://www.qrcodeapi.io/api/analytics',
        params=params,
        headers={'Authorization': f'Bearer {API_KEY}'}
    )
    
    response.raise_for_status()
    return response.json()

# Get last 30 days
end = datetime.now()
start = end - timedelta(days=30)

analytics = get_analytics(
    'your-link-id',
    start_date=start.strftime('%Y-%m-%d'),
    end_date=end.strftime('%Y-%m-%d')
)

print(f"Total scans: {analytics['analytics']['totalScans']}")
print(f"Unique scans: {analytics['analytics']['uniqueScans']}")

# Top countries
for country in analytics['analytics']['scansByCountry'][:5]:
    print(f"  {country['country']}: {country['scans']} scans")

Batch Generation

python
import requests
import zipfile
import io

def generate_batch(items, defaults=None):
    """Generate multiple QR codes and return a ZIP file."""
    payload = {'items': items}
    if defaults:
        payload['defaults'] = defaults
    
    response = requests.post(
        'https://www.qrcodeapi.io/api/batch',
        json=payload,
        headers={
            'Authorization': f'Bearer {API_KEY}',
            'Content-Type': 'application/json'
        }
    )
    
    response.raise_for_status()
    return response.content

# Usage
urls = [
    'https://example.com/product/1',
    'https://example.com/product/2',
    'https://example.com/product/3',
]

items = [
    {'data': url, 'filename': f'product-{i+1}.png'}
    for i, url in enumerate(urls)
]

zip_content = generate_batch(items, {'size': 500, 'color': '4F46E5'})

# Extract the ZIP
with zipfile.ZipFile(io.BytesIO(zip_content)) as z:
    z.extractall('qrcodes/')
    print(f"Extracted {len(z.namelist())} files")

Flask Web Application

python
from flask import Flask, request, Response, jsonify
import requests
import os

app = Flask(__name__)
API_KEY = os.environ.get('QRCODE_API_KEY')

@app.route('/api/qr')
def generate_qr():
    data = request.args.get('data')
    if not data:
        return jsonify({'error': 'data parameter required'}), 400
    
    params = {
        'data': data,
        'size': request.args.get('size', 300),
        'color': request.args.get('color', '000000'),
        'format': request.args.get('format', 'png')
    }
    
    response = requests.get(
        'https://www.qrcodeapi.io/api/generate',
        params=params,
        headers={'Authorization': f'Bearer {API_KEY}'}
    )
    
    if not response.ok:
        return jsonify(response.json()), response.status_code
    
    content_type = 'image/svg+xml' if params['format'] == 'svg' else 'image/png'
    return Response(response.content, mimetype=content_type)

if __name__ == '__main__':
    app.run(debug=True)

Django Integration

python
# views.py
from django.http import HttpResponse, JsonResponse
import requests
from django.conf import settings

def generate_qr(request):
    data = request.GET.get('data')
    if not data:
        return JsonResponse({'error': 'data parameter required'}, status=400)
    
    params = {
        'data': data,
        'size': request.GET.get('size', 300),
        'color': request.GET.get('color', '000000'),
        'format': request.GET.get('format', 'png')
    }
    
    response = requests.get(
        'https://www.qrcodeapi.io/api/generate',
        params=params,
        headers={'Authorization': f'Bearer {settings.QRCODE_API_KEY}'}
    )
    
    if not response.ok:
        return JsonResponse(response.json(), status=response.status_code)
    
    content_type = 'image/svg+xml' if params['format'] == 'svg' else 'image/png'
    return HttpResponse(response.content, content_type=content_type)

# urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('api/qr/', views.generate_qr, name='generate_qr'),
]

Error Handling

python
import requests
import time

def generate_qr_safe(data, retries=3):
    """Generate QR code with automatic retry on rate limit."""
    for attempt in range(retries):
        response = requests.get(
            'https://www.qrcodeapi.io/api/generate',
            params={'data': data},
            headers={'Authorization': f'Bearer {API_KEY}'}
        )
        
        if response.status_code == 429:
            error = response.json()
            wait_time = error.get('retryAfter', 60)
            print(f"Rate limited. Waiting {wait_time} seconds...")
            time.sleep(wait_time)
            continue
        
        if response.status_code == 401:
            raise Exception("Invalid API key")
        
        if response.status_code == 403:
            raise Exception("Feature requires plan upgrade")
        
        response.raise_for_status()
        return response.content
    
    raise Exception("Max retries exceeded")

Type Hints

python
from typing import Optional, TypedDict, List
from datetime import datetime

class QROptions(TypedDict, total=False):
    size: int
    format: str
    color: str
    background: str
    error_correction: str
    margin: int

class DynamicLink(TypedDict):
    id: str
    name: str
    shortCode: str
    targetUrl: str
    scanCount: int
    createdAt: str
    updatedAt: str

def generate_qr(data: str, options: Optional[QROptions] = None) -> bytes:
    """Generate a QR code."""
    ...

def create_link(name: str, target_url: str) -> DynamicLink:
    """Create a dynamic link."""
    ...