Rechnungserstellungs-API

Erstellen Sie professionelle Rechnungs-PDFs programmatisch von Ihrem eigenen Server aus — geeignet für interne Systeme, Marktplätze oder Ihr eigenes SaaS-Produkt.

1. Authentifizierung#

Erstellen Sie einen API-Schlüssel auf app.invosend.com/settings/api-keys. Ein kostenpflichtiger Workspace-Plan und die Owner-Rolle sind erforderlich.

Senden Sie den Schlüssel als Bearer-Token im Authorization-Header bei jeder Anfrage:

Authorization: Bearer isk_live_xxxxxxxxxxxxxxxxxxxxxxxx
Fehlende, fehlerhaft formatierte, ungültige oder widerrufene API-Schlüssel werden mit 403 abgelehnt. Schlüssel werden auch abgelehnt, wenn der Workspace auf einem kostenlosen Plan ist, gesperrt wurde oder abgelaufen ist.

2. Endpunkt#

POST/api/invoices/generate-external

Basis-URL: https://app.invosend.com

Maschinenlesbare API-Beschreibung: OpenAPI 3.1 und Postman collection. Importieren Sie eine davon in Postman, Insomnia oder einen SDK-Generator.

3. Anfragetext#

FeldTypErforderlichBeschreibung
customer_namestringJaName des Kunden oder Rechnungsempfängers.
customer_emailstringNeinGültige E-Mail-Adresse. Die mit diesem Aufruf erstellte Rechnung wird nicht per E-Mail versendet (diese API versendet keine E-Mails). Erforderlich bei wiederkehrenden Rechnungen: Jede danach erzeugte Rechnung wird an diese Adresse gesendet.
customer_tax_idstringNeinSteuernummer des Kunden (in Indonesien NPWP, bis zu 40 Zeichen). Wird auf der Rechnung unter der Kundenadresse gedruckt.
itemsarrayJaMindestens 1 gültiges Element mit Beschreibung, quantity > 0 und price >= 0.
items[].descriptionstringNeinProdukt- oder Dienstleistungsname. Wenn leer, wird Item verwendet.
items[].quantitynumberJaAnzahl der Einheiten mit bis zu 2 Dezimalstellen (z. B. 1.5 Stunden), von 0.01 bis 999.999.
items[].pricenumberJaPreis pro Einheit.
items[].discountnumberNeinRabattbetrag pro Position. Standardmäßig 0.
currencystringNeinWährungscode wie IDR oder USD. Standardmäßig IDR.
tax_ratenumberNeinSteuerprozentsatz, berechnet aus der Zwischensumme nach Rabatt. Standardmäßig 0.
due_datestringNeinFormat YYYY-MM-DD. Standardmäßig 14 Tage nach Erstellung.
notesstringNeinZusätzliche Notizen, die auf der Rechnung angezeigt werden.
items[].unitstringNeinEinheitsbezeichnung neben der Menge, z. B. pcs oder hour.
items[].tax_ratenumberNeinPositionsspezifischer Steuersatz-Override (0-100). Weglassen, um den rechnungsweiten tax_rate für diese Position zu verwenden.
discount_totalnumberNeinRechnungsweiter Rabatt. Er wird vor der Steuer abgezogen, die Steuer wird also auf den rabattierten Betrag berechnet (anteilig nach Wert auf die Positionen verteilt). Standardmäßig 0.
templatestringNeinID der zu verwendenden Rechnungsvorlage. Verfügbare Vorlagen listet GET /api/invoices/external/templates auf. Ohne Angabe gilt die in den Einstellungen gewählte Standardvorlage, danach die Standardvorlage von Invosend.
document_languagestringNeinSprache der Wörter im Rechnungsdokument (PDF und E-Mail): en (Standard), id, es, fr, de, nl, it, pt, zh, ja, hi, ar (Indonesisch, Spanisch, Französisch, Deutsch, Niederländisch, Italienisch, brasilianisches Portugiesisch, vereinfachtes Chinesisch, Japanisch, Hindi, Arabisch). Jeder andere Wert wird mit einem Fehler abgelehnt. Das einfache integrierte Layout, das nur ohne Vorlage verwendet wird, ist immer englisch.
custom_payment_notesstringNeinZusätzliche Zahlungshinweise, die auf dem PDF angezeigt werden.
footer_textstringNeinKurzer Text am unteren Rand des PDFs.
is_recurringbooleanNeinErstellt eine wiederkehrende Serie. Diese Rechnung ist die erste; die folgenden werden automatisch nach Zeitplan erzeugt und an customer_email gesendet, jeweils mit 1 Rechnungsguthaben. Erfordert einen Plan mit der Funktion für wiederkehrende Rechnungen sowie recurring_interval und customer_email.
recurring_intervalstringNeinWie oft sich die Serie wiederholt: einer von weekly, fortnightly, monthly, quarterly, semi-annually, yearly. Erforderlich, wenn is_recurring true ist.
recurring_countintegerNeinGesamtzahl der Rechnungen der Serie, diese erste eingeschlossen: eine ganze Zahl von 2 bis 121. Standard ist 4. Verwenden Sie dieses Feld oder recurring_end_date, nicht beide.
recurring_end_datestringNeinDatum, nach dem keine weiteren Rechnungen erzeugt werden, YYYY-MM-DD, in der Zukunft. Verwenden Sie dieses Feld oder recurring_count, nicht beide.
payment_gatewaystringNeinEiner von midtrans, xendit, stripe, paypal, razorpay, mollie. Das Gateway muss im Workspace bereits verbunden sein.
payment_accountstringNeinID eines bestehenden Zahlungskontos (Bankdaten), das der Rechnung zugeordnet werden soll.

