BillKit/DocsConsole
Documentation

BillKit for developers

BillKit is a subscription billing API for European businesses. It runs plans, checkout, invoices, VAT, dunning and the customer portal on top of your own Mollie account.

Updated Sep 26, 2026·OpenAPI v1.1.0

What BillKit is, and what it sits on

BillKit does not process payments. Your tenant account connects a Mollie account, and BillKit drives it: it creates the payments, stores the resulting mandates, schedules and charges renewals, closes periods, computes VAT, produces invoices and PDFs, retries failures and emits webhooks. Money moves through Mollie and settles into your Mollie balance.

That split explains most of the design. Card and SEPA details never reach BillKit. Anything Mollie decides (whether a charge needs Strong Customer Authentication, whether a SEPA debit eventually bounces) is reported to BillKit asynchronously, which is why almost every outcome you care about arrives as a webhook rather than in a response body.

How the API is shaped

REST over HTTPS, JSON in and JSON out, including errors. Amounts are integers in the smallest unit of the currency (amount_cents). Timestamps are Unix seconds. Object ids carry a type prefix, so sub_... is always a subscription.

Base URLhttps://api.billkit.eu
AuthBearer secret key: bk_live_… or bk_test_…
Request bodyapplication/json. Unknown fields, and unknown query parameters, are rejected with 400 parameter_unknown.
UpdatesOmitted fields are left alone. null clears a field that can be empty; on a field that cannot, it is refused with 400 naming the field.
Success status200 on every route, including creates
ListsCursor paginated: limit (default 10, max 100) and starting_after
IdempotencyIdempotency-Key header on any write

There is no API version header. Live and test mode are selected by which key you send, not by a parameter.

shell
curl https://api.billkit.eu/v1/ping \
-H "Authorization: Bearer $BILLKIT_API_KEY"
Response · 200 OK
{
"tenant_id": "7b0f1e2c-9a41-4d6e-8f30-1c5a2b7d4e88",
"mode": "test",
"object": "ping"
}

Id prefixes

PrefixObject
cus_Customer
prod_Product
price_Price
cs_Checkout session
sub_Subscription
pay_Payment
inv_Invoice
re_Refund
cn_Credit note
coup_Coupon
tr_Tax rate
ur_Usage record
evt_Event
we_Webhook endpoint
dp_Dispute
tc_Test clock
osp_One-off payment
bps_Billing portal session
ili_Invoice line item
ak_API key
al_Audit log entry
whd_Webhook delivery

Treat every id as an opaque string. Most are short and mixed-case; API keys, audit log entries and webhook deliveries end in 32 hex digits instead. Both forms keep their prefix.

The one thing that surprises people

You cannot POST /v1/subscriptions. A subscription is a side effect of a paid checkout: you create a checkout session, the customer pays, Mollie tells BillKit the payment settled, and BillKit creates the subscription and emits subscription.created. The reason is the mandate. A recurring charge needs an authorised mandate, and only a real first payment through Mollie produces one, so a subscription cannot exist before that payment lands.

Everything starts in test mode. Test-mode objects are stored separately, carry livemode: false, and are invisible to a live key. See Test mode.

Core concepts

Pick a path