Aller au contenu

API QR-Codes

Aperçu

L’API Codes est au cœur de qr3.app. Elle vous permet de créer, mettre à jour et supprimer des QR-Codes dynamiques et statiques.

URL de base : https://qr3.app/v1/codes

Contrat REST de référence

Le contrat suivant s’applique à tous les clients :

  • POST /v1/codes accepte uniquement les types url, vcard, wifi, email, sms et location. Les champs sont plats : url ; au moins vcard_first_name ou vcard_last_name ; wifi_ssid ; email_to ; sms_phone ; ou location_lat et location_lng.
  • Seuls les codes url peuvent être dynamiques. Les requêtes de création peuvent facultativement inclure expires_at sous la forme d’un horodatage ISO 8601 ; ab_enabled, ab_target_url_b et ab_weight_a (destinations A/B) sont acceptés pour les codes url dynamiques ; redirect_after_expiry ne fait pas partie du contrat de création.
  • GET /v1/codes ne prend en charge que limit, cursor et status (live, paused, flagged, draft).
  • POST /v1/codes/batch accepte url, vcard et wifi. La limite est de 10 pour Free, 500 pour Pro et 1 000 enregistrements pour Business/Agency/Enterprise par requête. Les analyses d’URL s’exécutent de façon synchrone pour 50 éléments URL au maximum ; au-delà, skip_url_scan: true est nécessaire.

Créer un QR-Code

POST /v1/codes

Fenêtre de terminal
curl -X POST https://qr3.app/v1/codes \
-H "Authorization: Bearer qr3_sk_..." \
-H "Content-Type: application/json" \
-d '{
"type": "url",
"url": "https://example.com",
"title": "Mein erster QR-Code",
"tags": ["marketing", "q1"],
"is_dynamic": true
}'

Réponse (HTTP 201) :

{
"data": {
"id": "qr_a1b2c3d4",
"short_code": "r7f3Kx",
"redirect_url": "https://qr3.app/r7f3Kx",
"image_svg_url": "https://qr3.app/v1/codes/r7f3Kx/qr.svg",
"image_png_url": "https://qr3.app/v1/codes/r7f3Kx/qr.png",
"image_pdf_url": "https://qr3.app/v1/codes/r7f3Kx/qr.pdf",
"image_eps_url": "https://qr3.app/v1/codes/r7f3Kx/qr.eps",
"type": "url",
"target_url": "https://example.com",
"is_dynamic": true,
"status": "live",
"tags": ["marketing", "q1"],
"total_scans": 0,
"created_at": "2026-03-15T10:00:00.000Z"
},
"meta": { "request_id": "req_xyz123" }
}

Types de QR-Codes

TypeDescriptionChamps obligatoires
urlURL de site web (dynamique ou statique)url
vcardCarte de visite (vCard 3.0)vcard_first_name ou vcard_last_name
wifiConfiguration Wi-Fiwifi_ssid
emailE-mail (mailto:)email_to
smsSMSsms_phone
locationLocalisation (geo:)location_lat, location_lng

Création par lot (Batch)

POST /v1/codes/batch

Fenêtre de terminal
curl -X POST https://qr3.app/v1/codes/batch \
-H "Authorization: Bearer qr3_sk_..." \
-H "Content-Type: application/json" \
-d '{
"items": [
{ "type": "url", "url": "https://produkt-1.example.com", "tags": ["batch"] },
{ "type": "url", "url": "https://produkt-2.example.com", "tags": ["batch"] },
{ "type": "wifi", "wifi_ssid": "GastWLAN", "wifi_password": "geheim123" }
],
"skip_url_scan": false
}'

Réponse (HTTP 201) :

{
"data": {
"created": [
{ "id": "qr_...", "short_code": "abc123", "redirect_url": "https://qr3.app/abc123" },
{ "id": "qr_...", "short_code": "def456", "redirect_url": "https://qr3.app/def456" },
{ "id": "qr_...", "short_code": "ghi789", "status": "live" }
],
"total": 3,
"failed": 0
}
}

Liste des QR-Codes

GET /v1/codes

Fenêtre de terminal
curl https://qr3.app/v1/codes?status=live&limit=20 \
-H "Authorization: Bearer qr3_sk_..."

Paramètres de requête (Query Parameters) :

ParamètreTypePar défautDescription
cursorstring—Curseur pour la pagination
limitinteger20Résultats par page (max. 100)
statusstring—Filtre : live, paused, flagged, draft

Récupérer un QR-Code

GET /v1/codes/:id

Fenêtre de terminal
curl https://qr3.app/v1/codes/qr_a1b2c3d4 \
-H "Authorization: Bearer qr3_sk_..."

Mettre à jour un QR-Code

PATCH /v1/codes/:id