Vollständiges Anfragebeispiel:

curl -X POST https://app.invosend.com/api/invoices/generate-external \
  -H "Authorization: Bearer isk_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_name": "Acme Corp",
    "customer_email": "billing@acme.com",
    "items": [
      { "description": "Consulting Services", "quantity": 2, "price": 500, "tax_rate": 11 }
    ],
    "discount_total": 50,
    "currency": "EUR",
    "notes": "Thank you for your business."
  }'

Beispiel für eine wiederkehrende Rechnung (die erste jetzt, danach eine pro Monat, insgesamt 6):

curl -X POST https://app.invosend.com/api/invoices/generate-external \
  -H "Authorization: Bearer isk_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_name": "Acme Corp",
    "customer_email": "billing@acme.com",
    "items": [
      { "description": "Monthly retainer", "quantity": 1, "price": 2500 }
    ],
    "currency": "EUR",
    "recurring_interval": "monthly",
    "recurring_count": 6
  }'
Um nach einem Timeout oder Netzwerkfehler sicher zu wiederholen, fügen Sie einen Idempotency-Key-Header hinzu (1-255 Zeichen, zum Beispiel eine pro Rechnung erzeugte UUID). War die erste Anfrage erfolgreich, liefert die Wiederholung dieselbe Antwort mit dem Header Idempotent-Replayed: true, ohne eine weitere Rechnung zu erstellen oder ein weiteres Guthaben zu verbrauchen (credits_remaining ist der Wert des ersten Aufrufs). Schlüssel werden 24 Stunden pro Workspace gespeichert. Nur erfolgreiche Antworten werden gespeichert, daher kann eine fehlgeschlagene Anfrage mit demselben Schlüssel wiederholt werden.

4. Antwort#

200 OK bedeutet, dass die Rechnung erstellt und das PDF generiert wurde:

{
  "data": {
    "id": "cjld2cjxh0000qzrmn831i7rn",
    "invoice_number": "INV-1-202609-0016",
    "pdf_url": "https://cdn.invosend.com/company/1/pdf/Invoice_INV_1_202609_0016_UNPAID_0da2beeabb.pdf",
    "credits_remaining": 24,
    "is_recurring": false,
    "template": {
      "id": "k3p9x2m7c0000abcd1234efgh",
      "name": "Classic",
      "source": "system_default"
    }
  }
}
credits_remaining ist null, wenn der Workspace über ein unbegrenztes Kontingent verfügt. id identifiziert diese Rechnung für die untenstehenden zusätzlichen Endpunkte. Über diese API erstellte Rechnungen erscheinen auch in der Workspace-Rechnungsliste und verwenden dieselbe Rechnungsnummernfolge wie manuell erstellte Rechnungen. Rechnungsnummern haben die Form INV-{Workspace-ID}-{JJJJMM}-{Folgenummer}. Bei einer wiederkehrenden Rechnung enthält die Antwort zusätzlich ein Objekt recurring: schedule_id, interval, occurrences, next_issue_date, end_date. recurring.schedule_id ist die ID für die wiederkehrenden Endpunkte weiter unten.

