Clubin API v2
Manage club members and their memberships programmatically — create users, look them up, update details, renew or cancel a membership, and list a club's members. This API powers the official Clubin app for Make.com and any server-to-server integration.
Authentication
Every request must carry your club's API key in the Authorization header. Find your key in Club settings → Automations → API v2. It identifies your club, and every request is automatically scoped to it — you can only read or change your own club's members.
Authorization: Bearer clb_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxConventions
Requests. GET endpoints read parameters from the query string; POST endpoints read a JSON body and require Content-Type: application/json.
Success responses always include "status": "success" alongside the endpoint's data. Dates are YYYY-MM-DD strings, or null when unset — a permanent membership has no expiry date. Membership state uses the underlying 'y'/'n' and 0/1 values, documented per endpoint.
Errors
Errors return the matching status code and a body of the form { "status": "error", "message": "…" }. The message names the specific problem.
| Status | Meaning |
|---|---|
| 400 | Missing or invalid input — the message says which field. |
| 401 | Missing or invalid API key. |
| 404 | The user does not exist, or is not a member of your club. |
| 405 | Wrong HTTP method for this endpoint. |
| 409 | The change collides with existing data (e.g. an email already in use). |
| 500 | Unexpected server error. |
Return basic information about the authenticated club. Handy for validating a key when an integration is first set up.
{
"status": "success",
"club": { "id": 999, "name": "Clubin", "subdomain": "clubin999" }
}Create a new user and assign them to your club. If a user with that email already exists, they're assigned to your club instead of being recreated — so the call is safe to repeat.
| Field | Type | Required | Description |
|---|---|---|---|
| string | required | The user's email — the unique identifier. | |
| name | string | new users | Required when creating a new user; ignored for existing ones. |
| phone | string | optional | Phone number. |
| address | string | optional | Street address. |
| city | string | optional | City. |
| send_signup_mail | boolean | default true | Email the auto-generated password to the user. |
curl -X POST https://api.clubin.co.il/webapi/v2/users/ \
-H "Authorization: Bearer clb_your_key" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"name": "Dana Levi",
"phone": "0500000000"
}'{
"status": "success",
"user": {
"id": 35057,
"email": "[email protected]",
"name": "Dana Levi",
"phone": "0500000000"
},
"already_existed": false,
"club_id": 999
}201 for a newly created user, 200 when the user already existed and was assigned to your club.
Look up one member of your club by email or ID, including their membership status. Returns 404 if the user isn't a member of your club.
| Parameter | Type | Required | Description |
|---|---|---|---|
| string | one of | Look up by email. | |
| id | integer | one of | Look up by user ID. |
curl "https://api.clubin.co.il/webapi/v2/users/\
[email protected]" \
-H "Authorization: Bearer clb_your_key"{
"status": "success",
"user": {
"id": 35057, "email": "[email protected]",
"name": "Dana Levi", "phone": "0500000000",
"city": "Tel Aviv", "address": "Herzl 1"
},
"membership": {
"active": "y",
"is_expire": 0,
"membership_start": "2026-09-01",
"expire_date": null
}
}active: 'y' active, 'n' cancelled. is_expire: 0 permanent, 1 temporary. expire_date is null for a permanent membership.
Update an existing member's details. Only the fields you send are changed; omitted or empty fields are left untouched.
| Field | Type | Required | Description |
|---|---|---|---|
| id / email | int / string | one of | Identifies the user. |
| name | string | optional | New name. |
| phone | string | optional | New phone. |
| city | string | optional | New city. |
| address | string | optional | New address. |
| new_email | string | optional | Change the user's email (must not already be in use). |
curl -X POST \
https://api.clubin.co.il/webapi/v2/users/update/ \
-H "Authorization: Bearer clb_your_key" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"phone": "0521111111",
"city": "Tel Aviv"
}'{
"status": "success",
"user": {
"id": 35057, "email": "[email protected]",
"name": "Dana Levi", "phone": "0521111111",
"city": "Tel Aviv", "address": "Herzl 1"
},
"updated_fields": ["phone", "city"]
}Returns 409 if new_email already belongs to another user.
Cancel a user's membership in your club (sets it inactive). The user record itself is not deleted, and memberships in other clubs are unaffected. Safe to repeat.
| Field | Type | Required | Description |
|---|---|---|---|
| id / email | int / string | one of | Identifies the user. |
curl -X POST \
https://api.clubin.co.il/webapi/v2/users/cancel/ \
-H "Authorization: Bearer clb_your_key" \
-H "Content-Type: application/json" \
-d '{ "email": "[email protected]" }'{
"status": "success",
"user": {
"id": 35057, "email": "[email protected]",
"name": "Dana Levi"
},
"club_id": 999,
"was_active": true,
"active": "n"
}was_active is false if the membership was already inactive before this call.
List your club's members, paginated. Request pages in sequence until page reaches total_pages. In Make this maps to a Search module, which iterates the pages for you.
| Parameter | Type | Required | Description |
|---|---|---|---|
| page | integer | default 1 | Page number. |
| per_page | integer | default 50, max 200 | Results per page. |
| active | string | optional | Filter by status: y (active) or n (inactive). |
curl "https://api.clubin.co.il/webapi/v2/users/list/\
?page=1&per_page=50&active=y" \
-H "Authorization: Bearer clb_your_key"{
"status": "success",
"users": [
{
"id": 35057, "email": "[email protected]",
"name": "Dana Levi", "phone": "0500000000",
"active": "y", "is_expire": 0,
"membership_start": "2026-09-01",
"expire_date": null
}
],
"pagination": {
"page": 1, "per_page": 50,
"total": 128, "total_pages": 3
}
}Reactivate a member and extend their membership. With days, the expiry extends from the later of now or the current expiry — so consecutive renewals stack rather than overwrite. Without days, the membership becomes permanent.
| Field | Type | Required | Description |
|---|---|---|---|
| id / email | int / string | one of | Identifies the user. |
| days | integer | optional | Extend by N days (stacks on existing expiry). Omit or 0 = permanent. |
| send_access_mail | boolean | default false | Reset the password and email new access details. |
curl -X POST \
https://api.clubin.co.il/webapi/v2/users/renew/ \
-H "Authorization: Bearer clb_your_key" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"days": 30
}'{
"status": "success",
"user": {
"id": 35057, "email": "[email protected]",
"name": "Dana Levi"
},
"membership": {
"active": "y",
"is_expire": 1,
"expire_date": "2026-10-07"
},
"club_id": 999
}Open, change, or remove a user's access to a single course. Access is permanent or temporary (with an expiry), and both the opening date and the closing date can be set.
| Field | Type | Required | Description |
|---|---|---|---|
| string | required | The user (must be a member of the club). | |
| book_id | integer | required | The course id (alias: course_id). |
| access | string | required | permanent, temporary, or remove. |
| start_date | string | optional | Opening date YYYY-MM-DD. |
| expire_date | string | temporary | Closing date YYYY-MM-DD (for temporary access). |
| days | integer | optional | For temporary access, expire in N days (used if expire_date omitted; defaults to +1 year). |
curl -X POST \
https://api.clubin.co.il/webapi/v2/courses/access/ \
-H "Authorization: Bearer clb_your_key" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"book_id": 123,
"access": "temporary",
"expire_date": "2027-09-08"
}'{
"status": "success",
"user": { "id": 35057, "email": "[email protected]" },
"course": { "id": 123, "name": "Advanced Course" },
"access": "temporary",
"is_expire": 1,
"start_date": "2026-09-08",
"expire_date": "2027-09-08",
"club_id": 999
}access: permanent (is_expire 0, no expiry), temporary (is_expire 1, expire_date set), or removed when revoked. Returns 404 if the user is not a member of this club, or the course does not belong to it.
Returns the club's most recently added members, newest first. Powers the Make Watch New Members polling trigger. Members added through the app are source: "manual"; members created via this API are source: "api" — filter with source to watch, for example, only manual additions (which also avoids trigger loops from API-created users).
| Parameter | Type | Required | Description |
|---|---|---|---|
| limit | integer | default 50, max 200 | Max members returned per poll. |
| source | string | optional | manual (UI additions only), api, or omitted (all). |
curl "https://api.clubin.co.il/webapi/v2/users/new/\
?limit=50&source=manual" \
-H "Authorization: Bearer clb_your_key"{
"status": "success",
"items": [
{
"user_id": 35057,
"email": "[email protected]",
"name": "Dana Levi",
"phone": "0500000000",
"active": "y",
"source": "manual",
"added_at": "2026-09-09T14:30:00+03:00",
"added_ts": 1788900000
}
]
}Items are ordered by join date (newest first). In Make this maps to a Trigger module that emits each new member once.
Returns members that were deleted from the club, most recent first. Powers the Make Watch Removed Members polling trigger. Backed by a removal log, so it captures the deletion event even though the membership row is already gone.
| Parameter | Type | Required | Description |
|---|---|---|---|
| limit | integer | default 50, max 200 | Max removals returned per poll. |
| source | string | optional | manual (admin "delete member" action) or omitted (all). |
curl "https://api.clubin.co.il/webapi/v2/users/removed/\
?limit=50&source=manual" \
-H "Authorization: Bearer clb_your_key"{
"status": "success",
"items": [
{
"removal_id": 412,
"user_id": 35057,
"email": "[email protected]",
"source": "manual",
"removed_at": "2026-09-10T09:15:00+03:00",
"removed_ts": 1789000000
}
]
}Each removal carries a unique removal_id (the trigger key). This fires only on a full member deletion — not on membership deactivation or whole-club cancellation.
Add a post to the club's feed, attributed to a member, and publish it immediately (approved) or leave it pending. Approval is an admin action — it runs under the club's API key, so a regular member cannot approve; email only sets the post's author.
| Field | Type | Required | Description |
|---|---|---|---|
| string | required | The author (must be a member of the club). | |
| body | string | required | The post text. |
| url | string | optional | An attached link or image URL. |
| approve | boolean | default true | true publishes it (active y); false leaves it pending (n). |
curl -X POST \
https://api.clubin.co.il/webapi/v2/posts/ \
-H "Authorization: Bearer clb_your_key" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"body": "Welcome to the new season!",
"approve": true
}'{
"status": "success",
"post": {
"id": 9021,
"body": "Welcome to the new season!",
"url": "",
"active": "y",
"approved": true,
"add_date": "2026-09-15T10:00:00+03:00"
},
"user": { "id": 35057, "email": "[email protected]" },
"club_id": 999
}active: y published, n pending approval. Returns 404 if the author is not a member of this club.
Roadmap
Not yet implemented — the additions that would bring v2 to the standard integrators expect from a mature SaaS, roughly in order of value.
metadata & external_id on users
Let an integrator attach their own identifiers (CRM, store, spreadsheet row) to a Clubin user and look the user up by them. The single most useful addition for real integrations.
Machine-readable error codes
Add a stable code (e.g. "code": "user_not_found") alongside message, so integrations branch on a code instead of parsing prose.
Idempotency keys
Accept an Idempotency-Key header on create and renew so a retried request can't create or charge twice.
Full timestamps & audit fields
Return ISO 8601 datetimes with offset, and expose created_at / updated_at on each user and membership.
request_id in every response
A per-request identifier the caller can quote to support so the exact request is found in the logs.
Richer list filtering
Add a name/email search (q) and an expiry-date range to GET /users/list/, beyond the current active filter.
Webhooks
Emit events (user.created, membership.cancelled, membership.renewed) so integrations react in real time — this is what unlocks Make.com triggers.