Zum Inhalt springen

QR-Code Bild-API

Ein HTTP-GET, kein Schlüssel, keine Anmeldung: Stellen Sie einer Adresse makeqrco.de/qr/ voran und Sie bekommen den QR-Code zurück – in Ihrer Größe, in Ihren Farben, als PNG oder SVG.

Anfrage

GET https://makeqrco.de/qr/https://example.com?size=1024&ec=h&format=svg

Antwort

200 OK · Content-Type: image/svg+xml · 24 Stunden im Cache

Wie es funktioniert

Alles nach /qr/ ist die Nutzlast, einschließlich ihrer eigenen Query-Parameter. Der Server dekodiert den Pfad, kodiert ihn als QR-Code und liefert ein Bild zurück. Ohne weitere Angaben ist das ein PNG mit 512 Pixeln Kantenlänge, Fehlerkorrektur M, 2 Modulen Ruhezone, Schwarz auf Weiß. Es gibt weder einen Kurz-URL-Dienst noch eine Weiterleitung: Der Code enthält Ihre Adresse wörtlich und funktioniert deshalb weiter, auch wenn es diese Seite einmal nicht mehr gibt.

Die Optionen sind Query-Parameter: ?size=1024, ?dark=7c3aed&light=transparent, ?format=svg. Gespeichert wird nichts, und geglaubt wird auch nichts – jeder Wert wird gegen einen festen Bereich geprüft. Ein falscher Wert führt zu 400 mit einer Meldung, die den Parameter nennt, statt stillschweigend ignoriert zu werden.

Antworten tragen Cache-Control: public, max-age=86400 und einen offenen CORS-Header; ein wiederholt angefragter Link kommt also aus dem Cache, und das Bild lässt sich aus eigenem JavaScript laden. Weil der Cache-Schlüssel die vollständige URL ist, sind zwei verschiedene Optionssätze zwei verschiedene Bilder.

Parameter

Alle optional, alle geprüft. Werte außerhalb des erlaubten Bereichs werden abgelehnt und nicht stillschweigend zurechtgebogen.

Parameter Typ Vorgabe Werte
data Zeichenkette beliebige Nutzlast
Ausdrückliche Nutzlast. Ist sie gesetzt, ersetzt sie den Pfad vollständig, und alle übrigen Query-Parameter werden ignoriert — damit umgehen Sie die Kollision zwischen der Query-Zeichenkette Ihrer Adresse und diesen Optionen. Für alles, was keine reine URL ist: WLAN-Zeichenketten, Telefonnummern, vCards.
size Ganzzahl 512 64–1024 (png) · 64–2048 (svg)
Breite und Höhe der Ausgabe in Pixeln, und zwar in beiden Formaten: bei SVG landet der Wert in den Attributen width und height des Wurzelelements und legt damit die Anzeigegröße fest (das Bild skaliert weiterhin verlustfrei, wirkungslos ist der Wert aber nicht). Bei PNG ist bei 1024 Schluss, weil jedes größere Rasterbild echte Rechenzeit auf einem Endpunkt ohne Schlüssel kostet; wer mehr anfordert, bekommt eine 400, die auf format=svg verweist — das rendert in jeder Größe gleich schnell und geht bis 2048. Werte außerhalb des Bereichs führen zu 400 statt zu einer stillen Korrektur, damit ein Tippfehler auffällt.
margin Ganzzahl 2 0–16
Ruhezone in Modulen — der leere Rand um das Symbol. Die Spezifikation verlangt 4; die Vorgabe 2 gibt zugunsten eines kompakteren Bildes ein wenig Normtreue auf und verhält sich so seit dem Start dieses Endpunkts. Wer einen Wert zwischen 1 und 3 ausdrücklich anfordert, bekommt das Bild trotzdem, dann aber mit dem Header X-QR-Warning. Für Gedrucktes nehmen Sie 4, und 0, wenn Sie den Code auf eine eigene Fläche mit Abstand setzen.
ec Auswahl m l | m | q | h
Fehlerkorrekturstufe: rund 7 %, 15 %, 25 % beziehungsweise 30 % des Symbols dürfen beschädigt sein und werden trotzdem gelesen. Höhere Stufen ergeben einen dichteren Code. Groß- und Kleinschreibung egal.
dark Farbe black #rgb, #rrggbb, #rrggbbaa, black, white, transparent, purple
Farbe der Module. Das führende # ist optional — und in einer URL unhandlich, weshalb `dark=7c3aed` die übliche Schreibweise ist. Bleiben Sie dunkel: Scanner brauchen Kontrast zur hellen Farbe.
light Farbe white #rgb, #rrggbb, #rrggbbaa, black, white, transparent, purple
Hintergrundfarbe. `light=transparent` liefert ein wirklich transparentes PNG (und ein SVG ganz ohne Hintergrundrechteck) — genau richtig, wenn der Code auf farbigem Untergrund liegt.
format Auswahl png png | svg
Format der Antwort. SVG ist wenige hundert Byte groß, skaliert verlustfrei auf jede Größe, kostet in jeder Größe gleich viel Rechenzeit und ist die richtige Wahl für Druck und Großformat — nur damit kommen Sie über die PNG-Grenze von 1024 px hinaus; PNG ist das, was ein <img> in einer E-Mail braucht.
download Ja/Nein false 1 | true | yes | 0 | false | no
Setzt Content-Disposition: attachment, sodass der Browser die Datei als qrcode.png beziehungsweise qrcode.svg speichert, statt sie anzuzeigen. Ein bloßes `?download` gilt als true.

