Clubtool.developers
Start

Getting started

The Club-tool public API is a JSON REST API over HTTPS at https://app.club-tool.nl/api/v1. It gives your integration access to the data of your own club — nothing else.

1. Check your plan

The public API is part of the Pro plan. On other plans the API responds with 403 upgrade_required; existing keys are kept and start working again after an upgrade.

2. Try it first? Grab a sandbox key

No club or Pro plan yet? Mint a free read-only sandbox key against the public demo club (fictional data, expires after 7 days, max 5 per day per IP):

curl -X POST https://app.club-tool.nl/api/v1/sandbox-keys

The response contains a ct_test_… key with every read scope. Writes on the demo club answer 403.

3. Create an API key

  1. Sign in to app.club-tool.nl as a club administrator.
  2. Go to System → API and click New API key.
  3. Give the key a label (e.g. membership sync) and tick the scopes it needs.
  4. Copy the full key immediately — it is shown only once.

Treat the key like a password: store it in a secret manager, never commit it to a repository, and never ship it in client-side code. Keys start with ct_live_ so secret scanners can recognise them.

4. Make your first call

curl https://app.club-tool.nl/api/v1/club \
  -H "Authorization: Bearer ct_live_..."

The response tells you which club the key belongs to and which scopes it carries:

{
  "id": 12,
  "name": "BC Amersfoort",
  "slug": "bca",
  "key": { "label": "membership sync", "prefix": "ct_live_3f9K",
           "scopes": ["members:read", "members:write"] }
}

5. Explore the resources

ResourceReadWriteBulk
/api/v1/members✓create · update · delete✓ (mixed, max 100)
/api/v1/groups✓— (memberships via members)—
/api/v1/events✓create · update · delete—
/api/v1/seasons✓——
/api/v1/competition-teams✓create · update · delete—
/api/v1/attendance✓ (filtered)upsert✓ (max 100)
/api/v1/kennismakers✓create · update · status—
/api/v1/charges✓ (read-only)——
/api/v1/tournaments✓ (read-only)——
/api/v1/news✓ (read-only)——

Every request/response shape is documented in the API reference, generated from the OpenAPI 3.1 spec — point your favourite client generator at that URL.

6. Incremental sync

Every resource carries an updated_at timestamp (UTC). Pass ?updated_since= on list endpoints to fetch only what changed since your last run — store the start time of each sync and use it as the next cursor:

curl "https://app.club-tool.nl/api/v1/members?updated_since=2026-07-01T22:00:00Z" \
  -H "Authorization: Bearer ct_live_..."

Deletions are not reflected in updated_since results — schedule a periodic full sync to reconcile removed records.

7. Example: create a member

curl -X POST https://app.club-tool.nl/api/v1/members \
  -H "Authorization: Bearer ct_live_..." \
  -H "Content-Type: application/json" \
  -d '{"name": "Sam de Vries", "birth_date": "2012-03-14",
       "gender": "female", "group_ids": [3]}'

8. Tooling

npx @openapitools/openapi-generator-cli generate \
  -i https://developers.club-tool.nl/openapi/openapi.yaml \
  -g typescript-fetch -o ./clubtool-client

Next: learn how scopes work, make your writes retry-safe with idempotency keys, and get push updates via webhooks.