API-Dokumentation
Endpoint
https://qr-rechnung-api.ch/api/v1/qr-bill/create
Erstellt eine Schweizer QR-Rechnung und gibt sie als Base64-kodierten String zurück.
Die API akzeptiert GET und POST (Form-Data oder JSON-Body).
Parameter werden in jeder Schreibweise akzeptiert: CreditorName, creditorName, creditor_name oder creditorname.
Authentifizierung
Senden Sie Ihren API-Key im Header:
X-API-Key: Ihr_API_Key
Den API-Key erstellen Sie im Dashboard unter «API Keys». Ohne gültigen Key wird HTTP 401 zurückgegeben.
Pflicht-Parameter
| Parameter | Beschreibung | Beispiel |
|---|---|---|
Account |
IBAN oder QR-IBAN | CH4431999123000889012 |
CreditorName |
Name des Empfängers | Muster AG |
CreditorZip |
PLZ des Empfängers | 8000 |
CreditorTown |
Ort des Empfängers | Zürich |
CreditorCountryCode |
Ländercode (Standard: CH) | Siehe Werte ↓ |
Optionale Parameter
Zahlung
| Parameter | Beschreibung | Standard |
|---|---|---|
Amount |
Betrag (Dezimal). Leer = offener Betrag | — |
Currency |
Währung | Siehe Werte ↓ |
ReferenceNr |
Referenznummer (QR oder SCOR) | — |
UnstructuredMessage |
Mitteilung (Freitext) | — |
BillInformation |
Swico S1 strukturierte Info Pro | — |
Empfänger (Creditor)
| Parameter | Beschreibung |
|---|---|
CreditorStreetName |
Strasse des Empfängers |
CreditorHouseNumber |
Hausnummer des Empfängers |
Zahler (Debtor)
| Parameter | Beschreibung |
|---|---|
DebtorName | Name des Zahlers |
DebtorStreetName | Strasse des Zahlers |
DebtorHouseNumber | Hausnummer des Zahlers |
DebtorZip | PLZ des Zahlers |
DebtorTown | Ort des Zahlers |
DebtorCountryCode | Ländercode des Zahlers — Siehe Werte ↓ |
Format-Parameter
Für volle Kontrolle über das Ausgabeformat. Diese Parameter überschreiben die einfachen Parameter, wenn beide vorhanden sind.
| Parameter | Werte | Standard |
|---|---|---|
GraphicsFormat |
Siehe Werte ↓ | |
OutputSize |
Siehe Werte ↓ | a4 |
SeparatorType |
Siehe Werte ↓ | dashed-scissors |
Language |
Siehe Werte ↓ | DE |
Resolution |
≥ 144 DPI (für PNG) | 144 |
CreditorCountryCode / DebtorCountryCode
| Wert | Beschreibung |
|---|---|
CH | Schweiz (Standard) |
LI | Liechtenstein |
Currency
| Wert | Beschreibung |
|---|---|
CHF | Schweizer Franken (Standard) |
EUR | Euro |
GraphicsFormat
| Wert | Beschreibung | Verfügbarkeit |
|---|---|---|
PDF | PDF-Dokument (Standard) | Alle Pläne |
PNG | PNG-Bild | Alle Pläne |
SVG | SVG-Vektorgrafik | Pro / Enterprise |
OutputSize
| Wert | Beschreibung | Verfügbarkeit |
|---|---|---|
qr-code | Nur QR-Code | Pro / Enterprise |
qr-code-padded | QR-Code mit Rand | Alle Pläne |
payment-part | Zahlteil ohne Empfangsschein | Pro / Enterprise |
bill | Zahlungsteil | Pro / Enterprise |
bill-with-separator | Zahlungsteil mit Trennlinie | Alle Pläne |
a4 | Ganze A4-Seite | Pro / Enterprise |
SeparatorType
| Wert | Beschreibung | Verfügbarkeit |
|---|---|---|
dashed | Gestrichelte Linie | Pro / Enterprise |
dashed-scissors | Gestrichelte Linie mit Schere (Standard) | Alle Pläne |
dotted | Gepunktete Linie | Pro / Enterprise |
dotted-scissors | Gepunktete Linie mit Schere | Pro / Enterprise |
solid | Durchgezogene Linie | Pro / Enterprise |
solid-scissors | Durchgezogene Linie mit Schere | Pro / Enterprise |
none | Keine Trennlinie | Pro / Enterprise |
Language
| Wert | Beschreibung |
|---|---|
DE | Deutsch (Standard) |
FR | Französisch |
IT | Italienisch |
EN | Englisch |
RM | Rätoromanisch |
Antwort-Format
{
"success": true,
"message": "QR-Rechnung erfolgreich erstellt",
"base64Content": "JVBERi0....",
"format": "PDF",
"billData": {
"account": "CH4431999123000889012",
"amount": 1500,
"currency": "CHF",
"creditor": {
"name": "Muster AG",
"street": "Hauptstrasse",
"houseNo": "10",
"postalCode": "8000",
"town": "Zürich",
"countryCode": "CH"
},
"debtor": null,
"reference": "210000000003139471430009017"
}
}
Das Feld base64Content enthält die generierte QR-Rechnung als Base64-String.
Dekodieren Sie diesen, um die Datei (PDF, PNG oder SVG) zu erhalten.
billData gibt die verarbeiteten Rechnungsdaten zurück.
{
"isSuccess": false,
"success": false,
"message": "Fehlerbeschreibung"
}
| HTTP-Code | Bedeutung |
|---|---|
| 200 | Erfolgreich |
| 400 | Ungültige Parameter |
| 401 | Fehlender oder ungültiger API-Key |
| 403 | Feature nicht in Ihrem Plan verfügbar |
| 429 | Monatliches Limit erreicht (Free-Plan) |
IBAN und Referenznummern
Die API erkennt automatisch den IBAN-Typ anhand der Institutsnummer (IID) an Position 5–9 der IBAN:
| IBAN-Typ | Erkennung | Beispiel |
|---|---|---|
| QR-IBAN | IID zwischen 30000 und 31999 | CH4431999123000889012 |
| Normale IBAN | Alle anderen IID | CH9300762011623852957 |
Die IBAN muss immer 21 Zeichen lang sein und mit CH oder LI beginnen.
QR-IBAN → QR-Referenz (QRR)
Bei einer QR-IBAN ist eine QR-Referenznummer Pflicht. Die QR-Referenz besteht aus 27 Ziffern: 26 Ziffern Basis + 1 Prüfziffer (Modulo 10, rekursiv). Die API unterstützt Sie bei der Vervollständigung:
Was Sie senden können:
| Ihre Eingabe | Länge | Was die API macht | Ergebnis |
|---|---|---|---|
3139471430009017 |
< 26 Ziffern | Füllt links mit Nullen auf 26 Stellen, berechnet Prüfziffer | 00000000003139471430009017 + Prüfziffer |
21000000000313947143000901 |
26 Ziffern | Berechnet Prüfziffer und hängt sie an | 210000000003139471430009017 |
210000000003139471430009017 |
27 Ziffern | Prüft die Prüfziffer. Falls falsch, wird sie korrigiert. | 210000000003139471430009017 |
Beispiel:
Account: CH4431999123000889012 (QR-IBAN, IID = 31999)
ReferenceNr: 210000000003139471430009017
→ Typ: QRR
→ Referenz auf der Rechnung: 21 00000 00003 13947 14300 09017
Kurzform-Beispiel:
Account: CH4431999123000889012
ReferenceNr: 3139471430009017 (nur 16 Ziffern)
→ API ergänzt zu: 00000000003139471430009017 (26 Ziffern)
→ API berechnet Prüfziffer und hängt sie an
→ Ergebnis: 27 Ziffern (26 + Prüfziffer)
Normale IBAN → SCOR-Referenz (ISO 11649)
Bei einer normalen IBAN können Sie optional eine SCOR-Referenz (Structured Creditor Reference) mitgeben. Die SCOR beginnt mit «RF», gefolgt von 2 Prüfziffern und einer alphanumerischen Referenz (max. 21 Zeichen).
Die API vervollständigt unvollständige SCOR-Referenzen automatisch:
Was Sie senden können:
| Ihre Eingabe | Format | Was die API macht | Ergebnis |
|---|---|---|---|
RF18539007547034 |
Vollständige SCOR | Prüft und übernimmt | RF18539007547034 |
539007547034 |
Nur der Referenzteil | Berechnet RF + Prüfziffern | RF18539007547034 |
O00WER |
Alphanumerisch | Berechnet RF + Prüfziffern | RF54O00WER |
RECHNUNG2024 |
Alphanumerisch | Berechnet RF + Prüfziffern | RF50RECHNUNG2024 |
Beispiel:
Account: CH9300762011623852957 (Normale IBAN, IID = 07620)
ReferenceNr: O00WER
→ API erkennt: Keine gültige SCOR → Vervollständigung
→ API berechnet: RF54O00WER
→ Typ: SCOR
→ Referenz auf der Rechnung: RF54O00WER
Normale IBAN → Ohne Referenz (NON)
Bei einer normalen IBAN können Sie die Referenznummer auch komplett weglassen. Das ist z.B. für Spenden oder einfache Zahlungen nützlich.
Account: CH9300762011623852957 (Normale IBAN)
ReferenceNr: (leer / nicht angegeben)
→ Typ: NON
→ Keine Referenz auf der Rechnung
Automatische Erkennung — Übersicht
Die API entscheidet automatisch basierend auf IBAN-Typ und Eingabe:
| IBAN-Typ | Referenznummer | Ergebnis |
|---|---|---|
| QR-IBAN | 210000000003139471430009017 |
✓ QRR — übernommen/korrigiert |
| QR-IBAN | 3139471430009017 |
✓ QRR — aufgefüllt + Prüfziffer |
| QR-IBAN | (leer) | ✗ Fehler — QR-IBAN benötigt Referenz |
| QR-IBAN | RF18539007547034 |
✗ Fehler — QR-IBAN akzeptiert keine SCOR |
| Normale IBAN | RF18539007547034 |
✓ SCOR — validiert |
| Normale IBAN | O00WER |
✓ SCOR — vervollständigt zu RF54O00WER |
| Normale IBAN | (leer) | ✓ NON — ohne Referenz |
| Normale IBAN | 210000000003139471430009017 |
✗ Fehler — Normale IBAN benötigt SCOR Referenz |
Migration von Legacy-API
Um Ihnen die Migration von der alten QR-Rechnung-API (Legacy) zur neuen Version zu erleichtern, haben wir einen Legacy-Mode implementiert. Damit können Sie die bisherigen Header- und GET-Parameter beibehalten. Sie können also weiterhin Ihre bestehenden Systeme nutzen, ohne grosse Anpassungen vornehmen zu müssen. Wenn Sie also einen möglichst effizienten Umstieg planen, dann können Sie den Grossteil der bisherigen Implementierungen übernehmen. Verpflichtend ist lediglich die Umstellung des Endpoints:
https://qr-rechnung-api.ch/api/v1/qr-bill/create?CreditorName=Muster+GmbH&CreditorStreetName=...
{
"isSuccess": true,
"success": true,
"message": "QR-Rechnung erfolgreich erstellt",
"base64Content": "JVBERi0....",
"format": "PDF"
}
Falls Sie den Aufwand nicht scheuen, dann empfehlen wir die Umstellung auf das neue JSON-Format. Damit können Sie alle Parameter in einem einzigen JSON-Body übergeben, was die Lesbarkeit und Wartbarkeit verbessert. Zudem profitieren Sie von neuen Features und mehr Kontrolle.
Code-Beispiele
curl -X POST "https://qr-rechnung-api.ch/api/v1/qr-bill/create" \
-H "X-API-Key: Ihr_API_Key" \
-H "Content-Type: application/json" \
-H "Cache-Control: no-cache" \
-d '{
"Account": "CH4431999123000889012",
"CreditorName": "Muster AG",
"CreditorZip": "8000",
"CreditorTown": "Zürich",
"CreditorCountryCode": "CH",
"Amount": "199.95",
"Currency": "CHF",
"ReferenceNr": "210000000003139471430009017",
"GraphicsFormat": "PNG",
"OutputSize": "bill-with-separator"
}'
$apiUrl = 'https://qr-rechnung-api.ch/api/v1/qr-bill/create';
$apiKey = 'Ihr_API_Key';
$payload = [
'Account' => 'CH4431999123000889012',
'CreditorName' => 'Muster AG',
'CreditorZip' => '8000',
'CreditorTown' => 'Zürich',
'CreditorCountryCode' => 'CH',
'Amount' => '195.95',
'Currency' => 'CHF',
'ReferenceNr' => '210000000003139471430009017',
'GraphicsFormat' => 'PNG',
'OutputSize' => 'bill-with-separator'
];
$ch = curl_init($apiUrl);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'X-API-Key: ' . $apiKey,
'Content-Type: application/json',
'Cache-Control: no-cache'
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
if ($data['success']) {
$pngContent = base64_decode($data['base64Content']);
file_put_contents('rechnung.png', $pngContent);
} else {
echo 'Fehler: ' . $data['message'];
}
const response = await fetch('https://qr-rechnung-api.ch/api/v1/qr-bill/create', {
method: 'POST',
headers: {
'X-API-Key': 'Ihr_API_Key',
'Content-Type': 'application/json',
'Cache-Control': 'no-cache'
},
body: JSON.stringify({
Account: 'CH4431999123000889012',
CreditorName: 'Muster AG',
CreditorZip: '8000',
CreditorTown: 'Zürich',
CreditorCountryCode: 'CH',
Amount: '199.95',
Currency: 'CHF',
ReferenceNr: '210000000003139471430009017',
GraphicsFormat: 'PNG',
OutputSize: 'bill-with-separator',
}),
});
const data = await response.json();
if (data.success) {
const byteCharacters = atob(data.base64Content);
const byteNumbers = new Array(byteCharacters.length);
for (let i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
const blob = new Blob([new Uint8Array(byteNumbers)], { type: 'application/pdf' });
const url = URL.createObjectURL(blob);
window.open(url);
} else {
console.error('Fehler:', data.message);
}
import requests
import base64
response = requests.post(
'https://qr-rechnung-api.ch/api/v1/qr-bill/create',
headers={
'X-API-Key': 'Ihr_API_Key',
'Content-Type': 'application/json',
'Cache-Control': 'no-cache'
},
json={
'Account': 'CH4431999123000889012',
'CreditorName': 'Muster AG',
'CreditorZip': '8000',
'CreditorTown': 'Zürich',
'CreditorCountryCode': 'CH',
'Amount': '199.95',
'Currency': 'CHF',
'ReferenceNr': '210000000003139471430009017',
'GraphicsFormat': 'PNG',
'OutputSize': 'bill-with-separator',
}
)
data = response.json()
if data['success']:
png_bytes = base64.b64decode(data['base64Content'])
with open('rechnung.png', 'wb') as f:
f.write(png_bytes)
else:
print(f"Fehler: {data['message']}")
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "Ihr_API_Key");
client.DefaultRequestHeaders.Add("Content-Type", "application/json");
client.DefaultRequestHeaders.Add("Cache-Control", "no-cache");
var payload = new {
Account = "CH4431999123000889012",
CreditorName = "Muster AG",
CreditorZip = "8000",
CreditorTown = "Zürich",
CreditorCountryCode = "CH",
Amount = "199.95",
Currency = "CHF",
ReferenceNr = "210000000003139471430009017",
GraphicsFormat = "PNG",
OutputSize = "bill-with-separator"
};
var json = System.Text.Json.JsonSerializer.Serialize(payload);
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");
var response = await client.PostAsync(
"https://qr-rechnung-api.ch/api/v1/qr-bill/create", content);
var result = await response.Content.ReadAsStringAsync();
var data = System.Text.Json.JsonDocument.Parse(result);
if (data.RootElement.GetProperty("success").GetBoolean())
{
var base64 = data.RootElement.GetProperty("base64Content").GetString();
var pngBytes = Convert.FromBase64String(base64);
File.WriteAllBytes("rechnung.png", pngBytes);
}
[...]
Dim payload As String
payload = "{" & _
"""Account"":""" & credIban & """," & _
"""CreditorName"":""" & credName & """," & _
"""CreditorStreetName"":""" & credStreet & """," & _
"""CreditorHouseNumber"":""" & credHouseNo & """," & _
"""CreditorZip"":""" & credZip & """," & _
"""CreditorTown"":""" & credTown & """," & _
"""CreditorCountryCode"":""" & credCountry & """," & _
"""DebtorName"":""" & debName & """," & _
"""DebtorStreetName"":""" & debStreet & """," & _
"""DebtorHouseNumber"":""" & debHouseNo & """," & _
"""DebtorZip"":""" & debZip & """," & _
"""DebtorTown"":""" & debTown & """," & _
"""DebtorCountryCode"":""" & debCountry & """," & _
"""Amount"":""" & amount & """," & _
"""Currency"":""" & curr & """," & _
"""ReferenceNr"":""" & refNr & """," & _
"""UnstructuredMessage"":""" & message & """," & _
"""GraphicsFormat"":""PNG""," & _
"""OutputSize"":""qr-code-padded""," & _
"""Language"":""DE""" & _
"}"
Dim http As Object
Set http = CreateObject("MSXML2.XMLHTTP.6.0")
http.Open "POST", apiUrl, False
http.SetRequestHeader "Content-Type", "application/json; charset=utf-8"
http.SetRequestHeader "Cache-Control", "no-cache"
http.SetRequestHeader "X-API-KEY", apiKey
http.SetRequestHeader "User-Agent", "Mozilla/5.0"
http.Send payload
Dim resp As String
resp = http.responseText
[...]
Makros aktivieren: rechte Maustaste -> Eigeschaften -> Haken bei "Zulassen" ganz unten aktivieren