Ledenbeheer Open API
Last updated About 1 hour ago
Ledenbeheer Open API
Access to the Ledenbeheer Open API is available with the Pro licence.
1. Introduction
The Ledenbeheer API lets you connect external applications to Ledenbeheer. Integration partners can, among other things:
retrieve clubs they can access;
retrieve user accounts;
create and edit user accounts;
retrieve active members;
retrieve courses and activities;
process registrations;
retrieve people responsible for courses;
read order and payment details linked to registrations.
The API is available to registered API partners and requires a partner token.
Request a partner token by emailing info@ledenbeheer.be.
The Open API is being expanded. Contact us if you need additional endpoints or data.
2. Base URL
All endpoints are under:
https://integrations.ledenbeheer.be/
For example:
https://integrations.ledenbeheer.be/test_connection
3. Authentication
Every API request requires a valid partner authentication token.
Depending on the endpoint, the token is currently sent in one of these ways.
3.1 Token as a parameter
Existing endpoints, including those for user accounts, use the parameter:
auth=PARTNER_AUTHENTICATION_TOKEN
Example:
https://integrations.ledenbeheer.be/test_connection?auth=PARTNER_AUTHENTICATION_TOKEN
3.2 Bearer token
The get_course_registrations endpoint supports authentication through this HTTP header:
Authorization: Bearer PARTNER_AUTHENTICATION_TOKEN
Always store the partner token in a secure server environment.
Never put it directly in publicly accessible browser JavaScript.
4. Check the connection and access rights
Before using other endpoints, we recommend calling test_connection.
Endpoint
GET /test_connection
Parameters
Example
https://integrations.ledenbeheer.be/test_connection?auth=PARTNER_AUTHENTICATION_TOKEN
Response
The endpoint returns, among other things:
which endpoints the token can access;
which clubs the token can access.
Example:
{ "availableEndpoints": [ "test_connection", "create_user_account", "edit_user_account", "get_user_accounts" ], "availableClubs": [ { "id": 102, "label": "Example club 1" }, { "id": 103, "label": "Example club 2" }, { "id": 104, "label": "Example club 3" } ], "result": true, "process_time": 0.26, "request_size": "373" }Use the id from availableClubs as the club parameter in other endpoints.
5. Retrieve valid field values
Ledenbeheer accepts only predefined values for certain fields.
Examples include:
address_countryaddress_postal_codeaddress_citynationality
Use this endpoint:
get_valid_field_options
Values for Belgian and Dutch addresses are validated when address_country is BE or NL.
For Dutch addresses, the response includes, among other things:
cities_nlpostals_nl
Always use the values returned by this endpoint.
6. General response
The Ledenbeheer API returns responses in JSON format.
On a successful request, result contains the result of the operation.
If an error occurs:
{ "result": false, "errors": [ "Error description" ] }Check for every request:
the HTTP status code;
the value of
result;the contents of
errors.
7. API limits
7.1 Rate limit
An integration partner can make at most 100 requests per minute.
When this limit is exceeded, the following response may be returned:
{ "errors": [ "You have exceeded your maximum amount of requests per minute" ] }7.2 High server load
Ledenbeheer may temporarily restrict API requests from integration partners when server load is too high.
Services for clubs using Ledenbeheer directly take priority.
Example:
{ "errors": [ "Server too busy, try again later" ] }For a temporary error, such as HTTP 503, the request may be retried later.
Prefer increasing delays, for example:
2 → 5 → 10 → 30 seconds
8. User accounts
8.1 Retrieve all users of a club
Use get_user_accounts to retrieve all user accounts for a club.
Endpoint
GET /get_user_accounts
Parameters
Example
https://integrations.ledenbeheer.be/get_user_accounts?auth=PARTNER_AUTHENTICATION_TOKEN&club=102
Response
{ "result": { "111855": { "uid": "111855", "fname": "John", "lname": "Smith", "email": "john.smith@gmail.com", "parent_uid": 0, "birthdate": "1997-08-21", "birthdate_unix": "557107200", "phone": "0123456789", "sex": "Man", "address": { "street": "Duet", "streetNumber": "33", "postal": "7430", "city": "Gent", "country": "BE" } }, "458436": { "uid": "458436", "fname": "Anna", "lname": "Woods", "email": "anna.woods@gmail.com", "parent_uid": 111855, "birthdate": "1960-12-11", "birthdate_unix": "-285728400", "phone": "0476337442", "sex": "Vrouw", "address": { "street": "Duet", "streetNumber": "33", "postal": "7430", "city": "Gent", "country": "BE" } } }, "process_time": 0.255, "request_size": "1526" }Error example
{ "result": false, "errors": [ "You don't have permission to access this club." ] }8.2 Retrieve one user
Use get_user_account when you need details of one particular user.
Endpoint
GET /get_user_account
Parameters
The uid can be obtained through, for example:
get_user_accountscreate_user_account
Example
https://integrations.ledenbeheer.be/get_user_account?auth=PARTNER_AUTHENTICATION_TOKEN&club=102&uid=111855
Response
{ "result": { "uid": "111855", "fname": "John", "lname": "Smith", "email": "john.smith@gmail.com", "parent_uid": 0, "birthdate": "1997-08-21", "birthdate_unix": "557107200", "phone": "0123456789", "sex": "Man", "address": { "street": "Duet", "streetNumber": "33", "postal": "7430", "city": "Gent", "country": "BE" } }, "process_time": 0.255, "request_size": "1526" }9. Create a user account
Use create_user_account to create a new user account for a club.
Endpoint
GET /create_user_account
The endpoint can create both:
main accounts;
child accounts
.
Ledenbeheer performs basic validation to avoid duplicate accounts where possible.
A user created through this API is automatically considered an active member, even if they do not yet have an order or registration.
Main and child accounts
For minors, a child account can be linked to a guardian's account, usually a parent.
Features such as session passes are managed per main account, so it is important to link parent and child accounts correctly.
Parameters
parent_uid
When parent_uid is sent, Ledenbeheer creates a child account under the specified main account.
The email addresses must match.
Response
On success, result contains the new user ID:
{ "result": 5468458 }If an error occurs:
{ "result": false, "errors": [ "Invalid email address." ] }Example
https://integrations.ledenbeheer.be/create_user_account ?auth=PARTNER_AUTHENTICATION_TOKEN &club=102 &fname=Jan &lname=Jansens &email=jan@gmail.com &parent_uid=123 &birthdate=1987-08-29 &sex=male &phone=0123456789 &nationality=Belg &address_street=Veldstraat &address_number=3 &address_unit=1b &address_postal_code=7550 &address_city=Brussel &address_country=BE10. Edit a user account
Use edit_user_account to edit an existing user account.
Endpoint
GET /edit_user_account
The same principles for main and child accounts apply as for create_user_account.
Parameters
Response
On success:
{ "result": 5468458 }If an error occurs:
{ "result": false, "errors": [ "Invalid phone number." ] }Example
https://integrations.ledenbeheer.be/edit_user_account ?auth=PARTNER_AUTHENTICATION_TOKEN &club=102 &uid=1351384132 &phone=0123456789 &nationality=Belg11. Retrieve active members
Use get_active_club_members to retrieve the active members of a club.
Endpoint
GET /get_active_club_members
Parameters
When IncludeDetails is omitted, the default response is only a list of active members and their user IDs.
12. Retrieve courses, activities and registrations
Use get_course_registrations to retrieve courses and activities with their registrations.
Along with course details, this endpoint includes information about:
sessions;
price categories;
additional services;
discounts;
registrations;
people responsible for courses;
linked orders and payments.
Endpoint
GET https://integrations.ledenbeheer.be/get_course_registrations
Authentication
Use:
Authorization: Bearer YOUR_TOKENParameters
The date filter selects courses and activities whose period overlaps with the specified period.
Important
If no dates are specified, the default period runs from:
1 January 1970 to today.
Future courses are therefore not returned.
Prefer to provide both startDate and endDate.
13. get_course_registrations examples
cURL
curl --get "https://integrations.ledenbeheer.be/get_course_registrations" \ -H "Authorization: Bearer YOUR_TOKEN" \ --data-urlencode "club=12345" \ --data-urlencode "startDate=2026-01-01" \ --data-urlencode "endDate=2026-12-31" \ --data-urlencode "includeCancelled=0"JavaScript / Node.js
Use this code only on a server, never directly in a browser.
const token = process.env.LEDENBEHEER_TOKEN; const clubId = 12345; const url = new URL( "https://integrations.ledenbeheer.be/get_course_registrations" ); url.searchParams.set("club", clubId); url.searchParams.set("startDate", "2026-01-01"); url.searchParams.set("endDate", "2026-12-31"); url.searchParams.set("includeCancelled", "0"); const response = await fetch(url, { headers: { Authorization: `Bearer ${token}`, Accept: "application/json" } }); const data = await response.json(); if (!response.ok || data.result === false || data.errors?.length) { throw new Error( data.errors?.join(", ") || `HTTP ${response.status}` ); } for (const course of Object.values(data.result)) { console.log( `${course.title}: ${course.registrations.length} registrations` ); }PHP
<?php $token = getenv('LEDENBEHEER_TOKEN'); $query = http_build_query([ 'club' => 12345, 'startDate' => '2026-01-01', 'endDate' => '2026-12-31', 'includeCancelled' => 0, ]); $curl = curl_init( 'https://integrations.ledenbeheer.be/get_course_registrations?' . $query ); curl_setopt_array($curl, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Authorization: Bearer ' . $token, 'Accept: application/json', ], CURLOPT_TIMEOUT => 30, ]); $body = curl_exec($curl); $status = curl_getinfo($curl, CURLINFO_HTTP_CODE); if ($body === false) { throw new RuntimeException(curl_error($curl)); } curl_close($curl); $data = json_decode( $body, true, 512, JSON_THROW_ON_ERROR ); if ( $status >= 400 || $data['result'] === false || !empty($data['errors']) ) { throw new RuntimeException( implode( ', ', $data['errors'] ?? ["HTTP error {$status}"] ) ); } foreach ($data['result'] as $course) { printf( "%s: %d registrations\n", $course['title'], count($course['registrations']) ); }14. Structure of get_course_registrations
An abbreviated response looks like this:
{ "result": { "70001": { "nid": 70001, "title": "Beginner swimming lessons", "type": "course", "status": 1, "startDate": "2026-09-01", "endDate": "2026-12-15", "location": "Sports centre", "tariffs": [ { "nid": 70002, "title": "Standard price", "registrationPeriod": [ "2026-06-01 09:00", "2026-08-31" ], "sessionPeriod": [ "2026-09-01", "2026-12-15" ] } ], "sessions": [ { "nid": 70003, "title": "Class 1", "date": "2026-09-01", "from": "18:00", "to": "19:00", "status": 1 } ], "registrations": [ { "uid": 456, "fname": "Jan", "lname": "Janssens", "tariff_label": "Standard price", "oid": 90001 } ] } }, "ordersPerUser": { "456": { "uid": 456, "firstName": "Jan", "lastName": "Janssens", "email": "jan@example.be", "orders": { "90001": { "oid": 90001, "orderID": "ORDER-001", "date": "2026-06-15", "status": 1, "amountPaid": 100, "amountOutstanding": 0, "amountTotal": 100 } } } } }Key fields
result
Contains all courses and activities in the requested period.
The object is indexed by course or activity ID.
nid
Unique ID of a:
course;
activity;
session;
price category.
Use nid as a stable key, not the title.
type
Gives the item type, for example:
courseactivity
registrations
Contains basic registration data for the course or activity.
uid
Unique user ID within Ledenbeheer.
Use uid as the stable key for people.
oid
Unique ID of the order linked to a registration.
The oid can be used to link a registration to the corresponding order in ordersPerUser.
ordersPerUser
Contains users with a registration for one of the selected courses or activities.
This can include:
contact details;
cost notes;
order details;
payment details;
discounts;
additional services.
status
Gives the status of, for example, a course, session or order.
When includeCancelled=0 is used, cancelled orders are excluded.
15. People responsible for courses
A course object from get_course_registrations may also contain the property:
responsibleUsers
.
This field contains Ledenbeheer users assigned as responsible for the course.
Example
{ "nid": "123", "title": "Beginner ballet", "responsibleUsers": { "555": "Kevin Teacher", "778": "Anne Instructor" }, "sessions": [ { "nid": "456", "date": "2026-09-07", "from": "18:00:00", "to": "19:00:00" } ] }The key of each item is the unique Ledenbeheer user ID, or uid.
The value is the visible name of the person responsible.
Always use the uid for linking.
Names:
can change;
are not necessarily unique.
Retrieve personal details of responsible users
To retrieve more details of a responsible user, such as:
first name;
last name;
email address;
phone number;
use get_user_accounts for the same club.
The uid from responsibleUsers matches the uid from get_user_accounts.
Example
Course:
{ "responsibleUsers": { "555": "Kevin Teacher" } }Users:
{ "result": { "555": { "uid": "555", "fname": "Kevin", "lname": "Teacher", "email": "kevin@example.be", "phone": "0470000000" } } }Notes on responsibleUsers
A course can have zero, one or several responsible users.
An empty or missing
responsibleUsersmeans that no responsible user was provided for that course.responsibleUsersis linked to the whole course and is not necessarily repeated for each session.An integration that schedules responsible users by class can link the course's responsible users to sessions within that course.
Use the
uid, not the name, as the linking key.Along with the
uid, store the course IDnidso the same person can be linked to multiple courses.Synchronisation should be idempotent. Do not create duplicates of the same course, user or session on subsequent runs.
Do not immediately delete a stored responsible user when responsibleUsers is temporarily missing. Check again whether the link was actually removed in Ledenbeheer.
16. Retrieve attendance through the API
The attendance API lets you retrieve participant lists and recorded attendance for courses and activities. You can use these data for reports, teacher dashboards or links to external software.
Three endpoints are available:
16.1 Authentication and access rights
All three endpoints use HTTPS GET requests. Send the partner token in this HTTP header:
Authorization: Bearer YOUR_TOKENYou receive data only for clubs that your integration partner can access. Each endpoint also requires a separate permission with the same name as that endpoint. A super administrator sets these permissions on the integrations administration page.
Access to get_attendance_bulk does not automatically grant access to the other two attendance endpoints. You do not need to send a separate club parameter for these endpoints.
Store the token on a secure server. Do not include it in a URL, public browser code or logs.
16.2 Attendance for one course or activity
Use get_attendance to retrieve all sessions, participants and attendance for one course or activity.
Endpoint
GET https://integrations.ledenbeheer.be/get_attendanceParameters
cURL example
curl --get 'https://integrations.ledenbeheer.be/get_attendance' --header 'Authorization: Bearer YOUR_TOKEN' --data-urlencode 'courseOrActivityId=842'Response
The result field contains sessions grouped by date. A list is returned for each date because several sessions can take place on the same day.
{ "result": { "2026-09-14": [ { "id": 5001, "startTime": "09:00", "endTime": "10:30", "attendance": { "123": { "id": 123, "name": "Jan Janssens", "registrationTariffIncludesSession": true, "attended": true, "type": "member" } } } ] }, "errors": [] }If the course or activity has no sessions, result is empty. It may be returned as an empty object or array. For an invalid or inaccessible ID, the result remains empty and errors contains an error message.
16.3 Attendance for several courses or activities
Use get_attendance_bulk to synchronise several courses or activities in one request.
Endpoint
GET https://integrations.ledenbeheer.be/get_attendance_bulkParameters
cURL example
curl --get 'https://integrations.ledenbeheer.be/get_attendance_bulk' --header 'Authorization: Bearer YOUR_TOKEN' --data-urlencode 'courseOrActivityIds=[842,913,999999]'Response
The result is indexed by course or activity ID. Each item contains id, title, type and sessions. The type is course or activity. Sessions have the same structure as in get_attendance.
A shortened example of a partially successful request:
{ "result": { "842": { "id": 842, "title": "Beginner ballet", "type": "course", "sessions": { "2026-09-14": [ { "id": 5001, "startTime": "09:00", "endTime": "10:30", "attendance": {} } ] } } }, "errors": [ { "message": "Course or activity does not exist.", "courseId": 999999 } ] }Accessible courses and activities without sessions are omitted. If an ID is invalid or inaccessible, other results may still be returned. Process result and errors separately.
16.4 Attendance by responsible user
Use get_attendance_for_responsible_users to retrieve attendance for courses and activities assigned to current or former responsible users. This is useful for a teacher dashboard or monthly report.
Endpoint
GET https://integrations.ledenbeheer.be/get_attendance_for_responsible_usersParameters
Both start and end dates are inclusive. Only sessions in this period are returned. Courses or activities without sessions in the period are omitted.
Important: userIds omitted is not the same as sending userIds=[]. An empty array means no users are selected and normally returns no courses.
cURL example
curl --get 'https://integrations.ledenbeheer.be/get_attendance_for_responsible_users' --header 'Authorization: Bearer YOUR_TOKEN' --data-urlencode 'userIds=[77,88]' --data-urlencode 'periodStart=2026-09-01' --data-urlencode 'periodEnd=2026-09-30'Response
The response has the same structure as get_attendance_bulk: for each course or activity, you receive basic details and sessions with participants and attendance. Filtering by responsible user limits the returned courses and activities; each attendance list also includes other participants in those sessions.
16.5 Sessions and attendance data
A date is shown as YYYY-MM-DD and is the scheduled local session date. Each session contains:
For each user, attendance contains these fields:
Note: attended=false means the user is not recorded as present. The field does not distinguish between other stored statuses. Whether a session is included in a price category is independent of recorded attendance.
Participant types
If a user qualifies for several types, this order applies: responsibleUser → member → trial → pass → other. A responsible user who is also registered as a member is therefore returned as responsibleUser.
Regularly registered members appear in every returned session of their course or activity, even if their price category does not include that session. Always check registrationTariffIncludesSession.
Expired registrations and registrations awaiting approval are included only if the user has an attendance record somewhere within that course or activity. Cancelled and temporary orders are excluded. Trial classes are handled through trial registrations, not regular member registrations.
History of responsible users
Where the history includes assignment start and end times, a responsible user appears only in sessions that start within that assignment period. A current assignment has no end time.
For older courses with only the current responsible user known, the API uses that person as a fallback for all returned course sessions.
16.6 Error handling and synchronisation
Check the HTTP status and read result and errors separately. A non-empty error list does not mean all results from bulk or responsible-user requests are unusable.
Errors involving courses or users contain a message and, depending on the error, a courseId or userId:
{ "message": "Responsible user is not visible to this integration partner.", "userId": 999999 }General errors, such as an invalid or disabled token or missing endpoint permissions, may appear as text in errors:
{ "result": false, "errors": ["You don't have permission to access this endpoint."] }Support both text messages and error objects. Resolve token and permission problems first; do not retry these requests indefinitely. For temporary connection or server problems, retry a limited number of times with increasing delays.
When synchronising, we recommend:
processing every session for each date, including multiple sessions on the same day;
linking attendance by course ID, session ID and user ID;
updating existing records so repeated imports do not create duplicates;
processing successful results while tracking errors separately;
storing the request periods or synchronisation progress;
safely ignoring additional fields, such as processing time, if your application does not use them.
17. Recommended synchronisation strategy
get_course_registrations currently supports:
no
updatedSinceparameter;no pagination.
The date filter uses the course or activity period, rather than when the course or registration was last modified.
We therefore recommend regularly synchronising the entire relevant season again.
Recommended approach
Retrieve the entire current season periodically.
Store courses by
nid.Store users by
uid.Store orders by
oid.For example, store registrations using this combination:
niduidoidtariff_label
Update existing records rather than creating them again.
Make synchronisation idempotent.
Do not immediately delete records when they are absent from a later synchronisation.
Check missing registrations again with
includeCancelled=1.
Example
startDate=2026-01-01 endDate=2026-12-31 includeCancelled=1For a production integration, it is usually better to synchronise a sufficiently broad period than only the current day or week.
18. Error handling
Always check both the HTTP status and the API response.
Example:
{ "result": false, "errors": [ "Invalid token" ] }Possible errors include:
invalid token;
disabled token;
token without access to the requested club;
missing club ID;
invalid club ID;
invalid field values;
exceeding the limit of 100 requests per minute;
temporary server overload.
Temporary errors
For temporary server problems, such as HTTP 503, the request may be retried.
Prefer exponential backoff or a similar strategy.
For example:
First retry: 2 seconds; second: 5 seconds; third: 10 seconds; fourth: 30 seconds.Avoid unlimited automatic retries.
19. Recommended integration flow
For a new integration, we recommend this order.
Step 1 — Check the connection
Call test_connection and check:
whether the token is valid;
which endpoints are available;
which clubs the token can access.
Step 2 — Retrieve valid values
Use get_valid_field_options before creating or editing user data.
Step 3 — Synchronise users
Use:
get_user_accountsget_user_accountcreate_user_accountedit_user_account
according to the functionality you need.
Step 4 — Synchronise active members
If needed, use:
get_active_club_members
Step 5 — Retrieve courses and registrations
Use:
get_course_registrations
with explicit startDate and endDate.
Step 6 — Link responsible users
Read responsibleUsers from the course and use uid to link them to users from get_user_accounts.
Step 7 — Link orders
Use the registration's oid to find the corresponding order in ordersPerUser to find it.
Step 8 — Synchronise periodically
Synchronise the relevant season again and update existing records by stable ID.
Where possible, use:
nidfor courses, activities, sessions and price categories;uidfor users;oidfor orders.
Do not use names or titles as a unique key.