5. Fehlercodes#

StatusUrsache
400Erforderliche Felder fehlen oder sind ungültig: customer_name, leere items, kein gültiges Element, ein nicht erkanntes payment_gateway, ein für diesen Workspace nicht verbundenes payment_gateway oder, bei einer wiederkehrenden Rechnung, ein fehlendes recurring_interval bzw. customer_email oder ein ungültiges recurring_count / recurring_end_date. Dieser Status wird auch zurückgegeben, wenn das PDF nicht erstellt werden konnte: Wiederholen Sie die Anfrage (es wird kein Guthaben abgezogen).
402Das invoice_credits-Guthaben des Workspace ist leer. Laden Sie Guthaben auf, um fortzufahren.
403Der Authorization-Header fehlt oder ist fehlerhaft formatiert, der API-Schlüssel ist ungültig oder widerrufen, oder der Workspace-Plan enthält keinen API-Zugriff.
403 (wiederkehrend)is_recurring wurde gesetzt, aber der Workspace-Plan enthält keine wiederkehrenden Rechnungen.
409Eine Anfrage mit demselben Idempotency-Key wird noch verarbeitet. Versuchen Sie es gleich erneut.
422Der Idempotency-Key wurde bereits mit einem anderen Anfrage-Body verwendet. Verwenden Sie für eine neue Rechnung einen neuen Schlüssel.
429Ratenlimit überschritten. Siehe Abschnitt Ratenlimit.

6. Ratenlimit#

UmfangLimit
Pro Workspace (alle API-Anfragen zusammen)Professional 10/min · Specialist 20/min · Business 30/min · Enterprise 60/min
Pro IP-Adresse (alle API-Anfragen zusammen)30 Anfragen/Minute
Aktive API-Schlüssel pro WorkspaceProfessional 3 · Specialist 5 · Business 10 · Enterprise 20
Das Erstellen von Rechnungen und die Lese-/Verwaltungs-Endpunkte teilen sich dasselbe Limit. Erfolgreiche Antworten enthalten die Header X-RateLimit-Limit und X-RateLimit-Remaining. Workspace-API-Kontingente werden pro Mitgliedschaftsplan in Invosend konfiguriert. Benötigen Sie ein höheres Produktionsvolumen? Kontaktieren Sie uns über Ihr Workspace-Konto. Widerrufene Schlüssel zählen nicht zum Schlüssellimit.

7. Zusätzliche Endpunkte#

Derselbe API-Schlüssel kann auch Rechnungen lesen und verwalten, die über generate-external erstellt wurden:

