Vom Enqre-Team·Veröffentlicht am 16.8.2026
Dynamische QR-Codes aus Python, Node und C#
Jede dieser Sprachen hat eine gute lokale Bibliothek: qrcode für Python, node-qrcode für Node, QRCoder für .NET. Sie zeichnen PNG und SVG offline, ohne Schlüssel, Kontingent und Kosten — und für einen Code, dessen Ziel sich nie ändert, ist das die vollständige Antwort.
Die API ist für die andere Hälfte: ein statischer Code ist sein Ziel — die URL steckt im Muster, ein Zielwechsel bedeutet Nachdruck. Wird das Erzeugte gedruckt, auf eine Maschine geklebt oder an einen Datensatz gehängt, der die diesjährige URL-Struktur überlebt, muss der Code eine kurze Adresse tragen, die Sie kontrollieren. Das ist Betrieb, nicht Zeichnen — deshalb kann es keine Bibliothek leisten.
Einen Code anlegen
Python
import os, requests
r = requests.post(
"https://enqre.com/api/v1/qrcodes",
headers={"Authorization": f"Bearer {os.environ['ENQRE_API_KEY']}"},
json={
"name": "Asset 4471 – service log",
"url": "https://maint.example/assets/4471",
},
timeout=10,
)
r.raise_for_status() # 4xx and 5xx become exceptions, not silence
code = r.json()["data"]
code["id"] # store this against your record
code["shortUrl"] # the address the QR image should encode
Node
const res = await fetch("https://enqre.com/api/v1/qrcodes", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.ENQRE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "Asset 4471 – service log",
url: "https://maint.example/assets/4471",
}),
});
// fetch does NOT throw on 4xx. Check the status or you will store undefined.
if (!res.ok) throw new Error(`enqre: ${res.status} ${await res.text()}`);
const { data: code } = await res.json();
Beachten Sie die Prüfung: fetch läuft auch bei 402 oder 429 durch, und ohne sie speichern Sie undefined — bemerkt wird das in der Druckerei.
C#
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", Environment.GetEnvironmentVariable("ENQRE_API_KEY"));
var payload = JsonContent.Create(new {
name = "Asset 4471 – service log",
url = "https://maint.example/assets/4471",
});
var res = await http.PostAsync("https://enqre.com/api/v1/qrcodes", payload);
res.EnsureSuccessStatusCode();
using var doc = JsonDocument.Parse(await res.Content.ReadAsStringAsync());
var code = doc.RootElement.GetProperty("data");
var id = code.GetProperty("id").GetString();
var shortUrl = code.GetProperty("shortUrl").GetString();
Das Ziel umlegen
PATCH https://enqre.com/api/v1/qrcodes/{id}
Authorization: Bearer enq_…
Content-Type: application/json
{ "url": "https://maint.example/assets/4471/v2" }
Der gedruckte Code bleibt unberührt; der nächste Scan geht woandershin.
Scans lesen
GET /api/v1/qrcodes/{id}/scans antwortet mit { total, data }, neueste zuerst, bis zu 1.000 Einträge: Zeit, Gerätetyp, System, Browser.
Keine Identität und kein Standort — weder Stadt noch Land. "Wie viele, wann, auf welchem Gerät" ist beantwortbar; "wer" und "wo" nicht.
Was tatsächlich schiefgeht
401 invalid_api_key400 invalid_body— fast immer eine URL, die keine ist.402 plan_limit_reached429 rate_limited— über 60 Anfragen je Minute.
Jede Sprache versteckt Fehler anders, und genau das gilt es je Sprache richtig zu machen: requests schweigt ohne raise_for_status, fetch lehnt nur bei Netzwerkfehlern ab, HttpClient braucht EnsureSuccessStatusCode.
Zwei Regeln, die mehr wert sind als der Code
Erzeugung idempotent machen. Zweimal gefragt heißt zwei Codes für Anlage 4471.
Nichts drucken, was nicht zurückgelesen wurde. Eine Anfrage verhindert den einzigen Fehler, der später nicht korrigierbar ist.
Wann sich keine Integration lohnt
Für ein paar hundert Codes einmalig ist der CSV-Upload schneller als jeder Code, den Sie schreiben würden. Integrieren Sie, wenn Codes laufend entstehen.
Kurze Antworten
- Beste Zeichenbibliothek?
qrcode,node-qrcode,QRCoder. - Liefert die API ein Bild? Nein,
shortUrl. - Authentifizierung?
Authorization: Bearer enq_…. - Ratenlimit? 60 je Minute.
- Standort in den Scans? Nein.
- Nach dem Druck änderbar? Genau darum geht es —
PATCH.