Démarrage rapide
En quatre étapes, de la clé à une intégration qui fonctionne. Comptez dix minutes.
1. Créer une clé
Un administrateur de l'association crée les clés dans Ledenboek sous Paramètres → Clés API → Nouvelle clé. Donnez à la clé un nom qui vous dira plus tard à quoi elle sert et choisissez ses droits. Par défaut tout est en lecture seule ; pour l'étape 4, il vous faut en plus leden:schrijven.
La clé n'est affichée qu'une fois. Placez-la dans une variable d'environnement, pas dans votre code :
export LEDENBOEK_API_KEY="lb_test_..."Dans une association d'exemple, la clé commence par lb_test_. Aucun e-mail ni aucune demande de paiement n'y est envoyé : vous pouvez tout essayer sans toucher à de vrais membres.
2. Votre premier appel
GET /v2/organization fonctionne avec n'importe quelle clé et renvoie l'association, les modules activés et les droits de votre clé. Une bonne première vérification que tout est en ordre.
curl https://api.ledenboek.nl/v2/organization \
-H "Authorization: Bearer $LEDENBOEK_API_KEY"const response = await fetch("https://api.ledenboek.nl/v2/organization", {
headers: { Authorization: `Bearer ${process.env.LEDENBOEK_API_KEY}` },
});
const organization = await response.json();
console.log(organization.name, organization.api_key.scopes);<?php
$ch = curl_init("https://api.ledenboek.nl/v2/organization");
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ["Authorization: Bearer " . getenv("LEDENBOEK_API_KEY")],
CURLOPT_RETURNTRANSFER => true,
]);
$organization = json_decode(curl_exec($ch), true);
echo $organization["name"];import os
import requests
response = requests.get(
"https://api.ledenboek.nl/v2/organization",
headers={"Authorization": f"Bearer {os.environ['LEDENBOEK_API_KEY']}"},
)
organization = response.json()
print(organization["name"], organization["api_key"]["scopes"])La réponse :
{
"object": "organization",
"id": 42,
"name": "Club de tennis Les Lilas",
"slug": "tc-les-lilas",
"country": "Belgique",
"language": "fr",
"website_url": "https://www.tc-les-lilas.be",
"modules": {
"groups": true,
"committees": true,
"participants": false,
"relationships": false,
"events": true,
"invoicing": true
},
"api_key": {
"name": "Intégration du site",
"prefix": "lb_test_8kQz",
"environment": "test",
"scopes": [
"leden:lezen",
"leden:schrijven"
]
}
}Un 401 signifie le plus souvent que l'en-tête n'est pas exactement Authorization: Bearer lb_.... Avec 402, l'association n'a pas d'abonnement valide.
3. Parcourir les membres
Avec le droit leden:lezen, vous consultez les membres avec GET /v2/members. Les listes arrivent par pages de 100 enregistrements au plus (25 par défaut). Tant que has_more est vrai, demandez la page suivante en passant next_cursor comme starting_after.
curl "https://api.ledenboek.nl/v2/members?limit=100" \
-H "Authorization: Bearer $LEDENBOEK_API_KEY"
# Next page: pass next_cursor from the previous response
curl "https://api.ledenboek.nl/v2/members?limit=100&starting_after=1234" \
-H "Authorization: Bearer $LEDENBOEK_API_KEY"const headers = { Authorization: `Bearer ${process.env.LEDENBOEK_API_KEY}` };
const members = [];
let cursor = null;
do {
const url = new URL("https://api.ledenboek.nl/v2/members");
url.searchParams.set("limit", "100");
if (cursor) url.searchParams.set("starting_after", cursor);
const page = await (await fetch(url, { headers })).json();
members.push(...page.data);
cursor = page.has_more ? page.next_cursor : null;
} while (cursor);<?php
$members = [];
$cursor = null;
do {
$query = http_build_query(array_filter(["limit" => 100, "starting_after" => $cursor]));
$ch = curl_init("https://api.ledenboek.nl/v2/members?" . $query);
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ["Authorization: Bearer " . getenv("LEDENBOEK_API_KEY")],
CURLOPT_RETURNTRANSFER => true,
]);
$page = json_decode(curl_exec($ch), true);
$members = array_merge($members, $page["data"]);
$cursor = $page["has_more"] ? $page["next_cursor"] : null;
} while ($cursor !== null);import os
import requests
session = requests.Session()
session.headers["Authorization"] = f"Bearer {os.environ['LEDENBOEK_API_KEY']}"
members, cursor = [], None
while True:
params = {"limit": 100}
if cursor:
params["starting_after"] = cursor
page = session.get("https://api.ledenboek.nl/v2/members", params=params).json()
members.extend(page["data"])
if not page["has_more"]:
break
cursor = page["next_cursor"]Une page ressemble à ceci (abrégée ; tous les champs sont dans la référence) :
{
"object": "list",
"data": [
{
"object": "member",
"id": 1234,
"membership_number": "L042",
"first_name": "Anne",
"last_name": "Dubois",
"email": "anne@example.com",
"status": "active",
"member_since": "2024-03-01",
"created_at": "2024-03-01T10:12:00+01:00",
"updated_at": "2026-10-02T08:30:00+02:00"
}
],
"has_more": true,
"next_cursor": "1234"
}4. Créer un membre
Avec leden:schrijven, vous créez un membre avec POST /v2/members. Envoyez un Idempotency-Key : une valeur unique par nouveau membre, par exemple un UUID. Si la connexion est coupée et que vous renvoyez la même requête avec la même clé, vous recevez la première réponse et le membre n'est pas créé deux fois.
curl https://api.ledenboek.nl/v2/members \
-X POST \
-H "Authorization: Bearer $LEDENBOEK_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 6f1c2a3e-8d4b-4c1e-9a7f-2b5d0e9c4a11" \
-d '{"first_name": "Anna", "last_name": "de Vries", "email": "anna@example.com"}'// Store this key with your own record, so a retry sends the same one.
const idempotencyKey = crypto.randomUUID();
const response = await fetch("https://api.ledenboek.nl/v2/members", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.LEDENBOEK_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": idempotencyKey,
},
body: JSON.stringify({ first_name: "Anna", last_name: "de Vries", email: "anna@example.com" }),
});
const member = await response.json();<?php
// Store this key with your own record, so a retry sends the same one.
$idempotencyKey = bin2hex(random_bytes(16));
$ch = curl_init("https://api.ledenboek.nl/v2/members");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("LEDENBOEK_API_KEY"),
"Content-Type: application/json",
"Idempotency-Key: " . $idempotencyKey,
],
CURLOPT_POSTFIELDS => json_encode([
"first_name" => "Anna",
"last_name" => "de Vries",
"email" => "anna@example.com",
]),
CURLOPT_RETURNTRANSFER => true,
]);
$member = json_decode(curl_exec($ch), true);import os
import uuid
import requests
# Store this key with your own record, so a retry sends the same one.
idempotency_key = str(uuid.uuid4())
response = requests.post(
"https://api.ledenboek.nl/v2/members",
headers={
"Authorization": f"Bearer {os.environ['LEDENBOEK_API_KEY']}",
"Idempotency-Key": idempotency_key,
},
json={"first_name": "Anna", "last_name": "de Vries", "email": "anna@example.com"},
)
member = response.json()Si un champ n'est pas valide, vous recevez 422 avec un détail par champ :
{
"type": "https://developers.ledenboek.nl/errors/validation_failed",
"title": "Données invalides",
"status": 422,
"detail": "Un ou plusieurs champs ne sont pas correctement remplis ; voir errors.",
"instance": "/v2/members",
"errors": [
{
"field": "email",
"code": "invalid",
"message": "L'e-mail n'est pas valide"
}
]
}Pour aller plus loin
- Authentification : les droits disponibles et ce qu'une clé de test change.
- Concepts : avec
updated_since, ne récupérer que ce qui a changé. - Référence de l'API : tous les endpoints. Avec la spécification à /openapi.json, vous générez vous-même un client dans votre langage, par exemple avec OpenAPI Generator.