Statistics (Statistieken)¶
Current version: 1.0.0
The statistics endpoints return aggregated figures over a period of time: totals per time bucket and, optionally, per grouping dimension (per product, per payment method, per company, and so on). They are the data source behind the statistics screens in Recras and are well suited to reporting, dashboards and periodic revenue or payment summaries.
They are not a per-transaction feed. There is no grouping by an individual booking or invoice; every value in a response is a sum over the matching rows. If you need per-sale detail – which products were sold, at which price, and how each sale was paid – use the transactional endpoints instead (see Choosing the right endpoint).
Warning
Recras is an administration system, not a tax or accounting authority. These
endpoints report how much money moved through Recras and for which
bookings; they do not make fiscal determinations. Recras does not decide
what counts as revenue for your business, whether you fall under a
small-business scheme (in the Netherlands, the KOR), whether an
organisation is a charity (ANBI), or how amounts should be recognised for
tax. Those settings are the customer’s responsibility: Recras assumes they are
configured correctly and reports accordingly. Always reconcile exported
figures against your own accounting rules.
Choosing the right endpoint¶
For aggregated totals – revenue, payments or quantities summed per period – use the statistics endpoints on this page.
Note
Exporting individual sales to a POS or accounting system? The statistics endpoints cannot produce a per-sale dataset. Combine the transactional endpoints instead:
Bookings (Boekingen) – the bookings themselves.
Invoice lines (Factuurregels) – the invoiced lines: which products were sold and at which price.
Invoices – the invoices the lines belong to.
Invoice payments – the payments: the amount (
bedrag) and the payment method (betaalmethode_id) of each individual payment.
The aggregated counterparts, when you only need totals, are
GET /api2/statistieken/verkoop and GET /api2/omzet for
invoiced revenue, and GET /api2/statistieken/betalingen for payments
received.
Note the difference between invoiced and paid amounts:
GET /api2/statistieken/verkoop and GET /api2/omzet report amounts
that have been invoiced (from sent, partially paid and paid invoices), which
is not necessarily what has been received.
GET /api2/statistieken/betalingen reports the amounts that were actually
paid. For cash-flow reconciliation, use the payment figures.
Mapping to a general ledger¶
To map money flows onto the accounts in your bookkeeping, Recras can store a ledger number (grootboeknummer) and, for product groups, a cost center (kostenplaats). These are read from the regular resource endpoints, not from the statistics endpoints:
Payment Methods (Betaalmethoden) –
ledger_numberper payment method (the payment side).Product Groups (Productgroepen) –
ledger_numberandcost_centerper product group (the revenue side).
Recras only stores and returns these values as configured by the customer; it does not validate them against any chart of accounts.
Common request format¶
The conventions in this section apply to the /api2/statistieken/* endpoints.
GET /api2/omzet and GET /api2/vouchers/overview use their own
parameters and response shape and are documented with each.
Response format¶
Each /api2/statistieken/* endpoint returns a JSON array of objects with two
members:
key– the dimensions the row is grouped by: the time bucket (period) and any values fromgroepeer_gegevens.data– the aggregated metric(s) for that combination of dimensions.
HTTP/1.1 200 OK
Content-Type: application/json
[
{
"key": { "period": "2026-01", "product_id": 42 },
"data": { "gefactureerd_bedrag_inclusief_btw": 1210.00, "gefactureerd_bedrag_exclusief_btw": 1000.00 }
}
]
Grouping¶
groepeer_tijd selects the length of the time bucket and determines the format
of period in each key:
jaar– calendar year, e.g."2026".maand– month number 1-12, e.g."6".week– ISO week number, e.g."22".jaar-maand– year and month, e.g."2026-06".jaar-week– ISO year and week, e.g."2026-W09".datum– a single date, e.g."2026-06-01".
groepeer_gegevens adds one or more extra dimensions to the key (for
example product_id or betaalmethode_id). It is a comma-separated list;
the accepted values differ per endpoint.
Date range¶
The period is bounded by two parameters whose names literally contain a > and
a < character:
datum>– start of the period (inclusive), an ISO8601 date.datum<– end of the period (inclusive), an ISO8601 date.
For example ?datum>=2026-01-01&datum<=2026-12-31. datum< must not be
earlier than datum>. Remember to URL-encode the parameter names where your
HTTP client requires it (datum%3E and datum%3C).
Default period and redirects¶
If required parameters are omitted, the endpoint responds with a 302 redirect
to the same URL with sensible defaults filled in (the date range defaults to the
current calendar year, plus per-endpoint defaults noted below). Standard HTTP
clients follow this redirect automatically. Supply all parameters yourself to
avoid the extra round trip.
Errors¶
On a validation error the endpoint responds with 406 Not Acceptable and a
body listing the problems. Each entry has a message and, for a field-specific
error, the field it applies to:
HTTP/1.1 406 Not Acceptable
Content-Type: application/json
[
{ "field": "datum<", "message": "\"datum<\" must be after \"datum>\"" }
]
There is no pagination; every request returns the full result set.
Sales – invoiced revenue (verkoop)¶
- GET /api2/statistieken/verkoop¶
Invoiced revenue and booking figures, aggregated per period and optionally per dimension. Amounts are taken from sent, partially paid and paid invoices.
Example request:
GET /api2/statistieken/verkoop?referentiedatum=boeking&datum>=2026-01-01&datum<=2026-12-31&gegevens=gefactureerd_bedrag&groepeer_tijd=jaar-maand&groepeer_gegevens=product_id HTTP/1.1 Host: demo.recras.nl Authorization: Bearer <your-api-key> Accept: application/json
Example response:
HTTP/1.1 200 OK Content-Type: application/json [ { "key": { "period": "2026-01", "product_id": 42 }, "data": { "gefactureerd_bedrag_inclusief_btw": 1210.00, // (invoiced_amount_including_vat) "gefactureerd_bedrag_exclusief_btw": 1000.00 // (invoiced_amount_excluding_vat) } } ]
- Query Parameters:
referentiedatum – Required. Which date the rows are attributed to:
boeking(booking date),factuur(invoice date),boeking_gemaakt(date the booking was created) orboekingsregel(per booking-line date).datum> (date) – Required. Start of the period (inclusive). The
>is part of the name.datum< (date) – Required. End of the period (inclusive). The
<is part of the name.gegevens – Required. The metric to return:
gefactureerd_bedrag(invoiced amount),gefactureerd_bedrag_per_persoon(invoiced amount per person),nog_te_factureren(still to be invoiced),boekingswaarde(booking value),personen(number of people) orboekingen(number of bookings).groepeer_tijd – Time bucket for
period(see Grouping). At least one ofgroepeer_tijdorgroepeer_gegevensis required.groepeer_gegevens – Comma-separated extra dimensions:
arrangement_id,bedrijf_id(company),soort_klant(customer type),product_id,productgroep_id,created_by,ISO3166-1(country),ISO3166-2(region) orbtw_percentage(VAT rate).bedrijf_id – Optional filter. Comma-separated company IDs.
soort_klant – Optional filter. Comma-separated customer types.
arrangement_id – Optional filter. Comma-separated package (arrangement) IDs.
book_process_id – Optional filter. Comma-separated book-process IDs.
boeking_status – Optional filter. Comma-separated booking statuses:
informatie,interesse,optie,reservering,definitief,gaande,voltooid,geannuleerd.landcode – Optional filter. An ISO3166-1 country code.
invoice_contexts – Optional filter. Comma-separated invoice contexts:
invoice,pos,online_booking. Requiresgegevens=gefactureerd_bedrag.product_id – Optional filter. Comma-separated product IDs (only combinable with
groepeer_gegevens=product_id).contains_product_id – Optional filter. Only bookings containing one of these product IDs.
contains_productgroup_id – Optional filter. Only bookings containing a product from one of these product groups.
contains_productlabel_id – Optional filter. Only bookings containing a product with one of these labels.
boeking_created_by – Optional filter. Contact ID of the booking’s creator.
boeking_los_op_planning – Optional filter. Boolean; filters on whether products are planned loosely.
include_voucher_sales – Optional filter. Boolean; whether to include voucher sales.
locatie – Optional filter. Location filter.
invoicing_setting – Optional filter. Boolean; the booking’s “should be invoiced” setting.
- JSON Parameters:
gefactureerd_bedrag_inclusief_btw (number) – For
gegevens=gefactureerd_bedrag: invoiced amount including VAT.gefactureerd_bedrag_exclusief_btwgives the amount excluding VAT.gefactureerd_bedrag_per_persoon_inclusief_btw (number) – For
gegevens=gefactureerd_bedrag_per_persoon: invoiced amount per person including VAT (plus..._exclusief_btw).nog_te_factureren_inclusief_btw (number) – For
gegevens=nog_te_factureren: amount still to be invoiced including VAT (plus..._exclusief_btw).boekingswaarde_inclusief_btw (number) – For
gegevens=boekingswaarde: booking value including VAT (plus..._exclusief_btw).personen (number) – For
gegevens=personen: number of people.boekingen (number) – For
gegevens=boekingen: number of bookings.
- Request Headers:
Authorization – Required. Bearer token with your API key, see Authenticating to the Recras API.
- Status Codes:
200 OK – no error
302 Found – required parameters were missing; follow the redirect (defaults
gegevens=gefactureerd_bedragandreferentiedatum=boeking).401 Unauthorized – not authenticated.
403 Forbidden – user does not have both the
viewStatistiekandviewFinancieleOverzichtenpermissions.406 Not Acceptable – error in the input. Some combinations are rejected, for example
referentiedatum=factuurrequiresgegevens=gefactureerd_bedrag; grouping byproduct_id,productgroep_idorbtw_percentagerequiresgegevens=gefactureerd_bedragorboekingswaarde.
Revenue per product (omzet)¶
- GET /api2/omzet¶
Invoiced revenue for a date range, broken down per product and VAT rate. Unlike the
/api2/statistieken/*endpoints, this returns a flat list (nokey/dataenvelope) and usesbegin/eindfor the date range.Example request:
GET /api2/omzet?begin=2026-01-01&eind=2026-12-31 HTTP/1.1 Host: demo.recras.nl Authorization: Bearer <your-api-key> Accept: application/json
Example response:
HTTP/1.1 200 OK Content-Type: application/json [ { "product_id": 42, "btw_percentage": 21, // (vat_percentage) "product_naam": "Kanovaren", // (product_name: "Canoeing") "productgroep_id": 3, // (product_group_id) "productgroep_naam": "Buitensport", // (product_group_name: "Outdoor sports") "bedrag_exc_btw": 1000.00, // (amount_excluding_vat) "bedrag_inc_btw": 1210.00 // (amount_including_vat) } ]
- Query Parameters:
begin (date) – Required. Start of the date range, an ISO8601 date.
eind (date) – Required. End of the date range, an ISO8601 date. Must not be earlier than
begin.
- JSON Parameters:
product_id (int) – The product, or
nullfor revenue not tied to a product.btw_percentage (number) – The VAT percentage of this row.
product_naam (string) – The product name, or
null.productgroep_id (int) – The product group, or
null.productgroep_naam (string) – The product group name, or
null.bedrag_exc_btw (number) – Invoiced amount excluding VAT.
bedrag_inc_btw (number) – Invoiced amount including VAT.
- Request Headers:
Authorization – Required. Bearer token with your API key, see Authenticating to the Recras API.
- Status Codes:
200 OK – no error
403 Forbidden – user has neither the
viewFinancieleOverzichtennor theviewStatistiekpermission.406 Not Acceptable – error in the input (for example
eindbeforebegin).
Payments received (betalingen)¶
- GET /api2/statistieken/betalingen¶
The amounts actually paid, aggregated per period and optionally per payment method. This is the aggregated counterpart of Invoice payments.
Example request:
GET /api2/statistieken/betalingen?datum>=2026-01-01&datum<=2026-12-31&referentiedatum=betaling&gegevens=betaald_bedrag&groepeer_tijd=jaar-maand&groepeer_gegevens=betaalmethode_id HTTP/1.1 Host: demo.recras.nl Authorization: Bearer <your-api-key> Accept: application/json
Example response:
HTTP/1.1 200 OK Content-Type: application/json [ { "key": { "period": "2026-01", "betaalmethode_id": 1 }, "data": { "bedrag": 1210.00 } // (amount) } ]
- Query Parameters:
referentiedatum – Required. Only
betaling(the payment date) is accepted.datum> (date) – Required. Start of the period (inclusive).
datum< (date) – Required. End of the period (inclusive).
gegevens – Required. Only
betaald_bedrag(paid amount) is accepted.groepeer_tijd – Required. Time bucket for
period(see Grouping).groepeer_gegevens – Optional. Only
betaalmethode_id(payment method) is accepted.
- JSON Parameters:
bedrag (number) – The total amount paid in this period (and, if grouped, with this payment method).
- Request Headers:
Authorization – Required. Bearer token with your API key, see Authenticating to the Recras API.
- Status Codes:
200 OK – no error
302 Found – required parameters were missing; follow the redirect (defaults
gegevens=betaald_bedrag,referentiedatum=betalingandgroepeer_tijd=jaar-maand).403 Forbidden – user does not have the
viewStatistiekpermission.406 Not Acceptable – error in the input.
Booked product quantities (geboekteproducten)¶
- GET /api2/statistieken/geboekteproducten¶
How many of each product were booked, aggregated per period and per product or product group.
Example request:
GET /api2/statistieken/geboekteproducten?datum>=2026-01-01&datum<=2026-12-31&groepeer_tijd=jaar-maand&groepeer_gegevens=product_id HTTP/1.1 Host: demo.recras.nl Authorization: Bearer <your-api-key> Accept: application/json
Example response:
HTTP/1.1 200 OK Content-Type: application/json [ { "key": { "period": "2026-01", "product_id": 42 }, "data": { "aantal": 87 } // (quantity) } ]
- Query Parameters:
datum> (date) – Required. Start of the period (inclusive).
datum< (date) – Required. End of the period (inclusive).
groepeer_tijd – Required. Time bucket for
period(see Grouping).groepeer_gegevens – Required.
product_idorproductgroep_id.bedrijf_id – Optional filter. Comma-separated company IDs.
soort_klant – Optional filter. Customer type.
boeking_status – Optional filter. Comma-separated booking statuses.
product_id – Optional filter. Comma-separated product IDs.
productgroep_id – Optional filter. Comma-separated product-group IDs.
invoicing_setting – Optional filter. Boolean; the booking’s “should be invoiced” setting.
- JSON Parameters:
aantal (number) – The total quantity booked.
- Request Headers:
Authorization – Required. Bearer token with your API key, see Authenticating to the Recras API.
- Status Codes:
200 OK – no error
302 Found – required parameters were missing; follow the redirect (defaults
groepeer_gegevens=product_idandgroepeer_tijd=jaar-maand).403 Forbidden – user does not have the
viewStatistiekpermission.406 Not Acceptable – error in the input.
Purchasing costs (inkoop)¶
- GET /api2/statistieken/inkoop¶
The purchasing cost (cost of goods) of booked products, aggregated per period and optionally per dimension.
Example request:
GET /api2/statistieken/inkoop?datum>=2026-01-01&datum<=2026-12-31&groepeer_tijd=jaar-maand&groepeer_gegevens=productgroep_id HTTP/1.1 Host: demo.recras.nl Authorization: Bearer <your-api-key> Accept: application/json
Example response:
HTTP/1.1 200 OK Content-Type: application/json [ { "key": { "period": "2026-01", "productgroep_id": 3 }, "data": { "inkoop": 320.50 } // (purchasing_cost) } ]
- Query Parameters:
datum> (date) – Required. Start of the period (inclusive).
datum< (date) – Required. End of the period (inclusive).
groepeer_tijd – Required. Time bucket for
period(see Grouping).groepeer_gegevens – Optional.
product_id,productgroep_id,arrangement_id,bedrijf_idorsoort_klant.soort_klant – Optional filter. Customer type.
boeking_status – Optional filter. Comma-separated booking statuses.
bedrijf_id – Optional filter. Comma-separated company IDs.
invoicing_setting – Optional filter. Boolean; the booking’s “should be invoiced” setting.
- JSON Parameters:
inkoop (number) – The total purchasing cost.
- Request Headers:
Authorization – Required. Bearer token with your API key, see Authenticating to the Recras API.
- Status Codes:
200 OK – no error
302 Found – required parameters were missing; follow the redirect (default
groepeer_tijd=jaar-maand).403 Forbidden – user does not have the
viewStatistiekpermission.406 Not Acceptable – error in the input.
Bookings overview (bookingsoverview)¶
- GET /api2/statistieken/bookingsoverview¶
The number of bookings or people, aggregated per period and optionally per dimension. This is the
bookingen/personensubset ofGET /api2/statistieken/verkoop, available with a lighter permission.Example request:
GET /api2/statistieken/bookingsoverview?datum>=2026-01-01&datum<=2026-12-31&referentiedatum=boeking&gegevens=boekingen&groepeer_tijd=datum HTTP/1.1 Host: demo.recras.nl Authorization: Bearer <your-api-key> Accept: application/json
Example response:
HTTP/1.1 200 OK Content-Type: application/json [ { "key": { "period": "2026-01-15" }, "data": { "boekingen": 4 } // (bookings) } ]
- Query Parameters:
referentiedatum – Required.
boeking,boeking_gemaaktorboekingsregel.datum> (date) – Required. Start of the period (inclusive).
datum< (date) – Required. End of the period (inclusive).
gegevens – Required.
boekingen(number of bookings) orpersonen(number of people).groepeer_tijd – Time bucket for
period(see Grouping). At least one ofgroepeer_tijdorgroepeer_gegevensis required.groepeer_gegevens – Optional. Same dimensions as
GET /api2/statistieken/verkoop.
- JSON Parameters:
boekingen (number) – For
gegevens=boekingen: number of bookings.personen (number) – For
gegevens=personen: number of people.
- Request Headers:
Authorization – Required. Bearer token with your API key, see Authenticating to the Recras API.
- Status Codes:
200 OK – no error
302 Found – required parameters were missing; follow the redirect (defaults
gegevens=boekingen,groepeer_tijd=datumandreferentiedatum=boeking).403 Forbidden – user does not have the
zoekBoekingenOpDatumpermission.406 Not Acceptable – error in the input.
Staff costs (personeelskosten)¶
- GET /api2/statistieken/personeelskosten¶
Planned and recorded staff hours and their cost, aggregated per period. Only confirmed shifts (bevestigd) are counted.
Example request:
GET /api2/statistieken/personeelskosten?datum>=2026-01-01&datum<=2026-12-31&groepeer_tijd=jaar-maand HTTP/1.1 Host: demo.recras.nl Authorization: Bearer <your-api-key> Accept: application/json
Example response:
HTTP/1.1 200 OK Content-Type: application/json [ { "key": { "period": "2026-01" }, "data": { "personeelskosten": 4200.00, // (staff_costs, from planned hours) "personeelskosten_geregistreerde_uren": 4050.00, // (staff_costs, from recorded hours) "geplande_uren": 240, // (planned_hours) "geregistreerde_uren": 231.5, // (recorded_hours) "geregistreerde_pauze": 12 // (recorded_break, hours) } } ]
- Query Parameters:
datum> (date) – Required. Start of the period (inclusive).
datum< (date) – Required. End of the period (inclusive).
groepeer_tijd – Required. Time bucket for
period(see Grouping).groepeer_gegevens – Optional.
soort_dienst(shift type:boeking,drukte,locatieorlos) orlocatie_id(location).
- JSON Parameters:
personeelskosten (number) – Staff cost based on the planned hours.
personeelskosten_geregistreerde_uren (number) – Staff cost based on the recorded hours (minus recorded breaks).
geplande_uren (number) – Planned hours.
geregistreerde_uren (number) – Recorded hours.
geregistreerde_pauze (number) – Recorded break time, in hours.
- Request Headers:
Authorization – Required. Bearer token with your API key, see Authenticating to the Recras API.
- Status Codes:
200 OK – no error
302 Found – required parameters were missing; follow the redirect (default
groepeer_tijd=jaar-maand).403 Forbidden – user does not have the
viewStatistiekpermission.406 Not Acceptable – error in the input.
Voucher overview (vouchers/overview)¶
- GET /api2/vouchers/overview¶
Vouchers created, redeemed and expired in a date range. Unlike the
/api2/statistieken/*endpoints this returns a single object with three lists and usesdate>/date<for the date range. Amounts are in the instance’s currency;typeisPRODUCTorCREDIT.Example request:
GET /api2/vouchers/overview?date>=2026-01-01&date<=2026-12-31 HTTP/1.1 Host: demo.recras.nl Authorization: Bearer <your-api-key> Accept: application/json
Example response:
HTTP/1.1 200 OK Content-Type: application/json { "created": [ { "internal_reference": "KO-2026-0001", "number_of_vouchers": 5, "product_amount": 5, "credit": 0, "type": "PRODUCT", "sale_price": 250.00, "sale_tax_percentage": 21, "company_id": 1 } ], "redeemed": [ { "internal_reference": "KO-2026-0001", "product_id": 42, "product_name": "Kanovaren", "type": "PRODUCT", "number_of_vouchers": 2, "redeemed_product_amount": 2, "redeemed_credit": 0, "product_value": 100.00, "product_tax_percentage": 21, "sale_price_credit": 0, "sale_price": 100.00, "sale_tax_percentage": 21, "company_id": 1 } ], "expired": [ { "internal_reference": "KO-2025-0009", "number_of_vouchers": 1, "expired_credit": 25.00, "expired_product_amount": 0, "type": "CREDIT", "sale_price_credit": 25.00, "sale_price": 25.00, "sale_tax_percentage": 21, "company_id": 1 } ] }
- Query Parameters:
date> (date) – Required. Start of the date range (inclusive). The
>is part of the name.date< (date) – Required. End of the date range (inclusive). The
<is part of the name. Must not be earlier thandate>.company_id (int) – Optional filter. Restrict to a single company.
- JSON Parameters:
created (array) – Vouchers created in the range, grouped by reference, VAT rate and company. Fields:
internal_reference,number_of_vouchers,product_amount,credit,type,sale_price,sale_tax_percentage,company_id.redeemed (array) – Vouchers redeemed in the range. Fields include
internal_reference,product_id,product_name,type,number_of_vouchers,redeemed_product_amount,redeemed_credit,product_value,product_tax_percentage,sale_price_credit,sale_price,sale_tax_percentage,company_id.expired (array) – Vouchers that expired in the range. Fields:
internal_reference,number_of_vouchers,expired_credit,expired_product_amount,type,sale_price_credit,sale_price,sale_tax_percentage,company_id.
- Request Headers:
Authorization – Required. Bearer token with your API key, see Authenticating to the Recras API.
- Status Codes:
200 OK – no error
403 Forbidden – user does not have the
viewStatistiekpermission.405 Method Not Allowed – method not allowed (only
GETis supported).406 Not Acceptable – error in the input.