Erzeuge individuell gestaltete QR-Codes direkt aus deiner Anwendung. Ein REST-Aufruf liefert SVG oder PNG und nutzt dieselbe Render-Engine wie der QRocodile-Generator.
Du schickst Inhalt und optional ein Design, der Response-Body ist das fertige Bild. Es läuft kein Browser mit, du brauchst keine QR-Bibliothek und ein Wasserzeichen gibt es nicht. Die API nutzt dieselbe Render-Engine wie der QRocodile-Generator: Ein Design, das du im Generator gestaltest, sieht per API genauso aus.
Weil es reines HTTP mit einem Bearer-Token ist, funktioniert es aus jedem Backend und aus dem HTTP-Node von Automatisierungsplattformen wie n8n, Zapier, Make oder KNIME. Typische Aufgaben sind Batch-Läufe über eine Produkt- oder Ticketliste, QR-Codes auf Rechnungen und Versandlabels direkt vom Server und Druck-Workflows, die Vektorausgabe in einem festen Stil benötigen.
Wir rendern, aber wir speichern nicht. Der kodierte Inhalt landet in keiner Datenbank. Erfasst werden nur Metadaten der Anfrage: API-Key, Zeitpunkt, Format und Größe. Genau diese Angaben benötigen wir für Missbrauchsschutz und Nutzungszählung.
Jeder Muster- und Finder-Stil aus dem Generator ist über seine ID verfügbar, dazu Vorlagen, Paletten und Farbverläufe. Baue den QR-Code im Generator und kopiere sein JSON – alle verwendeten IDs stehen darin.
SVG ist Vektor und eignet sich für den Druck, PNG lässt sich in jeder Größe von 64 bis 4.096 Pixel anfordern. Die beiden unterscheiden sich um einen einzigen Parameter derselben Anfrage.
Verwende eines der vorgegebenen Logos oder schicke dein eigenes PNG, JPEG oder SVG als Base64. Die Fehlerkorrektur passt sich an, damit der QR-Code scannbar bleibt.
Farbkombinationen mit zu wenig Kontrast werden automatisch nachjustiert, damit ein QR-Code, der gut aussieht, auch scannbar bleibt.
Dieselbe Anfrage liefert immer dieselben Bytes: Wiederholungen sind gefahrlos, Ergebnisse kannst du bei dir zwischenspeichern.
Trag unten deine E-Mail-Adresse ein und bestätige sie. Der API-Key wird genau einmal angezeigt – kopiere ihn und bewahre ihn sicher auf.
Sende Inhalt und optional ein Design und gib den API-Key als Bearer-Token mit.
Der Response-Body ist das Bild selbst, entweder SVG-Text oder PNG-Bytes. Schreib es in eine Datei, gib es weiter oder lege es dort ab, wo du deine Assets auslieferst.
Jede Render-Anfrage trägt einen API-Key als Bearer-Token. API-Keys sind kostenlos und an eine E-Mail-Adresse gebunden. Deinen bekommst du über das Formular weiter unten auf dieser Seite.
Authorization: Bearer qk_live_… Der API-Key wird genau einmal angezeigt, sobald du den Code bestätigst, denn wir speichern nur einen Hash davon und können das Original nicht wiederherstellen. Halte ihn geheim. Er weist dir die Nutzung zu – wer ihn hat, kann dein Kontingent verbrauchen.
Wenn du den API-Key verlierst, registriere dieselbe Adresse erneut. Mit dem neuen Code wird ein frischer API-Key ausgegeben und der alte wird ungültig. Bis zur Bestätigung funktioniert der bisherige API-Key ganz normal weiter.
Basis-URL und Versions-Präfix sind stabil. Das Design-Schema ist an diese Version gebunden und wird nur erweitert – kommen neue Felder dazu, laufen bestehende Integrationen also weiter.
https://api.qrocodile.io
| Endpunkt | Beschreibung |
|---|---|
| GET /v1/qr | QR-Code aus einem Inhalts-String und optionaler Vorlage rendern |
| POST /v1/qr | QR-Code aus einem Inhalts-String und vollem Design-Schema rendern |
Nimm diesen Endpunkt, wenn die ganze Anfrage in eine URL passt. Er liefert die Bild-Bytes direkt.
| Parameter | Typ | Standard | Beschreibung |
|---|---|---|---|
| content * | string | — | Der zu kodierende String, exakt so übernommen |
| format | enum (svg | png) | svg | Ausgabeformat |
| preset | enum (86 presets) | — | Eine der unten aufgelisteten Vorlagen-IDs |
| size | integer (64–4096) | 1024 | Pixelgröße für die PNG-Ausgabe |
| margin | integer (0–20) | — | Ruhezone, in Modulen |
| dark | string (hex color) | — | Modulfarbe, als Hex |
| bg | string (hex color) | — | Hintergrundfarbe, als Hex |
* Pflichtfeld – alles andere ist optional
Eine Vorlage – im Design-Schema das Feld preset – ist der schnellste Weg zu einem fertig gestalteten QR-Code. Du sendest nur ihre ID – Stile und Farben bringt die Vorlage mit. Nimm eine ID aus der Liste unten.
Alles über eine Vorlage hinaus benötigt das vollständige Design-Schema. Das passt nicht in einen Query-String – siehe Volles Design unten.
Die Antwort ist dieselbe, die Eingabe ist umfangreicher: ein JSON-Body mit dem Inhalt und einem vollständigen Design-Schema. Dieses Schema ist genau das Objekt, das auch der QRocodile-Generator erzeugt – was du dort visuell zusammenstellen kannst, kannst du hier also auch anfragen.
| Feld | Typ | Standard | Beschreibung |
|---|---|---|---|
| content * | string | — | Der zu kodierende String, exakt so übernommen |
| design | QrDesignConfig | {} | Vorlage, Farben, Muster- und Finder-Stile, Logo und Halo. Kopiere es im Generator über „JSON kopieren“ – dabei entsteht genau dieses Objekt. |
| format | enum (svg | png) | svg | Ausgabeformat |
| size | integer (64–4096) | 1024 | Pixelgröße für die PNG-Ausgabe |
| fixContrast | boolean | true | Zu geringen Kontrast nachjustieren, damit der QR-Code scannbar bleibt |
* Pflichtfeld – alles andere ist optional
Baue den QR-Code visuell im Generator. Klicke dann unten rechts in der Vorschau auf den Pfeil nach oben und wähle „JSON kopieren“: Du erhältst genau das Objekt, das dieses Feld erwartet. Als design eingesetzt, entsteht exakt das Bild, das du gesehen hast, mit Logo und Halo.
Ein Feld unterstützt dieser Endpunkt noch nicht: animation, das der Generator für animierte Ausgaben exportiert. Hier entsteht ein einzelnes Bild, ein Design mit diesem Feld wird deshalb mit einem Fehler abgelehnt. Entferne es, wenn du ein Standbild brauchst.
curl -G https://api.qrocodile.io/v1/qr \
-H "Authorization: Bearer $QR_API_KEY" \
--data-urlencode "content=https://qrocodile.io" \
-d "preset=ocean" -d "format=png" -d "size=512" \
--output qr.png const params = new URLSearchParams({
content: 'https://qrocodile.io',
preset: 'ocean',
format: 'svg',
})
const res = await fetch(`https://api.qrocodile.io/v1/qr?${params}`, {
headers: { Authorization: `Bearer ${process.env.QR_API_KEY}` },
})
if (!res.ok) throw new Error(`QR API ${res.status}`)
const svg = await res.text() import os
import requests
res = requests.get(
"https://api.qrocodile.io/v1/qr",
headers={"Authorization": f"Bearer {os.environ['QR_API_KEY']}"},
params={"content": "https://qrocodile.io", "preset": "ocean", "format": "png", "size": 512},
timeout=30,
)
res.raise_for_status()
with open("qr.png", "wb") as f:
f.write(res.content) curl -X POST https://api.qrocodile.io/v1/qr \
-H "Authorization: Bearer $QR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": "WIFI:T:WPA;S:Cafe Guest;P:latte123;;",
"design": {
"preset": "ocean",
"moduleColor": "#0d9488",
"moduleStyleId": "roundedSquares",
"logo": { "id": "wifi", "color": "#0d9488", "regionWidth": 0.25 }
},
"format": "png",
"size": 1024
}' \
--output wifi.png import { writeFile } from 'node:fs/promises'
const res = await fetch('https://api.qrocodile.io/v1/qr', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.QR_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
content: 'WIFI:T:WPA;S:Cafe Guest;P:latte123;;',
design: {
preset: 'ocean',
moduleColor: '#0d9488',
moduleStyleId: 'roundedSquares',
logo: { id: 'wifi', color: '#0d9488', regionWidth: 0.25 },
},
format: 'png',
size: 1024,
}),
})
if (!res.ok) throw new Error(`QR API ${res.status}`)
await writeFile('wifi.png', Buffer.from(await res.arrayBuffer())) import os
import requests
res = requests.post(
"https://api.qrocodile.io/v1/qr",
headers={"Authorization": f"Bearer {os.environ['QR_API_KEY']}"},
json={
"content": "WIFI:T:WPA;S:Cafe Guest;P:latte123;;",
"design": {
"preset": "ocean",
"moduleColor": "#0d9488",
"moduleStyleId": "roundedSquares",
"logo": {"id": "wifi", "color": "#0d9488", "regionWidth": 0.25},
},
"format": "png",
"size": 1024,
},
timeout=30,
)
res.raise_for_status()
with open("wifi.png", "wb") as f:
f.write(res.content) import { writeFile } from 'node:fs/promises'
import { setTimeout as sleep } from 'node:timers/promises'
// One design for the whole run; only the encoded content changes.
const design = { preset: 'ocean', moduleStyleId: 'roundedSquares' }
const skus = ['SKU-001', 'SKU-002', 'SKU-003'] // … a few thousand more
for (const sku of skus) {
const res = await fetch('https://api.qrocodile.io/v1/qr', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.QR_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ content: `https://myshop.com/p/${sku}`, design, format: 'svg' }),
})
if (!res.ok) throw new Error(`${sku}: QR API ${res.status}`)
// arrayBuffer, not text, so switching format to 'png' needs nothing but a new extension.
await writeFile(`out/${sku}.svg`, Buffer.from(await res.arrayBuffer()))
// The limit is 60 renders per minute per key, so one per second is a safe steady rate.
await sleep(1000)
} Die API rendert einen QR-Code pro Anfrage, ein Batch-Durchlauf wird also als Schleife in deiner Anwendung implementiert. Die einzelnen Renderings sind voneinander unabhängig. Du kannst die Schleife also so takten, dass du innerhalb deines Limits bleibst, und sie dann unbeaufsichtigt laufen lassen. Wenn du eine hohe Druckauflage in einem Durchgang brauchst, schreib uns, dann erhöhen wir die Obergrenze.
Ein Fehler kommt nie als defektes Bild zurück. Die Antwort ist JSON mit einem stabilen, maschinenlesbaren Fehlercode; bei Erfolg enthält der Body immer ein Bild:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "body/design/preset Invalid option: expected one of \"classic\"|\"ocean\"|…"
}
} | Status | Wann |
|---|---|
| 400 | Inhalt oder Design haben die Validierung nicht bestanden, oder das Format wird nicht unterstützt. Die Meldung nennt das betroffene Feld und listet bei einer ID die gültigen Optionen auf. |
| 401 | Der API-Key fehlt, ist ungültig, unbekannt oder widerrufen. |
| 413 | Ein eigenes Logo oder eine angefragte PNG-Größe hat das jeweilige Limit überschritten. |
| 422 | Die Eingabe war gültig, ließ sich aber nicht kodieren. In der Praxis heißt das, der Inhalt ist zu lang für einen QR-Code. |
| 429 | Du hast das Limit überschritten. Die Response-Header geben an, wann du es erneut versuchen kannst. |
| 500 | Ein Rendering ist bei uns fehlgeschlagen. Das sollte eigentlich nicht vorkommen. Wir loggen den Fehler, aber absichtlich nicht deinen Inhalt – wenn dir das passiert, hilft uns eine kurze Angabe zu Inhalt und Design, ihn nachzustellen. |
Renderings sind auf 60 Anfragen pro Minute und API-Key begrenzt. Das Limit liegt hoch genug, dass normale Automatisierung es nie erreicht, und niedrig genug, dass ein Skript in einer Endlosschleife auffällt. Weil das Limit am API-Key hängt und nicht an der aufrufenden IP-Adresse, folgt das Budget deiner Integration, egal wo sie läuft. Wenn du für den produktiven Einsatz mehr brauchst, schreib uns: In der Beta erhöhen wir Limits von Hand und sind dabei großzügig.
Jede Render-Antwort trägt diese Header. Eine Schleife kann sich also takten, lange bevor sie ins Limit läuft:
| Header | Bedeutung |
|---|---|
| x-ratelimit-limit | Erlaubte Anfragen pro Minute |
| x-ratelimit-remaining | Verbleibende Anfragen in der laufenden Minute |
| x-ratelimit-reset | Sekunden, bis das Fenster zurückgesetzt wird |
| retry-after | Wartezeit in Sekunden, nur bei Statuscode 429 |
Die API ist reines HTTP. Jede Sprache mit einem HTTP-Client funktioniert damit, die Beispiele oben laufen unverändert. Ein typisierter TypeScript-Client ist in Arbeit, weitere Sprachen folgen; bis dahin ist die OpenAPI-Spezifikation der schnellste Weg dorthin.
Die vollständige Spezifikation liegt unter /docs/json. Daraus erzeugt ein Code-Generator einen typisierten Client in deiner Sprache – inklusive der Design-IDs als Enums.
War das hilfreich?
Teile es mit jemandem, der es brauchen kann.
Pro E-Mail-Adresse gibt es einen kostenlosen API-Key. Adresse unten eintragen, bestätigen – fertig.
Kopiere ihn jetzt, denn er wird nur dieses eine Mal angezeigt. Wir speichern nur einen Hash davon und können das Original nicht wiederherstellen.
Erste Schritte mit deinem API-KeyWir speichern deine E-Mail-Adresse, um den API-Key auszugeben, die Nutzung zu zählen und dich zur API zu erreichen. Nichts weiter, kein Newsletter. Datenschutz
In der Beta nichts. API-Keys gibt es, damit sich Nutzung zuordnen und begrenzen lässt, nicht um abzurechnen. Sollten später bezahlte Stufen kommen, geht es dabei um Volumen. Die kostenlose Stufe bleibt nutzbar.
Rendern kostet uns CPU-Zeit; Nutzung muss deshalb zählbar und der Zugang widerrufbar sein. Außerdem hängen deine Limits so an deiner Integration und nicht an der IP-Adresse, von der sie gerade aufruft.
Gleiche Engine, andere Oberfläche. Die Website ist zum Gestalten eines einzelnen QR-Codes gedacht, die API zum Erzeugen vieler aus deinen eigenen Systemen. Visuell gestalten, dann mit derselben Konfiguration automatisieren.
Bitte nicht. Der API-Key steckt im Authorization-Header, den ein <img>-Tag nicht mitsenden kann – ein solcher Verweis schlägt also einfach fehl. Aus JavaScript ließe sich der Header setzen, dann stünde der API-Key aber im Code, den jeder Besucher lesen kann. Damit könnte jeder dein Kontingent verbrauchen. Die API ist für Aufrufe aus deiner eigenen Anwendung gedacht, nicht aus dem Browser: Rendere den QR-Code vorab – im Build, in einem Skript oder auf dem Server –, lege das Ergebnis bei deinen übrigen Assets ab und liefere es von dort aus. Das ist für deine Besucher auch schneller, weil das Bild dann von deiner eigenen Domain oder deinem CDN kommt und nicht bei jedem Seitenaufruf von uns.
Das ist Absicht. Die Render-Endpunkte akzeptieren den Authorization-Header nicht von Browser-Origins. Genau das verhindert, dass ein API-Key im Frontend-Code landet. Rufe die Render-Endpunkte stattdessen aus deiner Anwendung auf.
Ja. Das maschinenlesbare Dokument ist OpenAPI und liegt unter /docs/json, die lesbare Referenz unter /docs ist Swagger UI – „Swagger“ ist der ältere Name des Formats, deshalb begegnen dir beide. Wie du daraus einen typisierten Client erzeugst, steht oben unter „Clients & SDKs“.
SVG und PNG. SVG ist Vektor und ideal für den Druck, PNG kannst du in jeder Größe zwischen 64 und 4.096 Pixel anfordern. Animierte Ausgabe und PDF gibt es noch nicht.
Ja. Schicke es als Base64-PNG, -JPEG oder -SVG. Alternativ nutzt du eines der vorgegebenen Logos. Von einer URL laden wir ein Logo nie. Ein hochgeladenes SVG bereinigen wir vor der Ausgabe.
Nein. Der Inhalt wird ins Bild kodiert und danach verworfen. Wir loggen Metadaten der Anfrage (API-Key, Zeitpunkt, Format und Größe) für Missbrauchsschutz und Nutzungszählung, aber nie den Inhalt selbst.
Ja. Die erzeugten QR-Codes gehören dir, ohne Namensnennung und ohne Wasserzeichen, in kommerziellen Produkten genauso wie in Druckauflagen.
Ja. Das sind Textformate, keine Funktionen: Ein WLAN-Code ist der String WIFI:T:WPA;S:MeinNetz;P:geheim;;, ein Telefon-Code tel:+4915112345678. Baue den String in deiner Anwendung und sende ihn als content – die API kodiert genau das, was sie bekommt. Wir setzen diese Payloads absichtlich nicht für dich zusammen. Sonst gäbe es ein eigenes Feldvokabular, das du zusätzlich zum ohnehin dokumentierten Format lernen müsstest.
Nein. Die API rendert statische QR-Codes, der Inhalt steckt also im Muster selbst. Damit läuft nichts ab und nichts hängt davon ab, dass wir online bleiben. Nachträglich änderbare Weiterleitungen sind ein anderes Produkt.