API de QR code
Le QR code de vos factures, en un appel.
Envoyez le texte ou le lien et recevez seulement l’image du QR code, en PNG ou SVG, prête à placer sur votre facture, ticket ou étiquette. Un code par appel, rien n’est conservé.
Gratuit · 1 000 codes par mois · SVG ou PNG
Prêt en trois étapes.
Sans carte, rien à installer.
- Se connecter avec Google1
Connectez-vous avec Google
Gratuit, sans carte, rien à installer.
- Votre clé · montrée une foisqs_live_7hK2…Copier2
Créez votre clé
Un clic dans l’onglet Développeur de votre profil. Nous n’en gardons qu’une empreinte.
- POST3
Appelez et utilisez l’image
Vous recevez seulement l’image du code et le nombre restant. Le document reste le vôtre.
Voyez-le avant de coder.
Choisissez et voyez le code sur un document d’exemple, à sa taille réelle. Juste dessous, l’appel déjà écrit.
L’essentiel, d’un coup d’œil.
La clé reste sur votre serveur
Elle va dans l’en-tête Authorization. Jamais dans un navigateur ni une app.
- 6201 000
1 000 codes par mois
Le compte repart le 1er. Jusqu’à 30 appels par minute, un code chacun.
La marque vient toute seule
Un lien WhatsApp prend le logo de WhatsApp. Ou choisissez la vôtre, ou aucune.
- +52
59 types de contenu
Les mêmes que dans l’éditeur, avec les mêmes règles de validation.
Votre style, enregistré
Dessinez-le dans votre profil et utilisez son id, ou écrivez-le dans l’appel.
- 400 · content.ssid: required429 · quota-exceeded500 · render-failed
Des erreurs qui disent quoi
Un code pour votre programme, une phrase pour qui la lit. Une erreur ne coûte pas de quota.
Trois adresses, rien de plus.
Toutes sur https://api.qrsensei.com, avec votre clé dans l’en-tête Authorization. Les réponses sont toujours en JSON.
POST/v1/qr
Compte 1 code de votre mois (1 000)
Crée un code : envoyez le contenu (et, si vous voulez, marque, style, format et taille) et recevez l’image en data URL, avec ce qu’il vous reste.
{ "image": "data:image/png;base64,…", "format": "png", "remaining": 902, "limit": 1000, "resetsAt": "…" }GET/v1/usage
Non compté
Combien vous avez utilisé et ce qu’il reste ce mois-ci, sans rien dépenser. Utile avant un gros lot de factures.
{ "used": 98, "remaining": 902, "limit": 1000, "resetsAt": "…" }GET/v1/brands
Non compté
Les marques que vous pouvez nommer dans brand. Public, sans clé, mis en cache.
{ "brands": ["qrsensei", "instagram", "whatsapp", …], "auto": "auto", "none": "none" }
Questions fréquentes
Est-ce vraiment gratuit ? Combien de codes puis-je créer ?
Oui. Chaque compte a 1 000 codes par mois, toutes applications confondues, et le compteur repart le 1er. Le chiffre actuel est toujours affiché ici et dans votre profil.
Gardez-vous le contenu de mes codes ?
Non. Le contenu voyage dans le corps de la requête, il est dessiné puis renvoyé ; rien n’est conservé ni journalisé. De votre côté, nous ne gardons qu’un compte mensuel.
PNG ou SVG ?
SVG dès que votre PDF ou votre page l’accepte : net à toutes les tailles et plus léger. PNG pour les systèmes qui n’acceptent que des images ; il est dessiné à la taille demandée.
Quelle taille sur une facture ?
Entre 2 et 3 cm imprimés, soit une size de 256 à 384 à 300 dpi. En dessous de 1,5 cm, beaucoup de téléphones hésitent. Le laboratoire montre la taille réelle sur le papier.
Puis-je appeler l’API depuis un navigateur ou une app ?
Non : la clé serait visible de tous. Appelez-la depuis votre serveur et envoyez l’image toute prête au navigateur ou à l’app.
Comment mettre l’image dans un PDF ?
La réponse contient l’image en data URL. Dans un générateur PDF à partir de HTML, utilisez-la directement dans un <img>. Dans les bibliothèques PDF, prenez le base64 après la virgule, décodez-le et insérez-le comme image.
Le code sera-t-il toujours lisible ?
Chaque style est vérifié avant d’être accepté (formes qui vont ensemble, contraste d’au moins 4,5:1) et la correction d’erreur est choisie selon la taille et le logo. Essayez dans le laboratoire : il lit le code comme un téléphone.
Que se passe-t-il si je dépasse la limite ?
L’API répond 429 (quota-exceeded) avec la date de reprise, et rien n’est facturé. Les appels en erreur ne comptent jamais, et GET /v1/usage indique ce qu’il reste.
Puis-je mettre ma marque au centre ?
Vous pouvez utiliser la marque reconnue d’après le lien ("auto"), une marque du catalogue, celle de QrSensei ou aucune. Vos propres logos ne passent pas encore par l’API.
Quels paiements le code peut-il contenir ?
Tout lien de paiement (Stripe, PayPal, Mercado Pago…) en tant que lien, et les formats que les banques lisent directement : SEPA (EPC, en Europe) et PIX (au Brésil).
L’API peut-elle changer et casser mon système ?
Pas sans prévenir. Tout est sous /v1 : ce qui marche aujourd’hui continue ; les nouveautés arrivent en champs facultatifs.
Référence complète : tous les champs, types et erreurs
Créer un code
Un POST avec le contenu dans le corps. Le contenu ne passe jamais dans l’adresse, pour ne pas rester dans les journaux des serveurs en chemin.
curl https://api.qrsensei.com/v1/qr \
-H "Authorization: Bearer $QRSENSEI_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": {
"type": "text",
"text": "FT 2026/118 · 149,90 EUR"
},
"brand": "qrsensei",
"style": {
"color": {
"kind": "solid",
"color": "#18181B"
}
},
"format": "png",
"size": 256
}'Corps de la requête
| Champ | Valeurs | Ce que c’est |
|---|---|---|
| content | objet | Ce que contient le code, avec son type. Voir Contenus. |
| format | "svg" · "png" | SVG par défaut : net à toutes les tailles et plus léger. PNG pour les systèmes qui n’acceptent que des images. |
| size | 128 – 1024 | Le côté de l’image en pixels (512 par défaut). Pour une facture, 256 suffit. |
| style | id · objet | Un de vos styles par son id, ou un style écrit dans l’appel. Sans lui : le style de l’application, ou celui du compte par défaut. |
| brand | "auto" · "none" · … | Le logo au centre : reconnu d’après le lien (auto), le nom d’une marque, ou aucun. |
Réponse
{
"image": "data:image/png;base64,iVBORw0KGgo…",
"format": "png",
"remaining": 902,
"limit": 1000,
"resetsAt": "2026-12-01T00:00:00.000Z"
}Les mêmes nombres arrivent dans les en-têtes X-QrSensei-Remaining, X-QrSensei-Limit et X-QrSensei-Reset.
Authentification
Chaque appel porte la clé de votre application dans l’en-tête Authorization: Bearer qs_live_….
- La clé n’est montrée qu’une fois, à sa création. Nous n’en gardons qu’une empreinte : si vous la perdez, créez-en une nouvelle dans votre profil et l’ancienne cesse de fonctionner.
- Appelez depuis votre serveur, jamais depuis un navigateur ou une app : une clé dans le code front-end peut être lue par n’importe qui.
- Rien des codes n’est conservé : ni le contenu, ni les images. Seulement un compte par mois.
Contenus
Les mêmes types que l’éditeur, avec les mêmes règles. Ce tableau est lu dans les règles qui vérifient chaque appel : il ne peut pas être périmé.
| type | Obligatoires | Facultatifs |
|---|---|---|
| url | url | — |
| text | text | — |
| phone | phone | — |
| subject, body | ||
| sms | phone | message |
| wifi | ssid, password | encryption, hidden |
| vcard | firstName | lastName, organization, title, phone, email, website, address, note |
| raw | payload | — |
| phone | message | |
| telegram | usernameOrHandle | message |
| signal | recipient | message |
| viber | recipient | message |
| mecard | name | organization, phone, email, website, address, note |
| geo | latitude, longitude | label |
| googleMaps | — | latitude, longitude, query |
| waze | — | latitude, longitude, query |
| event | title, start, end | location, description, allDay |
| pix | pixKey, merchantName, merchantCity | amount, txid, description |
| epc | beneficiaryName, iban | bic, amount, reference, remittance |
| paypal | paypalHandleOrEmail | amount, currency, note, paymentUrl |
| mbway | phone | amount, note |
| cryptoWallet | address | currency, amount, network, memo |
| deepLink | uri | — |
| otp | issuer, accountName, secret | otpType, algorithm, digits, period, counter |
| auth | uri | — |
| structuredText | text | — |
| paramUrl | baseUrl | params |
| customContent | content | — |
| liens | url | calendarLink · instagram · facebook · linkedin · x · tiktok · youtube · github · spotify · snapchat · pinterest · threads · discord · appStore · googlePlay · appGallery · microsoftStore · pdf · fileDownload · onlineDocument · portfolio · menu · digitalCard · coupon · landingPage · form · review · checkIn · rsvp · catalog · credentialLink |
Un Wi-Fi sans mot de passe prend encryption "nopass". Un champ omis reste vide ; un champ obligatoire manquant est nommé dans le detail de l’erreur.
Styles
Dessinés dans votre profil, avec le code en direct à côté. Chacun a un id et l’un est votre style par défaut ; ou écrivez le style dans l’appel lui-même, comme style.
{}{ "color": { "kind": "solid", "color": "#18181B" }, "background": { "kind": "transparent" }, "quietZone": 2 }{ "dots": "dots", "finders": "drop", "color": { "kind": "gradient", "type": "linear", "angle": 45, "stops": [ "#0F172A", "#1E40AF" ] }, "background": { "kind": "solid", "color": "#FFF7ED" } }Un style n’est accepté que s’il se lit : des formes qui vont ensemble, et une encre plus foncée que son papier avec un contraste d’au moins 4,5:1. Un code transparent est vérifié sur blanc, le papier d’une facture.
Marques
"auto" reconnaît la marque d’après le lien (un lien Instagram prend le logo d’Instagram). Un nom fixe la marque ; "none" laisse le centre libre. La liste vient aussi de GET /v1/brands.
Contre le phishing : sur un lien, une marque fixée n’est utilisée que si le lien est bien le sien. Le logo d’une banque n’atterrit jamais sur un faux lien.
- qrsensei
- x
- tiktok
- youtube
- github
- spotify
- telegram
- signal
- viber
- snapchat
- threads
- discord
- messenger
- googleMaps
- appleMaps
- waze
- paypal
- revolut
- wise
- stripe
Limites
| Par mois | 1 000 codes par compte, toutes les applications ensemble. Le compte repart le 1er, à 00:00 UTC. |
| Par minute | 30 appels par application. Un code par appel : pas de génération en masse. |
| Non compté | Les appels en erreur, GET /v1/usage et GET /v1/brands. |
Erreurs
Toujours un objet error avec code, message et, quand il aide, detail : le code est pour votre programme, le message pour qui le lit. Un appel en erreur n’est pas compté.
| Statut | code | Quand |
|---|---|---|
| 401 | missing-key | Pas de clé dans l’en-tête Authorization. |
| 401 | invalid-key | La clé n’existe pas ou a été remplacée. |
| 400 | invalid-json | Le corps n’est pas du JSON. |
| 400 | invalid-request | Un champ hors de la liste, ou une valeur hors limites ; detail le nomme. |
| 400 | invalid-content | Un champ obligatoire manque ou est faux ; detail le nomme. |
| 400 | unknown-brand | Cette marque n’est pas dans GET /v1/brands. |
| 422 | brand-mismatch | Une marque fixée sur un lien qui n’est pas le sien. |
| 404 | unknown-style | Cet id de style n’appartient pas à votre compte. |
| 403 | not-developer | Le mode développeur est désactivé sur le compte. |
| 403 | suspended | Le compte ne peut pas utiliser l’API pour l’instant. |
| 413 | too-large | Le corps dépasse 16 Ko. |
| 429 | quota-exceeded | Les codes de ce mois sont épuisés. |
| 429 | rate-limited | Trop d’appels cette minute ; Retry-After indique combien attendre. |
| 500 | render-failed | Le code n’a pas pu être dessiné. Non compté. |
| 503 | api-off | L’API est coupée un moment. Non compté. |