← Back to blog
AI & Automation3 min read

Automating QR codes with Python: Library or REST API?

Bild von Unsplash

What a Python library can do

If you want to generate QR codes with Python, you will find several free libraries. They turn text into an image, often also an SVG, locally and without a service. This is exactly right for labels with serial numbers, internal documents, or Wi-Fi access.

Where static images reach their limits

A code generated this way is static; the content is embedded in the pattern. If the target changes due to a relaunch, a typo is only noticed after printing, or you want to know how often it is scanned, it will not help. For this, there are dynamic codes: Same-QR stores the target behind a short, constant address, counts scans, and checks nightly whether each target is reachable.

Dynamic codes via REST API

The API is located at https://sameqr.com/api/v1. In the dashboard under Account, create a key under "Access for CLI, scripts and agents", select "read + write" for creation, and set it as the environment variable SAMEQR_API_KEY. This example uses only the standard library:

import json, os, urllib.request

API = "https://sameqr.com/api/v1"
KEY = os.environ["SAMEQR_API_KEY"]

def rufe(methode, weg, daten=None):
    req = urllib.request.Request(
        API + weg, method=methode,
        data=json.dumps(daten).encode() if daten else None,
        headers={"Authorization": f"Bearer {KEY}", "Content-Type": "application/json"})
    with urllib.request.urlopen(req) as r:
        return json.load(r)

code = rufe("POST", "/qr", {"name": "Anleitung Modell A", "targetUrl": "https://example.com/anleitung-a"})
print(code["id"])

If the API returns an error, urlopen raises an exception. The content always contains an error object with status, code, and message. Evaluate it instead of letting the script run blindly.

A workflow from practice

A manufacturer prints a code for instructions on each package:

  • The script reads the product list from a CSV file.
  • For each new product, it creates a code and remembers its identifier alongside the article number.
  • If a new version of the instructions appears, it changes the target via PATCH to /qr/<id>. This requires a "full" key and the X-Confirm header with the read status.
  • A second script with a read key retrieves the scan counts once a month.

Plan the limits: maximum 10 target changes per hour and 30 per day via the API, 120 enquiries per minute per key, 60 per hour in the Free plan, 300 in Start, 1,000 in Pro, and 5,000 in Agentur. On 429, wait for the seconds specified in the Retry-After header.

Keep keys secure in the script

  • Never write the key into the .py file; read it from the environment instead.
  • For scripts that only read, use a "read only" key.
  • Each script should have its own key with a descriptive name and appropriate lifespan.

Conclusion: why Same-QR

For static codes, a library is sufficient. Once printing is involved, Same-QR is the better foundation: a lightweight REST API in every plan, clear error messages, protection against parallel overwrites, and targets you can change after printing.

Get started right away: sign up for free at sameqr.com, two dynamic QR codes are free forever. API, CLI and MCP server are included in every plan, and the documentation is at sameqr.com/entwickler.

Create dynamic QR codes for free
Start with 2 dynamic QR codes that are free forever. No subscription, no credit card.
Start free now →

Frequently asked questions

Do I need a dedicated Python library from Same-QR?

No. The REST API works with the standard library or any library for web requests.

Can I mix static and dynamic codes?

Yes. For fixed content, a static code is sufficient; for anything printed that may change, use a dynamic one.

Where can I get the print file?

In the dashboard as PNG, SVG, or PDF, or via API with the same key. The documentation on sameqr.com/entwickler describes the methods.

Reserve a spot

Reserve your spot before we go live.

One email as soon as the tool goes live — including pricing and the free plan. No spam, unsubscribe any time.

Only until launchLaunching in the next few weeks
  • Your free account is reserved — there is nothing to pay yet anyway
  • 90 days of unlimited destination changes instead of 30, only for early sign-ups
  • Launch price locked in, even if we raise prices later

By subscribing you consent to receiving the newsletter. You can withdraw consent at any time via the unsubscribe link in every email.

Keep reading