PlanDocket

Rechnungen

Business+

Rechnungen anlegen, stellen, versenden, herunterladen und stornieren. Es gelten alle Regeln des Admin-Bereichs (GoBD): Entwürfe erhalten ihre Nummer erst beim Stellen, gestellte Rechnungen sind gesperrt und werden nur durch Stornierung mit Gutschrift korrigiert.

Erforderliche Bereiche: invoices
Zugriffsstufe: GET invoices:read POST / PUT / PATCH / DELETE invoices:write Mehr zu Zugriffsstufen
Feature-Flag: invoices

Endpunkte

GET /api/v1/invoices

Alle Rechnungen auflisten (open_amount berücksichtigt Zahlungen, Gutschriften und Abschreibungen)

GET /api/v1/invoices/{id}

Einzelne Rechnung mit Positionen abrufen (include=payments,credit_notes,contact für mehr)

POST /api/v1/invoices

Entwurf für eine Teilnahme (event_participant_id) oder einen Kontakt (contact_id) anlegen. Positionen kommen aus "items" (description, quantity, unit_price netto, tax_rate aus Ihren Rechnungseinstellungen) und/oder den offenen abrechenbaren Leistungen der Teilnahme (Stand, Bestellungen, Dokumente; Standard, wenn keine items angegeben sind; "billable_item_ids" wählt einzelne aus). Das Fälligkeitsdatum ergibt sich aus dem Zahlungsziel. "issue": true stellt die Rechnung sofort (optional "invoice_date"), "send": true versendet sie zusätzlich. Antwort 201 mit der Rechnung; Probleme beim Stellen oder Versenden stehen in "warnings". Löst invoice.created aus

PUT/PATCH /api/v1/invoices/{id}

Rechnung aktualisieren: notes und due_date (auch bei gestellten Rechnungen); status "sent" stellt einen Entwurf (wie POST /issue), status "cancelled" storniert (wie POST /cancel, mit "cancellation_reason"). paid, partially_paid, overdue und refunded ergeben sich aus Zahlungen, Gutschriften und dem Mahnlauf und werden mit 422 abgelehnt

POST /api/v1/invoices/{id}/issue

Entwurf stellen: vergibt die nächste Rechnungsnummer und das Rechnungsdatum (heute oder "invoice_date", höchstens bis zum Anfang des Vormonats zurück und nie vor der zuletzt gestellten Rechnung) und sperrt die Rechnung. 422 bei einer Rechnung ohne Positionen oder einer bereits gestellten Rechnung

POST /api/v1/invoices/{id}/send

Rechnungs-PDF (plus XRechnung-XML) per E-Mail an die Rechnungsadresse des Kunden oder an "to" senden (cc, bcc, subject und eine persönliche "message" sind optional). Ein Entwurf wird vorher gestellt, damit der Anhang immer die endgültige Nummer trägt. Der Text erscheint in der Sprache des Kunden. Löst invoice.sent aus

GET /api/v1/invoices/{id}/pdf

Rechnungs-PDF herunterladen (application/pdf). Gestellte E-Rechnungen kommen aus dem Archiv; Entwürfe tragen ein Entwurfs-Wasserzeichen

GET /api/v1/invoices/{id}/e-invoice

E-Rechnung herunterladen: format=xrechnung (Standardausgabe XML) oder zugferd (Standardausgabe Hybrid-PDF); output=xml|pdf überschreibt das. Verfügbar ist nur das an der Rechnung hinterlegte Format; gestellte Rechnungen kommen aus dem Archiv. 422, wenn E-Rechnungen nicht aktiviert sind oder Stammdaten fehlen

POST /api/v1/invoices/{id}/cancel