MethodePfadBeschreibung
GET/api/invoices/externalListet Rechnungen für diesen Workspace auf. Unterstützt ?status= und ?page=/?pageSize= Query-Parameter.
GET/api/invoices/external/templatesListet die Rechnungsvorlagen auf, die du in template angeben kannst, ob dein Tarif sie erlaubt und welche die Standardvorlage ist.
GET/api/invoices/external/:idRuft eine Rechnung anhand ihrer id ab (der von generate-external zurückgegebene Wert).
PUT/api/invoices/external/:id/statusAktualisiert den Rechnungsstatus. Body: { "status": "paid" } (einer von unpaid, paid, overdue, cancelled).
PUT/api/invoices/external/:id/archiveArchiviert oder hebt die Archivierung einer Rechnung auf. Body: { "is_archived": true }.
POST/api/invoices/external/:id/pdfRuft die PDF-URL erneut ab und generiert sie bei Bedarf neu. Body: { "force": true }, um die Neugenerierung zu erzwingen.
GET/api/invoices/external/recurringListet wiederkehrende Serien auf. Unterstützt ?status= (active, paused, completed) und ?page=/?pageSize=.
GET/api/invoices/external/recurring/:idRuft eine Serie ab (die von generate-external zurückgegebene recurring.schedule_id) mit allen Terminen: Datum, Status und die id der jeweils erzeugten Rechnung.
PUT/api/invoices/external/recurring/:id/statusPausiert oder setzt eine Serie fort. Body: { "status": "paused" } oder { "status": "active" }. Das Fortsetzen erfordert einen Tarif mit wiederkehrenden Rechnungen.
PUT/api/invoices/external/recurring/:id/extendFügt Termine nach dem letzten hinzu. Body: { "count": 3 } oder { "end_date": "2027-12-31" }.
PUT/api/invoices/external/recurring/:id/frequencyÄndert die Wiederholungshäufigkeit der Serie; kommende, noch nicht erzeugte Termine werden ersetzt. Body: { "frequency": "monthly", "start_date": "2027-01-01", "count": 6 } (statt count ist auch end_date möglich; start_date muss in der Zukunft liegen).
POST/api/invoices/external/recurring/:id/skipEntfernt einen kommenden Termin. Body: { "date": "2027-01-01" }. Termine, die bereits eine Rechnung erzeugt haben, lassen sich nicht entfernen.
Um eine Online-Zahlung einzuziehen, setzen Sie payment_gateway (und optional payment_account) bei generate-external und senden Sie Ihrem Kunden dann die öffentliche Zahlungsseite der Rechnung: https://app.invosend.com/p/invoice/{id}, mit der von der API zurückgegebenen id. Dort bezahlt er über das verbundene Gateway, und die Rechnung wird automatisch als bezahlt markiert. Der Checkout wird von dieser Seite abgewickelt; es gibt keinen separaten öffentlichen Checkout-Endpunkt, den Sie aufrufen müssten.

8. Webhooks#

Statt ständig abzufragen, registrieren Sie eine HTTPS-URL: Invosend sendet dann bei jeder Änderung einer Rechnung eine POST-Anfrage mit JSON-Body dorthin. Endpunkte fügen Sie unter Einstellungen > Webhooks hinzu (Workspace-Inhaber, Tarif mit API-Zugriff, bis zu 5 Endpunkte). Jeder Endpunkt hat ein eigenes Signaturgeheimnis, das nur einmal angezeigt wird.

Ereignisse werden für Rechnungen aus dem Dashboard und über diese API gleichermaßen gesendet. Vorlagen für wiederkehrende Serien werden nie gesendet.

EreignisGesendet, wenn
invoice.createdEine Rechnung wird erstellt. Das PDF ist eventuell noch nicht fertig, daher kann pdf_url null sein.
invoice.paidDer Status wechselt zu paid (durch Sie, über die API oder durch eine Online-Zahlung).
invoice.overdueDer Status wechselt zu overdue (automatisch nach Fälligkeit oder manuell).
invoice.cancelledDer Status wechselt zu cancelled.

Jedes Ereignis hat denselben Aufbau. data.object ist die Rechnung in derselben Form wie bei GET /api/invoices/external/:id; Statusereignisse enthalten zusätzlich data.previous_status:

{
  "id": "evt_9f2c1b7a4e3d5c6b8a1f0e2d",
  "object": "event",
  "type": "invoice.paid",
  "created": "2026-10-01T09:30:12.000Z",
  "data": {
    "object": {
      "id": "cjld2cjxh0000qzrmn831i7rn",
      "invoice_number": "INV-1-202610-0007",
      "customer_name": "Acme Corp",
      "customer_email": "billing@acme.com",
      "currency": "USD",
      "subtotal": 500,
      "discount_total": 0,
      "tax_rate": 0,
      "tax_amount": 0,
      "amount": 500,
      "amount_paid": 500,
      "amount_credited": 0,
      "amount_received": 500,
      "invoice_status": "paid",
      "is_archived": false,
      "is_recurring": false,
      "recurring_interval": "none",
      "issue_date": "2026-10-01T02:15:40.000Z",
      "due_date": "2026-10-15",
      "paid_at": "2026-10-01T09:30:11.000Z",
      "pdf_url": "https://cdn.invosend.com/company/1/pdf/Invoice_INV_1_202610_0007_PAID.pdf",
      "pdf_status": "ready"
    },
    "previous_status": "unpaid"
  }
}

