Par l’équipe Enqre·Publié le 16/08/2026
QR codes dynamiques depuis Python, Node et C#
Chacun de ces langages a une bonne bibliothèque locale : qrcode pour Python, node-qrcode pour Node, QRCoder pour .NET. Elles dessinent PNG et SVG hors ligne, sans clé, sans quota et sans coût — et pour un code dont la destination ne change jamais, c'est toute la réponse.
L'API sert à l'autre moitié : un code statique est sa destination — l'URL est dans le motif, la déplacer impose de tout réimprimer. Si ce que vous générez sera imprimé, collé sur une machine ou rattaché à un enregistrement qui survivra à la structure d'URL de cette année, le code doit porter une adresse courte que vous contrôlez. C'est de l'hébergement, pas du dessin.
Créer un code
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();
Notez la vérification : fetch ne rejette pas sur un 402 ni un 429 ; sans elle vous stockez undefined.
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();
Déplacer la destination
PATCH https://enqre.com/api/v1/qrcodes/{id}
Authorization: Bearer enq_…
Content-Type: application/json
{ "url": "https://maint.example/assets/4471/v2" }
Le code imprimé n'est pas touché ; le scan suivant part ailleurs.
Lire les scans
GET /api/v1/qrcodes/{id}/scans répond { total, data }, du plus récent, jusqu'à 1 000 entrées : heure, type d'appareil, système, navigateur.
Ni identité ni localisation — ni ville ni pays.
Ce qui va réellement échouer
401 invalid_api_key400 invalid_body— presque toujours une URL qui n'en est pas une.402 plan_limit_reached429 rate_limited— au-delà de 60 requêtes par minute.
Chaque langage cache l'échec différemment : requests se tait sans raise_for_status, fetch ne rejette que sur erreur réseau, HttpClient réclame EnsureSuccessStatusCode.
Deux règles plus importantes que le code
Rendez la création idempotente. Deux appels créent deux codes.
N'imprimez rien sans relecture.
Quand ne pas écrire d'intégration
Pour quelques centaines de codes en une fois, l'import CSV est plus rapide que tout ce que vous écririez.
Réponses rapides
- Meilleure bibliothèque ?
qrcode,node-qrcode,QRCoder. - L'API renvoie-t-elle une image ? Non,
shortUrl. - Authentification ?
Authorization: Bearer enq_…. - Limite ? 60 par minute.
- Localisation dans les scans ? Non.
- Modifiable après impression ? C'est tout l'objet —
PATCH.