Rechnung stornieren. Eine gestellte Rechnung wird nie geändert: Der offene Rest wird durch eine Gutschrift ausgeglichen (eine Zeile je Steuersatz); "reason" ist Pflicht und wird dokumentiert. Ein Entwurf wird einfach verworfen. Optional versendet "send_credit_note": true die Gutschrift. Liefert invoice und credit_note. Löst invoice.cancelled und credit_note.created aus. 409, wenn bereits storniert, 422 für Gutschriften und erstattete Rechnungen

Abfrageparameter

Parameter Beschreibung
status Nach Rechnungsstatus filtern
customer_number Nach Kundennummer filtern
event_key Nach Event-Schlüssel filtern
type Nach Rechnungstyp filtern (invoice, credit_note)
sort Sortierfeld (invoice_number, invoice_date = Rechnungsdatum, bei Entwürfen leer und zuletzt, total, status, due_date, created_at)
order Sortierrichtung (ASC oder DESC, Standard: DESC)
include Verknüpfte Daten einschließen (items, payments, contact, credit_notes)
format Nur E-Rechnung: xrechnung oder zugferd (Standard: das an der Rechnung hinterlegte Format)
output Nur E-Rechnung: xml oder pdf (Standard: xml bei XRechnung, pdf bei ZUGFeRD)

Request-Schema

Parameter Typ Erforderlich Beschreibung
event_participant_id integer Nein Anlegen: abzurechnende Teilnahme (event_participant_id oder contact_id)
contact_id integer Nein Anlegen: Kontakt, der ohne Event abgerechnet wird
items array Nein Anlegen: Positionen [{"description", "quantity" (Standard 1), "unit_price" (netto), "tax_rate" (einer Ihrer Rechnungs-Steuersätze, Standard der höchste)}]
include_billable_items boolean Nein Anlegen: offene abrechenbare Leistungen der Teilnahme übernehmen (Stand, Bestellungen, Dokumente). Standard: true, wenn keine items angegeben sind
billable_item_ids array Nein Anlegen: nur diese offenen abrechenbaren Leistungen
due_date string Nein Fälligkeitsdatum (JJJJ-MM-TT oder ISO 8601). Standard beim Anlegen: Rechnungsdatum + Zahlungsziel
service_date string Nein Anlegen: Leistungsdatum (JJJJ-MM-TT; Standard: Eventbeginn)
is_reverse_charge boolean Nein Anlegen: Reverse Charge (0 % USt; nur für EU-Kunden mit ausländischer USt-IdNr.)
e_invoice_format string Nein Anlegen: none, xrechnung oder zugferd
leitweg_id string Nein Anlegen: Leitweg-ID für öffentliche Auftraggeber (XRechnung)
buyer_reference string Nein Anlegen: Käuferreferenz (BT-10), wenn keine Leitweg-ID vorliegt
issue boolean Nein Anlegen: Rechnung sofort stellen (Nummer + Rechnungsdatum)
invoice_date string Nein Anlegen mit issue / POST issue: Rechnungsdatum (JJJJ-MM-TT, Standard heute)
send boolean Nein Anlegen: Rechnung sofort stellen und per E-Mail senden (an die Rechnungs-E-Mail oder "send_to")
status string Nein Nur PATCH: "sent" stellt einen Entwurf, "cancelled" storniert die Rechnung. Zahlungsstatus (paid, partially_paid, overdue, refunded) können nicht gesetzt werden (422)
notes string Nein Interne Notizen zur Rechnung
reason string Nein POST cancel: Stornogrund (Pflicht bei gestellten Rechnungen)
to string|array Nein POST send: Empfängeradresse(n); Standard die Rechnungs-E-Mail des Kunden. Außerdem cc, bcc, subject, attach_xml
message string Nein POST send: persönlicher Text, der nach der Anrede eingefügt wird

Response-Schema

