# Generate a QR code in Python

> Two options: call the keyless HTTP API with requests, which needs no dependencies beyond requests and no key, or use the qrcode library locally when you cannot make network calls. The API is better when you want styling and verification without pulling in an imaging stack.

Source: https://useqr.app/docs/developers/generate-a-qr-code-in-python · Last reviewed 2026-08-21 · UseQR is free forever, MIT licensed, no signup.

---

## Via the keyless API

No key, no SDK, no imaging dependencies:

```python
import requests
from urllib.parse import urlencode

def qr(data: str, path: str = "qr.png", **opts) -> None:
    params = {"data": data, "size": 1024, **opts}
    r = requests.get("https://useqr.app/api/v1/qr?" + urlencode(params), timeout=30)
    r.raise_for_status()
    with open(path, "wb") as f:
        f.write(r.content)

qr("https://example.com", "site.png", color="6366f1", ec="Q")
```

Errors come back as `application/problem+json` with a `fix` field:

```python
r = requests.get("https://useqr.app/api/v1/qr", params={"data": "x", "size": 9000})
if not r.ok:
    problem = r.json()
    print(problem["detail"])  # size 9000 is out of range
    print(problem["fix"])     # choose between 64 and 4096 pixels, e.g. size=1024
```

## Typed payloads without writing the format yourself

```python
requests.get("https://useqr.app/api/v1/wifi", params={
    "ssid": "CafeGuest", "password": "espresso", "security": "WPA",
})
```

The escaping rules for `WIFI:` (backslash before `;`, `:`, `,`, `\` and `"`) are handled
server-side, which is where most hand-rolled WiFi codes go wrong.

## Locally, with the qrcode library

When you cannot make network calls:

```python
import qrcode
from qrcode.constants import ERROR_CORRECT_Q

img = qrcode.make("https://example.com", error_correction=ERROR_CORRECT_Q, box_size=10, border=4)
img.save("qr.png")
```

`border=4` is the four-module quiet zone. The default is 4; do not reduce it.

For SVG output, which is what you want for print:

```python
import qrcode
import qrcode.image.svg

img = qrcode.make("https://example.com", image_factory=qrcode.image.svg.SvgPathImage)
img.save("qr.svg")
```

## Verify before you ship

Local libraries render and hope. If the code is styled or carries a logo, decode it back:

```python
from pyzbar.pyzbar import decode
from PIL import Image

result = decode(Image.open("qr.png"))
assert result and result[0].data.decode() == "https://example.com"
```

Or use the API's verify endpoint, which does the render-rasterise-decode loop for you:

```python
r = requests.get("https://useqr.app/api/v1/verify", params={"data": "hello", "color": "cccccc"})
print(r.json())
```

## Bulk

```python
r = requests.post("https://useqr.app/api/v1/qr/batch",
                  json={"items": [{"data": u} for u in urls[:100]]})
```

100 items per call. For larger runs, chunk and reuse a `requests.Session`.

## FAQ

### What is the easiest way to make a QR code in Python?
Call the keyless HTTP API with requests and write the bytes to a file — no key, no imaging dependencies. Use the qrcode library when you need to work offline.

### How do I make an SVG QR code in Python?
With the API, add format=svg. With the qrcode library, pass image_factory=qrcode.image.svg.SvgPathImage.

### What border should I use with the qrcode library?
The default of 4, which is the four-module quiet zone required by the specification. Reducing it is the most common cause of codes that will not scan.

### How do I check a Python-generated QR code actually scans?
Decode it back with pyzbar or zxing before shipping. Rendering a matrix does not prove the result is readable, especially with styling or a logo.

## Try it

- https://useqr.app/developers