Jede Anfrage trägt diese Header. Zur Prüfung berechnen Sie mit dem Geheimnis des Endpunkts einen HMAC-SHA256 über {t}.{roher Body} und vergleichen ihn mit v1; lehnen Sie die Anfrage ab, wenn t älter als 5 Minuten ist:

POST /your/webhook/url
Content-Type: application/json
Invosend-Event: invoice.paid
Invosend-Delivery: evt_9f2c1b7a4e3d5c6b8a1f0e2d
Invosend-Signature: t=1790847012,v1=5b1d...e9a2

// Node.js
import crypto from "crypto";

function verify(rawBody, header, secret) {
  const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
  if (Math.abs(Date.now() / 1000 - Number(parts.t)) > 300) return false;
  const expected = crypto
    .createHmac("sha256", secret)
    .update(parts.t + "." + rawBody)
    .digest("hex");
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}
Antworten Sie innerhalb von 10 Sekunden mit einem beliebigen 2xx-Status. Andernfalls wird bis zu 7 weitere Male wiederholt (nach 1 Minute, 5 Minuten, 30 Minuten, 2 Stunden, 6 Stunden, 12 Stunden und 24 Stunden). Ein Endpunkt, der dauerhaft fehlschlägt, wird deaktiviert und Sie werden benachrichtigt. Ein Ereignis kann mehrfach oder in anderer Reihenfolge eintreffen: Ignorieren Sie Duplikate anhand der Ereignis-id und behandeln Sie invoice_status als maßgeblich. Zustellprotokolle werden 30 Tage aufbewahrt, und jedes Ereignis lässt sich unter Einstellungen > Webhooks erneut senden.

9. Einschränkungen#

Diese API ist bewusst auf die Rechnungserstellung und leichte Rechnungsverwaltung beschränkt. Folgendes ist noch nicht verfügbar:

  • Webhooks decken nur erstellte, bezahlte, überfällige und stornierte Rechnungen ab. Andere Änderungen, etwa Bearbeitungen oder Archivierung, werden nicht gesendet: Lesen Sie den aktuellen Stand mit GET /invoices/external/:id.
  • Die mit jeder Anfrage erstellte Rechnung wird nicht per E-Mail versendet: Diese API erstellt nur das PDF, die Zustellung an Ihren Kunden liegt bei Ihnen (oder nutzen Sie das Dashboard). Ausnahme sind wiederkehrende Serien: Jede vom Planer erzeugte Folgerechnung wird automatisch an customer_email gesendet.
  • Keine Bearbeitung einer Rechnung nach der Erstellung — nur ihr Status und Archivierungsstatus können über diese API geändert werden.
  • Die Unterstützung von Zahlungs-Gateways erfordert, dass das Gateway bereits im Dashboard verbunden ist; diese API ordnet es nur der Rechnung zu, sie verbindet kein Gateway von sich aus.
  • Eine wiederkehrende Serie lässt sich über die API pausieren, fortsetzen, verlängern, neu takten und einzelne kommende Termine überspringen, ihr Inhalt (Positionen, Kunde, Beträge) kann jedoch nicht bearbeitet und die Serie nicht über die API gelöscht werden; das geht im Dashboard.

Häufig gestellte Fragen#

Wie erhalte ich einen Invosend-API-Schlüssel?

Erstellen Sie ein Konto auf app.invosend.com, upgraden Sie den Workspace auf einen kostenpflichtigen Plan, öffnen Sie dann Settings > API Keys und klicken Sie auf Generate key. Der Rohschlüssel wird nur einmal bei der Erstellung angezeigt.

Wie viel kostet jeder Aufruf der Rechnungserstellungs-API?

Jede erfolgreiche Anfrage zieht 1 Rechnungsguthaben von Ihrem Workspace-Guthaben ab. Es verwendet denselben Rechnungsguthaben-Pool wie über das Dashboard erstellte Rechnungen.

Wie hoch ist das Ratenlimit für diese API?

Das Ratenlimit des Workspace richtet sich nach der Konfiguration Ihres kostenpflichtigen Plans. Der Abschnitt Ratenlimit oben nennt das aktuelle Limit jedes Plans.