AlphaCount Developers
Guides

Bill your customers from your product

Mirror customers, issue and send invoices, keep in sync, cancel — while AlphaCount books, sends and dunns.

Your product knows who bought what for which period. AlphaCount knows how a correct German invoice looks, books it, sends it, sees the payment arrive and dunns when it does not. This guide connects the two.

1. Mirror the customer

PUT /customers/by-ref/{source}/{external_ref} creates the customer or updates it to what you send — call it whenever the customer changes in your product, or before every invoice.

What a valid invoice needs: name, e-mail (where the invoice goes), street, zip, city, country. For a business customer in another EU country, add the vat_id — without it, AlphaCount cannot issue a reverse-charge invoice. For public sector customers, leitweg_id goes into the XRechnung. contact_name appears as "attn." under the name.

2. Create the invoice

POST /invoices with an Idempotency-Key:

{
  "customer": { "source": "myapp", "external_ref": "cust-42" },
  "external_ref": "order-1001",
  "lines": [
    { "description": "Licence, October 2026", "quantity": 1, "unit": "Monat", "unit_price_net": "1000.00", "vat_rate": 19 },
    { "description": "Textbook", "quantity": "3", "unit_price_net": "19.90", "vat_rate": 7 }
  ],
  "service_period": { "start": "2026-10-01", "end": "2026-10-31" },
  "payment_terms_days": 14,
  "issue": true,
  "send": true
}
  • external_ref is your id for the invoice. AlphaCount keeps one invoice per reference; a second request for the same reference with another key is 409 invoice_external_ref_exists and names the invoice.
  • service_period is required: a German invoice states when the service was provided.
  • A line may name a product you keep in AlphaCount (product_ref, or its product_number) so that revenue lands on the product's account and revenue shares can depend on it.

What happens:

issuesendResult
false—a draft; a person reviews and issues it in the app
truefalseissued: number, VAT verdict, booking, PDF — and e-invoice for business customers
truetrueissued, then mailed from the company's mailbox

Issuing runs all the checks the app runs. If one fails — the company has no tax number yet, the address is incomplete, the VAT verdict needs a person — the answer is 422 invoice_not_issuable with the reasons, and nothing was created: no draft, no number, no used-up idempotency key.

If the invoice was issued but the mail failed, the answer is still 201, with send_error saying why. Send it later with POST /invoices/{id}/send.

3. Learn what happens next

Subscribe a webhook to the invoice events. Each comes once per invoice:

EventWhen
invoice.issuedit got its number
invoice.sentit was mailed for the first time
invoice.paidit is paid in full — a partial payment is no event
invoice.overdueit is past due and unpaid
invoice.dunning_senta reminder or dunning notice went out
invoice.cancelledit was cancelled

Match an event to your record by data.external_ref. Events can arrive twice or out of order — use the envelope's id to process each once.

To keep a copy in sync without webhooks, ask GET /invoices?changed_since=… on a schedule.

4. Cancel

An issued invoice cannot be changed or deleted. POST /invoices/{id}/cancel issues a cancellation invoice — the negative mirror with its own number and a reference to the original — and books the reversal. To correct an invoice, cancel it and create a new one with a new external_ref.

An invoice that is paid, even partly, is not cancelled through the API (422 invoice_not_cancellable): the payment needs a person's decision first.

What the API does not do

  • issue a draft — that is done in the app;
  • change an issued invoice;
  • override a tax warning that a person would confirm in the app;
  • record payments or start dunning — AlphaCount does that from the bank statement;
  • bill in another currency than EUR, or at another VAT rate than 0, 7 or 19 %.

On this page