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.
GET https://makeqrco.de/qr/https://example.com?size=1024&ec=h&format=svg
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.
Beispiele zum Kopieren
https://makeqrco.de/qr/https://example.com https://makeqrco.de/qr/https://example.com?format=svg&size=2048&margin=4 https://makeqrco.de/qr/https://example.com?size=1024&margin=4 https://makeqrco.de/qr/https://example.com?format=svg https://makeqrco.de/qr/https://example.com?dark=7c3aed&light=transparent https://makeqrco.de/qr/https://example.com?ec=h https://makeqrco.de/qr/?data=WIFI%3AT%3AWPA%3BS%3ACafe%3BP%3Ahunter2%3B%3B https://makeqrco.de/qr/?data=tel%3A%2B49301234567 <img src="https://makeqrco.de/qr/https://example.com?size=256&dark=7c3aed"
alt="QR-Code für example.com" width="256" height="256">  curl -o qr.svg "https://makeqrco.de/qr/https://example.com?format=svg&download=1" 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