Update contract: url may be changed only for an existing type: "url" code, and its value must use http:// or https://. Other code types must not receive url; invalid requests return 422.

Les QR-Codes dynamiques permettent de modifier l’URL de destination à tout moment — sans avoir à réimprimer le QR-Code.

Fenêtre de terminal
curl -X PATCH https://qr3.app/v1/codes/qr_a1b2c3d4 \
-H "Authorization: Bearer qr3_sk_..." \
-H "Content-Type: application/json" \
-d '{ "url": "https://neue-zielseite.example.com", "status": "live" }'

Page d’atterrissage (Landing page) & liens externes

Pour les codes url dynamiques, vous pouvez définir is_landing_page: true (lors de la création ou via PATCH). Un scan affichera alors une page hébergée par qr3 contenant les fichiers publics et les liens externes du code, au lieu de rediriger. Les liens externes sont transmis sous forme de tableau links :

{
"is_landing_page": true,
"links": [
{ "label": "Datenblatt", "url": "https://example.com/datenblatt.pdf" },
{ "label": "Zertifikat", "url": "https://example.com/zertifikat.pdf" }
]
}
  • 0 à 20 liens par code ; label doit faire entre 1 et 100 caractères ; url doit être au format http(s) (≤ 2048 caractères).
  • Chaque URL est vérifiée avec Google Web Risk — une URL non sécurisée renvoie une erreur 422.
  • Si Web Risk n’est pas accessible lors de l’enregistrement, le lien est tout de même accepté, mais marqué pour une nouvelle vérification. Une tâche quotidienne vérifie à nouveau les liens enregistrés (et réévalue régulièrement les liens classés comme sûrs) et suspend automatiquement le code si un lien est ultérieurement détecté comme non sécurisé.
  • "links": [] supprime tous les liens. Voir le guide de la page d’atterrissage.

Supprimer un QR-Code

DELETE /v1/codes/:id

Soft-delete (suppression logique) — le QR-Code est archivé, les données de scan sont conservées.

Un second DELETE sur le même code renvoie 404, même si les deux requêtes arrivent en même temps. Le webhook qr.deleted est envoyé exactement une fois.

Fenêtre de terminal
curl -X DELETE https://qr3.app/v1/codes/qr_a1b2c3d4 \
-H "Authorization: Bearer qr3_sk_..."

Télécharger les images de QR-Codes

Tous les formats d’image sont accessibles publiquement — aucune authentification n’est requise.

FormatURLUtilisation
SVG (vectoriel)/v1/codes/:code/qr.svgWeb, mise à l’échelle, numérique
PNG (matriciel)/v1/codes/:code/qr.pngE-mail, présentations
PDF (vectoriel)/v1/codes/:code/qr.pdfPar défaut : carré (uniquement le code) ; ?format=a4 pour une feuille d’impression
EPS (vectoriel)/v1/codes/:code/qr.epsFlux de travail d’impression professionnels (Adobe, imprimeries)

Optionnel : ?size=N — Taille du module en pixels (2–20, par défaut : 4) pour SVG, PNG et EPS. Le PDF utilise une taille de module fixe.

Uniquement PDF : ?format=a4|square — Format de page (par défaut : square — uniquement le code + zone de silence, pas de marge blanche A4 ; a4 pour une feuille A4 prête à imprimer)

Fenêtre de terminal
# SVG für Web
curl https://qr3.app/v1/codes/r7f3Kx/qr.svg
# PNG in hoher Auflösung
curl https://qr3.app/v1/codes/r7f3Kx/qr.png?size=10 -o qr-hires.png
# Kompaktes PDF (nur der Code, Standard)
curl https://qr3.app/v1/codes/r7f3Kx/qr.pdf -o qr.pdf
# Druckfertiges A4-Blatt
curl "https://qr3.app/v1/codes/r7f3Kx/qr.pdf?format=a4" -o qr-a4.pdf

Couleurs et correction d’erreurs

Les quatre routes d’image acceptent trois paramètres optionnels. Ils s’appliquent à cette seule requête et prévalent sur les couleurs enregistrées sur le code (section suivante).

