Developer API

Generate Swiss QR-Bill Invoices with One API Call

Create compliant Swiss QR-bill invoices in seconds. One POST request returns a complete PDF with payment slip—ready for your customers. No API key needed to start testing.

Magic Heidi Invoice Generation

Building QR-Bills Yourself? Here's the Reality.

Creating Swiss QR-bill invoices manually wastes hours every month. Building your own generator means navigating complex SIX regulations, structured address requirements, and QR-IBAN validation rules.

📋
Complex RegulationsSIX Implementation Guidelines v2.3 compliance
🏠
Structured AddressesOnly structured formats permitted since Nov 2025
Validation RulesQR-IBAN, reference types, amount limits
Quick Start

Your First Invoice in 60 Seconds

Send a POST request to generate a complete Swiss QR-bill invoice.

curl -X POST 'https://europe-west6-magic-heidi.cloudfunctions.net/create_invoice_abstract_v1d' \
  -H 'Content-Type: application/json' \
  -d '{
    "data": {
      "language": "en",
      "file_name": "invoice-001.pdf",
      "invoice_number": 1,
      "invoice_date": "15/01/2025",
      "user_details": {
        "name": "Your Company GmbH",
        "address": "Bahnhofstrasse 10",
        "zip": "8001",
        "city": "Zürich",
        "iban": "CH93 0076 2011 6238 5295 7"
      },
      "customer_details": {
        "name": "Customer AG",
        "address": "Rue du Marché 5",
        "zip": "1204",
        "city": "Genève"
      },
      "invoice_items": [
        {
          "description": "Consulting services",
          "quantity": 8,
          "unit_price": 150.00
        }
      ]
    }
  }'

The response contains a URL to your generated PDF:

{
  "result": "https://storage.googleapis.com/.../invoice-001.pdf"
}

That's it. A complete, compliant Swiss invoice with QR payment slip.

Why Use an API for Swiss QR-Bills?

Since October 2022, Swiss QR-bills replaced all legacy payment slips. Every invoice to Swiss customers now requires a standardized QR code containing payment data. Building this yourself means weeks of development and ongoing maintenance as regulations change.

🇨🇭 Swiss Hosted
Fully Compliant
🔄 Auto-Updated
🚀 Free Testing
📜
SIX Guidelines v2.3

Full compliance since November 2025

🏠
Structured Addresses

Automatically parsed and formatted

💰
Amount Validation

CHF/EUR 0.01 to 999,999,999.99

🏦
IBAN Verification

Swiss & Liechtenstein only

API Reference

Complete Documentation

Hosted in Zurich (europe-west6) for optimal Swiss latency and data residency.

Endpoint

POST https://europe-west6-magic-heidi.cloudfunctions.net/create_invoice_abstract_v1d

Required Parameters

ParameterTypeDescription
file_namestringOutput PDF filename
invoice_numberintegerInvoice reference number
invoice_datestringDate in DD/MM/YYYY format
user_detailsobjectYour company details
customer_detailsobjectRecipient details
invoice_itemsarrayLine items for the invoice

user_details object:

{
  "name": "Company Name",
  "address": "Street and number",
  "zip": "8001",
  "city": "Zürich",
  "iban": "CH93 0076 2011 6238 5295 7"
}

customer_details object:

{
  "name": "Customer Name",
  "address": "Street and number",
  "zip": "1204",
  "city": "Genève"
}

invoice_items array:

[
  {
    "description": "Service description",
    "quantity": 1.5,
    "unit_price": 100.00
  }
]
Code Samples

Integration in Your Language

Ready-to-use code samples for popular programming languages.

Python

import requests
import json

url = "https://europe-west6-magic-heidi.cloudfunctions.net/create_invoice_abstract_v1d"

payload = {
    "data": {
        "language": "de",
        "currency": "CHF",
        "file_name": "rechnung-2025-001.pdf",
        "invoice_number": 1,
        "invoice_date": "15/01/2025",
        "vat_enabled": True,
        "vat_percentage": 0.081,
        "vat_number": "CHE-123.456.789",
        "user_details": {
            "name": "Muster GmbH",
            "address": "Bahnhofstrasse 10",
            "zip": "8001",
            "city": "Zürich",
            "iban": "CH93 0076 2011 6238 5295 7"
        },
        "customer_details": {
            "name": "Kunde AG",
            "address": "Hauptstrasse 1",
            "zip": "3000",
            "city": "Bern"
        },
        "invoice_items": [
            {
                "description": "Beratungsleistungen Januar 2025",
                "quantity": 10,
                "unit_price": 180.00
            },
            {
                "description": "Reisekosten",
                "quantity": 1,
                "unit_price": 45.50
            }
        ]
    }
}

response = requests.post(url, json=payload)
result = response.json()

