Connect your gym management system to GymBuddy. Import members, pull match data, and sync sessions.
All API endpoints are served at /api/v1 relative to your GymBuddy instance.
Every request must include your gym's API key in the X-API-Key header. Keys are scoped to a single gym — a key from Gym A cannot access Gym B's data.
curl https://your-gymbuddy.replit.app/api/v1/members \
-H "X-API-Key: YOUR_API_KEY"
Find your API key in the Admin Dashboard → API Integration section. Use "Rotate" to generate a new key and immediately invalidate the old one.
Returns a paginated list of members at your gym.
| Query param | Type | Default | Description |
|---|---|---|---|
| page | integer | 1 | Page number (1-indexed) |
| per_page | integer | 20 | Results per page (max 100) |
{
"data": [
{
"id": 2,
"name": "Marcus Rivera",
"focus_areas": ["Chest", "Back", "Shoulders"],
"training_style": "Bodybuilding",
"joined_at": "2025-01-15T10:30:00+00:00"
}
],
"total": 42,
"page": 1,
"per_page": 20
}
Creates a user account for an existing gym member. Returns a one-time temp_password the gym should share with the member.
| Field | Required | Description |
|---|---|---|
| name | ✅ yes | Member's full name |
| ✅ yes | Unique email within the gym | |
| focus_areas | no | Array of muscle groups (e.g. ["Chest","Back"]) |
| training_style | no | e.g. "Bodybuilding", "Powerlifting", "CrossFit" |
| experience_years | no | Integer, defaults to 1 |
| weekly_frequency | no | Sessions per week, defaults to 3 |
curl -X POST /api/v1/members \
-H "X-API-Key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Alex Chen","email":"alex@gym.com","focus_areas":["Legs"]}'
// Response 201
{
"data": {
"id": 12,
"name": "Alex Chen",
"email": "alex@gym.com",
"focus_areas": ["Legs"],
"training_style": "",
"joined_at": "2026-06-13T09:00:00+00:00",
"temp_password": "Xk9mR2vLpQwN"
}
}
Returns all buddy matches (pending and accepted) for your gym, ordered by most recent first.
{
"data": [
{
"id": 5,
"requester": {"id": 1, "name": "Marcus Rivera"},
"matched": {"id": 3, "name": "Priya Sharma"},
"status": "accepted",
"compatibility_pct": 99,
"created_at": "2026-06-13T08:00:00+00:00"
}
],
"total": 8,
"page": 1,
"per_page": 20
}
Returns all confirmed workout sessions at your gym.
{
"data": [
{
"id": 3,
"user1": {"id": 1, "name": "Marcus Rivera"},
"user2": {"id": 3, "name": "Priya Sharma"},
"session_date": "2026-06-15",
"session_time": "7:00 AM",
"focus_area": "Chest",
"created_at": "2026-06-13T08:00:00+00:00"
}
],
"total": 3,
"page": 1,
"per_page": 20
}
Generates a new API key, stores its SHA-256 hash, and immediately invalidates the old key. Requires the admin JWT in Authorization: Bearer <token> — not the API key. The raw key is returned exactly once; save it immediately.
curl -X POST /api/v1/keys/rotate \
-H "Authorization: Bearer ADMIN_JWT"
// Response 200
{
"api_key": "new_raw_key_here",
"api_key_masked": "newrawk••••••••",
"note": "Save this key now — it will not be shown again."
}
All errors return JSON with an error field:
| HTTP status | Meaning |
|---|---|
| 400 | Bad request — missing or invalid field in the request body |
| 401 | Missing or invalid X-API-Key header |
| 404 | Resource not found |
| 409 | Conflict — e.g. member email already exists |
| 500 | Internal server error |
{ "error": "A member with this email already exists at this gym" }