ParamètreValeursPar défautSVG, PNGPDF, EPS
fgHex RRGGBB ou RGB000000est dessinéest dessiné comme couleur d’impression
bgHex comme fg ou transparentffffffest dessinéest dessiné comme couleur d’impression
eccL, M, Q, HMs’appliques’applique
  • Casse : La casse n’a pas d’importance, le # est facultatif. S’il est envoyé, il doit être encodé en %23.
  • Les valeurs invalides sont considérées comme non définies. ?fg=lila renvoie la couleur enregistrée sur le code, ou le noir normal si aucune n’est enregistrée, avec un statut 200 et jamais une erreur. Seul un ?fg=000000 explicite force le noir.
  • bg=transparent renvoie un SVG, PDF ou EPS sans arrière-plan et un PNG avec un véritable canal alpha. Le support sur lequel le code est placé doit être clair et laisser une zone de silence de 4 modules tout autour. Un code sombre sur un support sombre n’est pas lisible.
  • PDF et EPS écrivent le noir et le gris en niveaux de gris (plaque noire uniquement) et toute autre couleur en CMJN en pourcentages entiers, par exemple 1F4E79 sous la forme C74 M36 Y0 K53. Dès qu’une couleur est choisie, un fond opaque se trouve derrière le code et sa zone de silence, en blanc ou dans la couleur de bg, comme dans le SVG. Sans couleurs, les deux fichiers restent inchangés. Conversion et limites : Couleurs à l’impression.
  • Lisibilité : La route d’image ne vérifie pas le contraste. Un rapport d’au moins 4:1 et des modules sombres sur fond clair sont recommandés. #1F4E79 sur blanc a un rapport de 8,7:1, #ff6600 sur blanc seulement 2,9:1.
  • ecc modifie le motif de points, pas le contenu. Un code imprimé continue de fonctionner, mais les anciens et nouveaux fichiers d’impression ne doivent pas être mélangés. Q ou H rendent le code plus robuste, par exemple sur du carton ondulé. Un logo impose toujours H.
  • Avec logo, la zone derrière le logo reste blanche, même avec un arrière-plan coloré ou transparent.
  • Mise en cache : Seule l’image par défaut réelle (noir sur blanc, correction d’erreurs M, sans logo) est livrée comme immuable pendant 24 heures ; tout autre rendu pendant 5 minutes. Pour PDF et EPS, tout arrière-plan indiqué compte comme un écart : bg=ffffff y dessine un fond blanc que le fichier standard n’a pas.
  • Disponibilité : Les couleurs et la correction d’erreurs sont disponibles dans tous les forfaits, y compris le forfait gratuit.
Fenêtre de terminal
# Dark blue code on white
curl "https://qr3.app/v1/codes/r7f3Kx/qr.svg?fg=1F4E79" -o qr-blue.svg
# Transparent PNG for a layout on a light surface
curl "https://qr3.app/v1/codes/r7f3Kx/qr.png?size=10&bg=transparent" -o qr-transparent.png
# More robust for corrugated board: error correction Q
curl "https://qr3.app/v1/codes/r7f3Kx/qr.pdf?ecc=Q" -o qr-q.pdf

Enregistrer les couleurs sur le code

PATCH /v1/codes/:id enregistre les couleurs sous appearance sur le code. Les routes d’image les dessinent ensuite par défaut, sans paramètre.

Fenêtre de terminal
curl -X PATCH https://qr3.app/v1/codes/qr_a1b2c3d4 \
-H "Authorization: Bearer qr3_sk_..." \
-H "Content-Type: application/json" \
-d '{"appearance": {"foreground_color": "#1F4E79"}}'

Réponse (HTTP 200, abrégée) :

{
"data": {
"id": "qr_a1b2c3d4",
"short_code": "r7f3Kx",
"appearance": { "foreground_color": "#1F4E79", "background_color": null }
},
"meta": { "request_id": "req_xyz", "issues": [] }
}
  • Valeurs : foreground_color sous forme de #RRGGBB, background_color sous forme de #RRGGBB ou transparent. D’autres clés renvoient 400.
  • Fusion : Un champ omis conserve sa valeur enregistrée. null réinitialise un champ, "appearance": null réinitialise les deux. Le noir et le blanc ne sont pas enregistrés ; la réponse les affiche comme null.
  • Chaque réponse de code contient appearance, tout comme les webhooks qr.created et qr.updated.
  • Ordre dans les routes d’image : d’abord le paramètre, puis la couleur enregistrée, puis la valeur par défaut. ?fg=000000 fournit donc le fichier d’impression noir d’un code couleur.
  • Images intégrées : Une URL d’image suit les couleurs enregistrées, dans la mesure où elle ne les définit pas elle-même avec fg et bg : une URL sans paramètre pour les deux couleurs, ?fg=000000 pour l’arrière-plan, ?ecc=Q également pour les deux. Après un changement de couleur, une page qui intègre une telle URL peut encore afficher l’ancienne image : pendant une durée allant jusqu’à 24 heures si l’URL livrait l’image par défaut jusque-là (noir sur blanc, correction d’erreurs M, sans logo), sinon pendant une durée allant jusqu’à 5 minutes. La solution consiste à ajouter votre propre paramètre à l’URL, qui change à chaque modification de couleur, par exemple ?v=2 ou le updated_at du code comme dans le tableau de bord. Les routes d’image ignorent les paramètres inconnus.
  • La correction d’erreurs n’est jamais enregistrée. Elle est choisie par téléchargement avec ?ecc=.
  • Uniquement via PATCH : POST /v1/codes, le traitement par lots et l’importation rejettent appearance avec 422.
  • PDF et EPS dessinent les couleurs enregistrées comme des couleurs d’impression, tout comme les paramètres. Comme le blanc n’est jamais enregistré, un code avec une couleur de premier plan enregistrée y obtient un fond blanc, comme dans le SVG.