print(f"Invoice URL: {result['result']}")

Node.js (Axios)

const axios = require('axios');

const url = 'https://europe-west6-magic-heidi.cloudfunctions.net/create_invoice_abstract_v1d';

const payload = {
  data: {
    language: 'fr',
    currency: 'CHF',
    file_name: 'facture-2025-001.pdf',
    invoice_number: 1,
    invoice_date: '15/01/2025',
    logo_url: 'https://your-domain.ch/logo.png',
    user_details: {
      name: 'Votre Entreprise Sàrl',
      address: 'Rue du Lac 15',
      zip: '1003',
      city: 'Lausanne',
      iban: 'CH93 0076 2011 6238 5295 7'
    },
    customer_details: {
      name: 'Client SA',
      address: 'Avenue de la Gare 8',
      zip: '1201',
      city: 'Genève'
    },
    invoice_items: [
      {
        description: 'Services de développement',
        quantity: 40,
        unit_price: 120.00
      }
    ]
  }
};

axios.post(url, payload)
  .then(response => {
    console.log('Invoice URL:', response.data.result);
  })
  .catch(error => {
    console.error('Error:', error.response?.data || error.message);
  });

PHP (cURL)

<?php

$url = 'https://europe-west6-magic-heidi.cloudfunctions.net/create_invoice_abstract_v1d';

$payload = [
    'data' => [
        'language' => 'it',
        'file_name' => 'fattura-2025-001.pdf',
        'invoice_number' => 1,
        'invoice_date' => '15/01/2025',
        'user_details' => [
            'name' => 'La Tua Azienda Sagl',
            'address' => 'Via Nassa 20',
            'zip' => '6900',
            'city' => 'Lugano',
            'iban' => 'CH93 0076 2011 6238 5295 7'
        ],
        'customer_details' => [
            'name' => 'Cliente SA',
            'address' => 'Piazza Grande 5',
            'zip' => '6600',
            'city' => 'Locarno'
        ],
        'invoice_items' => [
            [
                'description' => 'Servizi di consulenza',
                'quantity' => 5,
                'unit_price' => 200.00
            ]
        ]
    ]
];

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);

$response = curl_exec($ch);
curl_close($ch);

$result = json_decode($response, true);
echo "Invoice URL: " . $result['result'];
Error Handling

Response Codes & Validation

The API returns standard HTTP status codes for easy error handling.

200 OK

{
  "result": "https://storage.googleapis.com/.../invoice.pdf"
}

422 Unprocessable Entity

{
  "error": "Provided IBAN is invalid"
}

Common validation errors:

  • Invalid IBAN format or checksum
  • Missing required parameters
  • Invalid date format (must be DD/MM/YYYY)
  • Amount outside valid range

500 Internal Server Error

These are monitored internally. If you encounter one, email hello@magicheidi.ch with the timestamp for troubleshooting.

November 2025 Update

Automatic Compliance Updates

Since November 22, 2025, SIX Implementation Guidelines version 2.3 requires structured addresses only. All addresses must include street name, house number, postal code, city, and country. Magic Heidi's API handles this automatically—when you provide an address like 'Bahnhofstrasse 10', we parse and structure it correctly for the QR code.

Swiss Business Compliance
FAQ

Frequently Asked Questions

Do I need a QR-IBAN?

Only if you want to use QR-Reference numbers (QRR). For Creditor References (SCOR) or no reference, a regular Swiss IBAN works fine. Check positions 5-9 of your IBAN—if the number is between 30000 and 31999, it's a QR-IBAN.

Can I generate invoices in Euros?

Yes. Set "currency": "EUR" in your request. Both CHF and EUR are supported per Swiss QR-bill specifications.

Does this work for international customers?

The QR-bill standard only supports Swiss and Liechtenstein IBANs. For international invoices, you'll need a Swiss bank account.

Can I generate just the QR payment slip?

Yes. Set "qr_only": true to receive only the QR payment slip without the full invoice document.

How do I add my company logo?

Include a logo_url parameter with a publicly accessible URL to your logo image. We recommend PNG or SVG format.

Is there a rate limit?

For testing without an API key, reasonable usage is expected. For production applications, contact hello@magicheidi.ch to request an API key with defined limits.

Start Generating Invoices Today

Test the API with the code samples above—no authentication needed. Request an API key for production use.

Get Started

  1. Test the API with the code samples above—no authentication needed
  2. Integrate into your application using your preferred language
  3. Request an API key at hello@magicheidi.ch for production use

For the complete API documentation and updates, visit our GitHub repository.

Questions? Reach out to hello@magicheidi.ch. We typically respond within 24 hours.


Magic Heidi is a Swiss invoicing platform built for freelancers and small businesses. Available on iOS, Android, Mac, Windows, and web.