Invoices
Business+Create, issue, send, download and cancel invoices. Every rule of the admin applies (GoBD): drafts get their number only when they are issued, issued invoices are locked and are corrected only by cancelling them with a credit note.
Endpoints
/api/v1/invoices
List all invoices (open_amount already subtracts payments, credit notes and write-offs)
/api/v1/invoices/{id}
Retrieve a single invoice with its lines (include=payments,credit_notes,contact for more)
/api/v1/invoices
Create a draft for a participation (event_participant_id) or a contact (contact_id). Lines come from "items" (description, quantity, unit_price net, tax_rate from your invoice settings) and/or the participation's open billable items (booth, service orders, documents; default when no items are given; "billable_item_ids" picks single ones). The due date defaults to the payment terms. "issue": true issues it right away (optional "invoice_date"), "send": true also e-mails it. Returns 201 with the invoice; problems with issuing or sending are listed in "warnings". Fires invoice.created
/api/v1/invoices/{id}
Update an invoice: notes and due_date (also on issued invoices); status "sent" on a draft issues it (like POST /issue), status "cancelled" cancels it (like POST /cancel, with "cancellation_reason"). paid, partially_paid, overdue and refunded follow from payments, credit notes and the dunning run and are rejected with 422
/api/v1/invoices/{id}/issue
Issue a draft: assigns the next invoice number and the invoice date (today or "invoice_date", at most back to the start of the previous month and never before the last issued invoice) and locks it. 422 for an invoice without lines or one that is already issued
/api/v1/invoices/{id}/send
E-mail the invoice PDF (plus the XRechnung XML) to the customer's billing address or to "to" (cc, bcc, subject and a personal "message" are optional). A draft is issued first, so the attachment always carries the final number. The text uses the customer's language. Fires invoice.sent
/api/v1/invoices/{id}/pdf
Download the invoice PDF (application/pdf). Issued e-invoices are served from the archive; drafts carry a draft watermark
/api/v1/invoices/{id}/e-invoice
Download the e-invoice: format=xrechnung (default output: XML) or zugferd (default output: hybrid PDF); output=xml|pdf overrides it. Only the format set on the invoice is available; issued invoices come from the archive. 422 when e-invoicing is not enabled or master data is missing
/api/v1/invoices/{id}/cancel
Cancel an invoice (Storno). An issued invoice is never edited: the open remainder is reversed by a credit note (one line per tax rate); "reason" is required and documented. A draft is simply discarded. Optional "send_credit_note": true e-mails the credit note. Returns invoice and credit_note. Fires invoice.cancelled and credit_note.created. 409 if already cancelled, 422 for credit notes and refunded invoices
Query Parameters
| Parameter | Description |
|---|---|
status
|
Filter by invoice status |
customer_number
|
Filter by customer number |
event_key
|
Filter by event key |
type
|
Filter by invoice type (invoice, credit_note) |
sort
|
Sort field (invoice_number, invoice_date = issue date, empty for drafts and sorted last, total, status, due_date, created_at) |
order
|
Sort direction (ASC or DESC, default: DESC) |
include
|
Include related data (items, payments, contact, credit_notes) |
format
|
e-invoice only: xrechnung or zugferd (default: the format set on the invoice) |
output
|
e-invoice only: xml or pdf (default: xml for XRechnung, pdf for ZUGFeRD) |
Request Schema
| Parameter | Type | Required | Description |
|---|---|---|---|
event_participant_id
|
integer | No | Create: participation to invoice (one of event_participant_id or contact_id) |
contact_id
|
integer | No | Create: contact to invoice without an event |
items
|
array | No | Create: lines [{"description", "quantity" (default 1), "unit_price" (net), "tax_rate" (one of your invoice tax rates, default the highest)}] |
include_billable_items
|
boolean | No | Create: add the participation's open billable items (booth, service orders, documents). Default: true when no items are given |
billable_item_ids
|
array | No | Create: only these open billable items |
due_date
|
string | No | Due date (YYYY-MM-DD or ISO 8601). Default on create: invoice date + payment terms |
service_date
|
string | No | Create: service date (YYYY-MM-DD; default the event start) |
is_reverse_charge
|
boolean | No | Create: reverse charge (0 % VAT; only for EU customers with a VAT ID abroad) |
e_invoice_format
|
string | No | Create: none, xrechnung or zugferd |
leitweg_id
|
string | No | Create: Leitweg-ID for public-sector XRechnung recipients |
buyer_reference
|
string | No | Create: buyer reference (BT-10) when there is no Leitweg-ID |
issue
|
boolean | No | Create: issue the invoice right away (number + invoice date) |
invoice_date
|
string | No | Create with issue / POST issue: invoice date (YYYY-MM-DD, default today) |
send
|
boolean | No | Create: issue and e-mail the invoice right away (to = billing e-mail or "send_to") |
status
|
string | No | PATCH only: "sent" issues a draft, "cancelled" cancels the invoice. Payment states (paid, partially_paid, overdue, refunded) cannot be set (422) |
notes
|
string | No | Internal notes for the invoice |
reason
|
string | No | POST cancel: cancellation reason (required for issued invoices) |
to
|
string|array | No | POST send: recipient address(es); default the billing e-mail of the customer. Also cc, bcc, subject, attach_xml |
message
|
string | No | POST send: personal text inserted after the greeting |
Response Schema
| Field | Type |
|---|---|
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 |
Code Examples
curl -X POST "https://your-tenant.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://your-tenant.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://your-tenant.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://your-tenant.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)
Sample Response
{
"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"
}
}