Overview
The Club Schedule API allows external systems to manage club members programmatically. This is useful for integrating with membership management systems, payment processors, or other third-party applications that need to add, update, or deactivate members automatically.
Available Operations:
- Create member invitations
- Deactivate members
- Update membership expiration datesRequirements:
- Active SyncSchedule subscription
- Admin access to your club
Getting Started
Step 1: Generate Your API Key
- Log in to SyncSchedule as a club admin
- Navigate to Settings β API Settings
- Click Generate API Key
- Important: Copy your API key immediately β it will only be displayed once. Your API key will look like this: tcs_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6Step 2:
- Store your API key in a secure location (environment variable, secrets manager)
- Never commit API keys to version control
- Never share your API key publicly
Step 2: Managing Your API Key
From the API Settings page, you can:
- Disable Key: Temporarily stop all API access without deleting the key
- Enable Key: Re-enable a disabled key
- Regenerate Key: Create a new key (invalidates the old key immediately)
Authentication
All API requests must include your API key in the Authorization header using Bearer token format:
Authorization: Bearer tcs_your_api_key_here
Example Request
curl -X POST https://app.theclubschedule.com/api/v1/members/add/ \ -H "Authorization: Bearer tcs_your_api_key_here" \ -H "Content-Type: application/json" \ -d '{"email": "john@example.com", "first_name": "John", "last_name": "Doe", "joined_date": "2024-01-15"}'
API Endpoints
Base URL
https://app.theclubschedule.com/api/v1
Create Member Invitation
Creates an invitation for a new member. The invited person will receive an email with a link to accept the invitation and set up their account.
Endpoint: POST /api/v1/members/add/
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
| string | Yes | Email address of the person to invite | |
| first_name | string | Yes | First name (max 100 characters) |
| last_name | string | Yes | Last name (max 100 characters) |
| joined_date | string | Yes | Date the member joined (format: YYYY-MM-DD) |
| member_through | string | No | Membership expiration date (format: YYYY-MM-DD). Use null for lifetime membership. |
Example Request:
{ "email": "john@example.com", "first_name": "John", "last_name": "Doe", "joined_date": "2024-11-15", "member_through": "2025-03-31" }
Success Response (201 Created):
{ "id": 42, "email": "john@example.com", "first_name": "John", "last_name": "Doe", "joined_date": "2024-11-15", "member_through": "2025-03-31", "status": "pending", "invited_at": "2024-12-13T14:30:00Z", "expires_at": "2025-01-12T14:30:00Z", "email_sent": true }
Note: The response includes email_sent: true if the invitation email was sent successfully. If email sending fails, the invitation is still created and email_sent: false with email_error will be included.
Deactivate Member
Deactivates an existing member (soft delete). The member’s data is preserved but they will no longer have access to the club.
Endpoint: POST /api/v1/members/deactivate/
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
| string | Yes | Email address of the member to deactivate |
Example Request:
{ "email": "john@example.com" }
Success Response (200 OK):
{ "id": 15, "email": "john@example.com", "first_name": "John", "last_name": "Doe", "joined_date": "2024-01-15", "member_through": "2025-01-15", "is_active": false, "created_at": "2024-01-15T10:00:00Z", "updated_at": "2024-12-13T14:35:00Z" }
Update Membership Expiration
Updates the membership expiration date for an existing member.
Endpoint: POST /api/v1/members/update-through/
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
| string | Yes | Email address of the member | |
| member_through | string | Yes | New expiration date (format: YYYY-MM-DD) or null for lifetime membership |
Example Request β Set Expiration:
{ "email": "john@example.com", "member_through": "2025-12-31" }
Example Request β Set Lifetime Membership:
{ "email": "john@example.com", "member_through": null }
Success Response (200 OK):
{ "id": 15, "email": "john@example.com", "first_name": "John", "last_name": "Doe", "joined_date": "2024-01-15", "member_through": "2025-12-31", "is_active": true, "created_at": "2024-01-15T10:00:00Z", "updated_at": "2024-12-13T14:40:00Z" }
Error Responses
All error responses follow this format:
{ "error": "Human-readable error message", "code": "machine_readable_code" }
For validation errors, additional details are provided:
{ "error": "Validation failed", "code": "validation_error", "details": { "email": ["Enter a valid email address."], "joined_date": ["Date has wrong format. Use YYYY-MM-DD."] } }
Error Codes Reference
| HTTP Status | Code | Description |
|---|---|---|
| 400 | validation_error | Invalid request data. Check the details field for specific issues. |
| 401 | authentication_failed | Missing, invalid, or disabled API key. |
| 403 | permission_denied | API access not available (e.g., subscription inactive). |
| 404 | not_found | Member not found in your club. |
| 409 | member_exists | An active member with this email already exists. |
| 409 | inactive_member_exists | An inactive member exists. Use the web interface to resend their invitation. |
| 409 | invitation_pending | A pending invitation already exists for this email. |
| 409 | already_inactive | The member is already inactive. |
| 429 | throttled | Rate limit exceeded. Wait before retrying. |
| 500 | internal_error | Server error. Contact support if this persists. |
Rate Limiting
API requests are limited to 100 requests per hour per API key.
When you exceed the rate limit, you’ll receive a 429 Too Many Requests response:
{ "detail": "Request was throttled. Expected available in 1800 seconds." }
Best Practices:
- Batch operations where possible
- Implement exponential backoff for retries
- Monitor the Retry-After header when rate limited
Security Best Practices
- Keep your API key secret β Treat it like a password
- Use environment variables β Never hardcode keys in your application
- Rotate keys periodically β Regenerate your key if you suspect compromise
- Monitor API activity β Check the Recent API Activity section in your API Settings
- Use HTTPS only β All API requests must use HTTPS
Common Integration Scenarios
Syncing with a Payment Processor
When a new member pays through your payment system:
- Call POST /api/v1/members/add/ with member details
- Set member_through to match their subscription end date
- The member receives an invitation email to join SyncScheduleWhen membership is renewed:
- Call POST /api/v1/members/update-through/ with the new expiration dateWhen membership is cancelled:
- Call POST /api/v1/members/deactivate/ to remove their access
Example: Python Integration
import requests
API_KEY = "tcs_your_api_key_here"
BASE_URL = "https://app.theclubschedule.com/api/v1"
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
# Add a new member
response = requests.post(
f"{BASE_URL}/members/add/",
headers=headers,
json={
"email": "newmember@example.com",
"first_name": "Jane",
"last_name": "Smith",
"joined_date": "2024-12-13",
"member_through": "2025-12-13"
}
)
if response.status_code == 201:
print("Invitation sent!")
print(response.json())
elif response.status_code == 409:
print("Member or invitation already exists")
else:
print(f"Error: {response.json()}")
Need Help?
If you encounter issues with the API:
- Check the Recent API Activity in your API Settings for error details
- Verify your API key is active and not disabled
- Ensure your subscription is active
- Contact support at support@theclubschedule.com