Ihre Query-Parameter und unsere Optionen

Die Nutzlast steht im Pfad, deshalb funktioniert eine Adresse mit eigenem ? und & ohne Maskierung: /qr/https://shop.example/p?id=42&ref=plakat kodiert genau diese Adresse. Nur die acht Namen aus der Tabelle oben gelten als Optionen, exakt und mit Beachtung der Groß- und Kleinschreibung; jeder andere Parameter bleibt Teil dessen, was kodiert wird.

Eine Kollision bleibt, und die verschweigen wir nicht: eine Zieladresse, die selbst size, margin, ec, dark, light, format, download oder data enthält. Bei /qr/https://shop.example/p?size=XL lässt sich Ihr Parameter nicht von unserem unterscheiden; size=XL wird als Option gelesen und endet in einer 400. Es gibt zwei eindeutige Auswege:

Zieladresse prozentkodieren

/qr/https%3A%2F%2Fshop.example%2Fp%3Fsize%3DXL

Oder als ?data= übergeben

/qr/?data=https%3A%2F%2Fshop.example%2Fp%3Fsize%3DXL

?data= ist die verlässliche Form für alles, was keine reine URL ist, und die erste Wahl aus einem Skript: Ist der Parameter gesetzt, ist er die ganze Nutzlast, der Pfad wird ignoriert, und kein anderer Parameter kann in den Code geraten. Prozentkodieren müssen Sie zusätzlich, wenn die Nutzlast ein # enthält, das der Browser sonst als Fragment abschneidet, bevor die Anfrage überhaupt losgeht.

Beispiele zum Ansehen

Jeder Code hier unten ist eine echte Anfrage an diesen Endpunkt, die Ihr Browser beim Laden dieser Seite gestellt hat. Scannen Sie einen davon und Sie landen auf dieser Seite.

QR-Code für makeqrco.de in Schwarz auf Weiß
/qr/https://makeqrco.de/?size=256
Violetter QR-Code für makeqrco.de auf weißem Hintergrund
?dark=7c3aed
Violetter QR-Code für makeqrco.de auf transparentem Hintergrund
?dark=a855f7&light=transparent
QR-Code für makeqrco.de als SVG mit Fehlerkorrektur H
?format=svg&ec=h&margin=4

Beispiele zum Kopieren

Einfacher Code
https://makeqrco.de/qr/https://example.com
Großer Code für den Druck – als SVG, denn ein Vektor kommt über die PNG-Grenze von 1024 px hinaus und kostet dabei keine zusätzliche Rechenzeit
https://makeqrco.de/qr/https://example.com?format=svg&size=2048&margin=4
Größtes PNG (1024 px ist die Rastergrenze; darüber hinaus format=svg ergänzen)
https://makeqrco.de/qr/https://example.com?size=1024&margin=4
SVG – skaliert beliebig, nur wenige hundert Byte
https://makeqrco.de/qr/https://example.com?format=svg
Transparenter Hintergrund, eigene Farbe
https://makeqrco.de/qr/https://example.com?dark=7c3aed&light=transparent
Höchste Fehlerkorrektur (übersteht Logo oder Kratzer)
https://makeqrco.de/qr/https://example.com?ec=h
Beliebige Nutzlast mit ?data= – WLAN-Zugangsdaten
https://makeqrco.de/qr/?data=WIFI%3AT%3AWPA%3BS%3ACafe%3BP%3Ahunter2%3B%3B
Beliebige Nutzlast mit ?data= – eine Telefonnummer
https://makeqrco.de/qr/?data=tel%3A%2B49301234567
Einbindung in HTML
<img src="https://makeqrco.de/qr/https://example.com?size=256&dark=7c3aed"
     alt="QR-Code für example.com" width="256" height="256">