Vérification du contraste

L’API vérifie la paire résultant de la requête et de la valeur enregistrée :

NiveauQuandRéponse
blockedContraste inférieur à 1,5:1422, rien n’est enregistré
criticalinférieur à 2:1 ou différence de luminosité inférieure à 0,30 ; un avertissement en combinaison avec un logo ; tout arrière-plan transparent200 avec meta.issues
warninginférieur à 4:1 ou différence de luminosité inférieure à 0,50 ; modules clairs sur fond sombre200 avec meta.issues
oktout le reste200, meta.issues est vide

Chaque entrée dans meta.issues contient code, severity, field, message et facultativement hints comme contrast_ratio — la même forme que les messages de conformité d’un passeport de produit numérique. Un arrière-plan transparent n’est jamais bloqué, car un code clair sur un emballage sombre est un cas d’utilisation réel. Le support nécessite néanmoins un contraste net et une zone de silence libre de 4 modules tout autour.

Le chargement et la suppression d’un logo (POST et DELETE /v1/codes/:id/logo) vérifient également les couleurs enregistrées et renvoient aussi les résultats dans meta.issues : avec un logo, un avertissement devient critical, sans logo, il redevient un avertissement.

Si une autre requête modifie le même code au même moment, l’API applique les modifications à la dernière version en date. Ce n’est que si cela échoue trois fois de suite qu’elle répond par 409 ; le client recharge alors le code et répète la modification.


Requête multipart, champ file : PNG, JPEG ou WebP, 1 Mo maximum, détecté par les octets magiques. Normalise l’image en un PNG 512×512 transparent et remplace un logo existant.

Fenêtre de terminal
curl -X POST https://qr3.app/v1/codes/qr_a1b2c3d4/logo \
-H "Authorization: Bearer qr3_sk_..." \

Réponse (HTTP 201) : le code mis à jour, avec logo_file_id défini.

Supprime le logo et efface l’objet stocké. Idempotent — un appel sans logo existant renvoie toujours 200.

Si une autre requête modifie le logo du même code au même moment (un second téléversement ou une suppression), POST et DELETE /v1/codes/:id/logo renvoient 409 (errors/conflict) et ne modifient rien ; l’image téléversée est supprimée. Rechargez le code et réessayez. Deux appels simultanés de DELETE /v1/codes/:id/logo ne constituent pas un conflit ; les deux renvoient 200.

S’il est défini, les quatre formats — qr.svg, qr.png, qr.pdf et qr.eps — intègrent les pixels du logo et augmentent la correction d’erreurs à H. Le contrat complet — y compris quel changement (ajout/suppression vs remplacement) modifie le motif de points — ainsi que les instructions d’impression se trouvent sous Logo dans le code QR.


Commentaires

Les commentaires permettent des boucles de rétroaction entre les agences et les clients.

GET /v1/codes/:id/comments

POST /v1/codes/:id/comments

PATCH /v1/codes/:id/comments/:commentId

DELETE /v1/codes/:id/comments/:commentId

Les commentaires créés depuis le Tableau de bord sont attribués à l’utilisateur qui les a générés (author_id) ; les commentaires créés via une simple clé API restent non attribués (author_id: null). Un commentaire ne peut être supprimé que par son propre auteur ou par un org_admin/ws_admin — une simple clé API ne peut supprimer que les commentaires non attribués créés par API.

Fenêtre de terminal
# Kommentar hinzufügen
curl -X POST https://qr3.app/v1/codes/qr_a1b2c3d4/comments \
-H "Authorization: Bearer qr3_sk_..." \
-H "Content-Type: application/json" \
-d '{ "body": "QR-Code bitte auf grünen Hintergrund abstimmen.", "author_name": "Max Müller" }'
# Offene Kommentare auflisten
curl "https://qr3.app/v1/codes/qr_a1b2c3d4/comments?resolved=false" \
-H "Authorization: Bearer qr3_sk_..."
# Kommentar als erledigt markieren
curl -X PATCH https://qr3.app/v1/codes/qr_a1b2c3d4/comments/cmt_xyz \
-H "Authorization: Bearer qr3_sk_..." \
-H "Content-Type: application/json" \
-d '{ "resolved": true }'