Feld Typ
id integer
invoice_number string|null
display_number string
invoice_type string
related_invoice_id integer|null
status string
event_participant_id integer|null
contact_id integer|null
invoice_date string|null
issued_at string|null
total float
currency string
credited_amount float
paid_amount float
written_off_amount float
open_amount float
service_date string|null
due_date string|null
is_reverse_charge boolean
is_locked boolean
locked_at string|null
sent_at string|null
reminder_sent_at string|null
reminder_count integer
cancellation_reason string|null
e_invoice_format string
e_invoice_status string|null
leitweg_id string|null
buyer_reference string|null
po_number string|null
notes string|null
links object
created_at string
updated_at string

Codebeispiele

curl -X POST "https://ihr-mandant.plandocket.com/api/v1/invoices" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "event_participant_id": 7,
    "items": [
        {
            "description": "Standfläche Halle A, 12 m²",
            "quantity": 12,
            "unit_price": 75,
            "tax_rate": 19
        }
    ],
    "include_billable_items": false,
    "issue": true
}'
<?php
$apiKey = 'YOUR_API_KEY';
$baseUrl = 'https://ihr-mandant.plandocket.com';

$payload = [
    'event_participant_id' => 7,
    'items' => [
        [
            'description' => 'Standfläche Halle A, 12 m²',
            'quantity' => 12,
            'unit_price' => 75,
            'tax_rate' => 19,
        ],
    ],
    'include_billable_items' => false,
    'issue' => true,
];

$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL => $baseUrl . '/api/v1/invoices',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode($payload),
]);

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

$data = json_decode($response, true);
print_r($data);
const apiKey = 'YOUR_API_KEY';
const baseUrl = 'https://ihr-mandant.plandocket.com';

const payload = {
    "event_participant_id": 7,
    "items": [
        {
            "description": "Standfläche Halle A, 12 m²",
            "quantity": 12,
            "unit_price": 75,
            "tax_rate": 19
        }
    ],
    "include_billable_items": false,
    "issue": true
};

const response = await fetch(`${baseUrl}/api/v1/invoices`, {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(payload),
});

const data = await response.json();
console.log(data);
import requests

api_key = 'YOUR_API_KEY'
base_url = 'https://ihr-mandant.plandocket.com'

headers = {
    'Authorization': f'Bearer {api_key}',
}

payload = {
    'event_participant_id': 7,
    'items': [
        {
            'description': 'Standfläche Halle A, 12 m²',
            'quantity': 12,
            'unit_price': 75,
            'tax_rate': 19,
        },
    ],
    'include_billable_items': False,
    'issue': True,
}

response = requests.request('POST', f'{base_url}/api/v1/invoices', headers=headers, json=payload)
data = response.json()
print(data)

Beispiel-Antwort

200 OK
{
    "data": {
        "id": 1,
        "invoice_number": "string",
        "display_number": "string",
        "invoice_type": "string",
        "related_invoice_id": 1,
        "status": "string",
        "event_participant_id": 1,
        "contact_id": 1,
        "invoice_date": "2026-01-15T10:00:00+01:00",
        "issued_at": "2026-01-15T10:00:00+01:00",
        "total": 100,
        "currency": "string",
        "credited_amount": 100,
        "paid_amount": 100,
        "written_off_amount": 100,
        "open_amount": 100,
        "service_date": "2026-01-15T10:00:00+01:00",
        "due_date": "2026-01-15T10:00:00+01:00",
        "is_reverse_charge": true,
        "is_locked": true,
        "locked_at": "2026-01-15T10:00:00+01:00",
        "sent_at": "2026-01-15T10:00:00+01:00",
        "reminder_sent_at": "2026-01-15T10:00:00+01:00",
        "reminder_count": 1,
        "cancellation_reason": "string",
        "e_invoice_format": "string",
        "e_invoice_status": "string",
        "leitweg_id": "string",
        "buyer_reference": "string",
        "po_number": "string",
        "notes": "string",
        "links": {},
        "created_at": "2026-01-15T10:00:00+01:00",
        "updated_at": "2026-01-15T10:00:00+01:00"
    }
}
API Version v1.0