Markdown
![QR-Code für example.com](https://makeqrco.de/qr/https://example.com)
Shell – direkt in eine Datei laden
curl -o qr.svg "https://makeqrco.de/qr/https://example.com?format=svg&download=1"
JavaScript
const res = await fetch(`https://makeqrco.de/qr/?data=${encodeURIComponent(payload)}&ec=h`);
const blob = await res.blob();

Referenz

Methode GET (und OPTIONS für den CORS-Preflight)
Pfad /qr/<url> · /qr/?data=<nutzlast>
Antwort image/png (Vorgabe) oder image/svg+xml
Vorgaben 512 × 512 PNG, Fehlerkorrektur M, 2 Module Ruhezone, Schwarz auf Weiß
Größengrenzen PNG 64–1024 px · SVG 64–2048 px
Optionen data, size, margin, ec, dark, light, format, download
Authentifizierung Keine – kein Schlüssel, kein Kontingent
CORS Access-Control-Allow-Origin: *
Cache public, max-age=86400 (pro vollständiger URL, Optionen eingeschlossen)
Indexierung X-Robots-Tag: noindex, nofollow

Statuscodes

200 Das Bild. 24 Stunden lang von Browsern und gemeinsamen Caches gehalten; der Cache-Schlüssel ist die vollständige URL, ein anderer Satz Optionen ist also ein anderes Bild.
400 Ein Parameter liegt außerhalb des erlaubten Bereichs oder ist unbekannt, die Nutzlast fehlt, oder sie ist zu lang für ein QR-Symbol. Die Antwort ist Klartext und nennt den Parameter samt erlaubter Werte.
X-QR-Warning Kein Status, sondern ein Header auf einer ansonsten normalen 200. Er kommt, wenn die Ausgabe zulässig, aber riskant ist – eine Ruhezone unter 4 Modulen oder zwei Farben ohne Kontrast zueinander.

Eine 400 liest sich so: Invalid `size`: 999999 is out of range. Allowed: 64–2048. – Klartext statt kaputtem Bild. OPTIONS auf demselben Pfad beantwortet den CORS-Preflight, damit auch ein fetch mit eigenem Header funktioniert.

/qr/<url> oder /<url>?

Es gibt zwei Routen, und sie liefern unterschiedliche Inhaltstypen. Die falsche zu wählen ist der häufigste Fehler, deshalb kurz und deutlich:

makeqrco.de/qr/<url>

Liefert image/png oder image/svg+xml. Für <img>-Tags, Markdown, HTML-E-Mails, PDFs und Skripte.

makeqrco.de/<url>

Liefert text/html: eine kleine Seite mit demselben Code und Open-Graph-Tags, damit sie in Messengern mit Vorschau erscheint. Für Links an Menschen.

Beide werden pro Anfrage erzeugt und speichern nichts. Beide senden X-Robots-Tag: noindex, nofollow, und die HTML-Seite lädt keine Statistik, weil die kodierte Adresse Teil ihres Pfads ist.

Grenzen und faire Nutzung

Der Endpunkt ist kostenlos und ohne Authentifizierung – das funktioniert nur, wenn alle vernünftig damit umgehen. Er ist dafür gedacht, Codes in Dokumente, Dashboards und E-Mails einzubetten, nicht dafür, hunderttausende Bilder in einem Rutsch zu rendern. Wer dieses Volumen braucht, lässt dieselbe Bibliothek, node-qrcode, problemlos auf dem eigenen Rechner laufen.

Ein PNG ist bei 1024 Pixeln gedeckelt, weil Rendern nicht umsonst ist und niemand sich dafür anmelden muss: ein Rasterbild wird Pixel für Pixel auf einem Server mit einem einzigen Thread gezeichnet, die Kosten wachsen also mit der Fläche, und einige wenige große Anfragen gleichzeitig würden die ganze Seite ausbremsen. Ein SVG hat diese Kosten nicht – die Größe landet nur in den Attributen width und height –, deshalb reicht format=svg bis 2048 Pixel und skaliert auch darüber hinaus verlustfrei, was für den Druck ohnehin die richtige Wahl ist. Wer ein größeres PNG anfordert, bekommt eine 400, die genau das sagt und format=svg nennt. Das Einzige, was die API bewusst nicht kann, ist das Logo in der Mitte: dafür braucht es Ihre Bilddatei, deshalb bleibt das im QR-Code Generator, wo die Montage in Ihrem Browser passiert. Kombinieren Sie es mit ec=h, damit der Code die verdeckten Module verkraftet.

Lieber ein Logo in der Mitte – oder klicken statt tippen?

QR-Code Generator öffnen