API v1 Integration Docs

GymBuddy Public API

Connect your gym management system to GymBuddy. Import members, pull match data, and sync sessions.

Authentication Members Matches Sessions Key Rotation Errors

Base URL

All API endpoints are served at /api/v1 relative to your GymBuddy instance.

Authentication

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.

Members

GET /api/v1/members Paginated member list

Returns a paginated list of members at your gym.

Query paramTypeDefaultDescription
pageinteger1Page number (1-indexed)
per_pageinteger20Results 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
}
POST /api/v1/members Import a member

Creates a user account for an existing gym member. Returns a one-time temp_password the gym should share with the member.

FieldRequiredDescription
name✅ yesMember's full name
email✅ yesUnique email within the gym
focus_areasnoArray of muscle groups (e.g. ["Chest","Back"])
training_stylenoe.g. "Bodybuilding", "Powerlifting", "CrossFit"
experience_yearsnoInteger, defaults to 1
weekly_frequencynoSessions 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"
  }
}

Matches

GET /api/v1/matches All matches at the gym

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
}

Sessions

GET /api/v1/sessions All confirmed sessions

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
}

Key Rotation

POST /api/v1/keys/rotate Rotate API key (admin JWT required)

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."
}

Error Responses

All errors return JSON with an error field:

HTTP statusMeaning
400Bad request — missing or invalid field in the request body
401Missing or invalid X-API-Key header
404Resource not found
409Conflict — e.g. member email already exists
500Internal server error
{ "error": "A member with this email already exists at this gym" }