🔐 Authentication
POST
/api/login
Login with email & password
▼
✅ Success Response (200)
{"success": true, "message": "Login successful", "data": {"user_id": 1, "name": "Super Admin", "email": "superadmin@gymops.com", "role": "super_admin", "gym_id": null, "message": "Use X-User-Id header with value 1 for subsequent API calls"}}❌ Error Response (401)
{"success": false, "message": "Invalid credentials"}
GET
/api/me
Get current authenticated user
▼
No additional parameters. Uses X-User-Id header.
✅ Success Response (200)
{"success": true, "data": {"id": 1, "name": "Super Admin", "email": "superadmin@gymops.com", "role": "super_admin", "gym_id": null, "status": "active", "gym": null}}
POST
/api/change-password
Change your password
▼
✅ Success Response (200)
{"success": true, "message": "Password changed successfully"}🏢 Super Admin — Gym Management
POST
/api/super-admin/gyms
Create a new gym with unique gym_id
▼
✅ Success Response (201)
{"success": true, "message": "Gym created successfully with admin account", "data": {"gym": {"id": 2, "gym_id": "GYM-AB12CD34", "name": "PowerGym", "gym_email": "powergym@example.com", "status": "active"}, "admin": {"user_id": 5, "name": "PowerGym Admin", "email": "admin.powergym@example.com"}, "admin_user_id": 5, "admin_email": "admin.powergym@example.com"}}
GET
/api/super-admin/gyms
List all gyms with member/trainer counts
▼
✅ Success Response (200)
{"success": true, "data": {"data": [{"id": 1, "gym_id": "GYM-DEMO0001", "name": "FitLife Gym", "status": "active", "members_count": 2, "trainers_count": 1}], "current_page": 1, "total": 1}}
GET
/api/super-admin/gyms/{id}
Get single gym details
▼
✅ Success Response (200)
{"success": true, "data": {"id": 1, "gym_id": "GYM-DEMO0001", "name": "FitLife Gym", "gym_email": "fitlife@example.com", "status": "active", "members_count": 2, "trainers_count": 1, "gym_admin": {"id": 2, "email": "admin@fitlife.com", "name": "FitLife Gym Admin", "status": "active"}}}
PATCH
/api/super-admin/gyms/{id}/activate
Activate a gym
▼
✅ Success (200)
{"success": true, "message": "Gym activated successfully"}
PATCH
/api/super-admin/gyms/{id}/deactivate
Deactivate a gym
▼
✅ Success (200)
{"success": true, "message": "Gym deactivated successfully"}
PUT
/api/super-admin/gyms/{id}/subscription
Assign subscription plan to gym
▼
✅ Success (200)
{"success": true, "message": "Subscription assigned successfully"}💰 Super Admin — SaaS Revenue & Payments
GET
/api/super-admin/saas/overview
Total gyms, members, revenue overview
▼
✅ Success (200)
{"success": true, "data": {"total_gyms": 1, "active_gyms": 1, "inactive_gyms": 0, "monthly_saas_revenue": "12000.00", "gyms": [{"gym_id": "GYM-DEMO0001", "name": "FitLife Gym", "members_count": 2, "status": "active"}]}}
GET
/api/super-admin/saas/payment-status
Payment status per gym
▼
GET
/api/super-admin/saas/expiring-gyms
Gyms expiring within 30 days
▼
POST
/api/super-admin/gym-payments
Record gym subscription payment
▼
✅ Success (201)
{"success": true, "message": "Payment recorded successfully", "data": {"id": 1, "gym_id": 1, "amount": "12000.00", "plan": "yearly", "invoice_number": "INV-20260331-AB12CD", "status": "paid"}}
GET
/api/super-admin/gym-payments/{gymId}/history
Gym payment history
▼
GET
/api/super-admin/gym-payments
All gym payments (filterable)
▼
✅ Success (200)
{"success": true, "data": {"payments": {"data": []}, "summary": {"total_paid": "12000.00", "total_pending": "0.00", "total_payments": 1}}}
GET
/api/super-admin/gym-payments/summary
Per-gym payment summary with totals
▼
✅ Success (200)
{"success": true, "data": [{"gym_id": 1, "gym_code": "GYM-DEMO0001", "name": "FitLife Gym", "status": "active", "total_paid": "12000.00", "total_payments": 1, "last_payment_date": "2026-03-31"}]}
GET
/api/super-admin/gym-payments/{paymentId}/view
View invoice data as JSON
▼
GET
/api/super-admin/gym-payments/{paymentId}/invoice
Download gym invoice PDF
▼
GET
/api/super-admin/dashboard
Super Admin Dashboard
▼
✅ Success (200)
{"success": true, "data": {"total_gyms": 1, "active_gyms": 1, "inactive_gyms": 0, "total_revenue": "12000.00", "monthly_revenue": "12000.00", "top_gyms": [{"id": 1, "gym_id": "GYM-DEMO0001", "name": "FitLife Gym", "status": "active", "members_count": 2}], "expiry_alerts": []}}🔑 Super Admin — Password Management
PUT
/api/super-admin/users/{userId}/password
Set password for any user
▼
✅ Success (200)
{"success": true, "message": "Password updated successfully for John Doe", "data": {"user_id": 2, "name": "John Doe", "email": "john@example.com", "role": "gym_admin"}}
PUT
/api/super-admin/gyms/{gymId}/admin-password
Set/create gym admin password (auto-creates admin if none exists)
▼
✅ Admin Exists — Password Updated (200)
{"success": true, "message": "Password updated for admin of FitLife Gym", "data": {"user_id": 2, "name": "FitLife Gym Admin", "email": "fitlife@example.com", "created": false}}✅ No Admin — Admin Created (201)
{"success": true, "message": "Admin account created for FitLife Gym", "data": {"user_id": 5, "name": "FitLife Gym Admin", "email": "fitlife@example.com", "created": true}}❌ No Email on Gym (422)
{"success": false, "message": "Cannot create admin: gym has no contact email. Update gym_email first."}👥 Gym Admin — User Management
POST
/api/gym-admin/trainers
Add a new trainer
▼
✅ Success (201)
{"success": true, "message": "Trainer added successfully", "data": {"id": 6, "name": "Mike Trainer", "email": "mike.trainer@example.com", "role": "trainer", "trainer_salary": "30000.00"}}
POST
/api/gym-admin/members
Add a new member
▼
✅ Success (201)
{"success": true, "message": "Member added successfully", "data": {"id": 7, "name": "Charlie Member", "role": "member", "member_type": "self", "fitness_goal": "General Fitness"}}
GET
/api/gym-admin/users
List all users in your gym
▼
GET
/api/gym-admin/users/{id}
Get user details
▼
PUT
/api/gym-admin/users/{id}
Update user details
▼
DELETE
/api/gym-admin/users/{id}
Delete a user (trainer/member)
▼
PATCH
/api/gym-admin/users/{id}/activate
Activate a user
▼
PATCH
/api/gym-admin/users/{id}/deactivate
Deactivate a user
▼
PUT
/api/gym-admin/users/{id}/password
Reset password for member/trainer in same gym
▼
PATCH
/api/gym-admin/members/{id}/membership-expiry
Manual override for member membership expiry
▼
🏋️ Gym Admin — Members & Trainer Management
PATCH
/api/gym-admin/members/{memberId}/assign-trainer
Assign trainer to member
▼
PATCH
/api/gym-admin/members/{memberId}/remove-trainer
Remove trainer from member
▼
PATCH
/api/gym-admin/members/{memberId}/fitness-goal
Set member's fitness goal
▼
GET
/api/gym-admin/trainers
List trainers with member counts
▼
GET
/api/gym-admin/trainers/{trainerId}/members
View trainer's assigned members
▼
POST
/api/gym-admin/trainers/{trainerId}/assign-members
Assign multiple members to trainer
▼
📍 Gym Admin — Location Setup
POST
/api/gym-admin/location
Set gym geo-fence location
▼
GET
/api/gym-admin/location
Get gym location settings
▼
📅 Attendance System (Geo-Fenced)
POST
/api/attendance/check-in
Check in with GPS location
▼
✅ Success (200)
{"success": true, "message": "Checked in successfully", "data": {"attendance": {"id": 1, "user_id": 3, "gym_id": 1, "date": "2026-03-31", "time_in": "09:30:00", "lat_in": "19.07600000", "long_in": "72.87770000", "distance_in": "0.00", "status": "checked_in"}, "distance_from_gym": "0.00m"}}❌ Geo-fence Error (403)
{"success": false, "message": "You are 150.00m away from gym. Must be within 50m.", "data": {"distance": 150.00, "allowed_radius": 50}}
POST
/api/attendance/check-out
Check out with GPS location
▼
GET
/api/attendance/my-status
Get today's check-in status
▼
No additional parameters. Uses X-User-Id header.
✅ Checked In (200)
{"success": true, "data": {"checked_in": true, "attendance": {"id": 1, "date": "2026-03-31", "time_in": "09:30:00", "time_out": null, "status": "checked_in"}}}ℹ️ Not Checked In (200)
{"success": true, "data": {"checked_in": false, "attendance": null}}
GET
/api/attendance/my-history
Get my attendance history (all dates)
▼
Optional pagination. Uses X-User-Id header.
✅ Success (200)
{"success": true, "data": {"data": [{"id": 12, "date": "2026-03-30", "time_in": "09:12:00", "time_out": "18:03:00", "status": "checked_out"}], "current_page": 1, "total": 15}}
POST
/api/attendance/admin/check-in
Admin checks in a user (no geo-fence)
▼
✅ Success (200)
{"success": true, "message": "User checked in by admin", "data": {"attendance": {"id": 5, "user_id": 3, "gym_id": 1, "date": "2026-03-31", "time_in": "09:30:00", "status": "checked_in"}}}
POST
/api/attendance/admin/check-out
Admin checks out a user
▼
✅ Success (200)
{"success": true, "message": "User checked out by admin", "data": {"attendance": {"id": 5, "user_id": 3, "gym_id": 1, "date": "2026-03-31", "time_in": "09:30:00", "time_out": "17:00:00", "status": "checked_out"}}}
GET
/api/attendance/daily
Daily attendance report
▼
GET
/api/attendance/monthly
Monthly attendance report
▼
GET
/api/attendance/user/{userId}
User attendance history
▼
💳 Member Payment Management
POST
/api/gym-admin/member-payments
Record member payment (Admin only)
▼
✅ Success (201)
{"success": true, "message": "Payment recorded successfully", "data": {"id": 1, "member_id": 4, "amount": "2000.00", "plan": "monthly", "payment_mode": "upi", "status": "paid"}}
GET
/api/gym-admin/member-payments
List all member payments
▼
GET
/api/gym-admin/member-payments/dues
Members with pending dues
▼
GET
/api/gym-admin/member-payments/validity
Check membership validity for all members
▼
GET
/api/receipts/{paymentId}/download
Download member payment receipt PDF
▼
💼 Trainer Salary Management
PATCH
/api/gym-admin/trainers/{trainerId}/salary
Define trainer's monthly salary
▼
POST
/api/gym-admin/trainer-salaries
Record monthly salary
▼
✅ Success (201)
{"success": true, "message": "Salary record created", "data": {"id": 1, "trainer_id": 3, "amount": "25000.00", "salary_month": "2026-03", "status": "paid"}}
PATCH
/api/gym-admin/trainer-salaries/{salaryId}
Update salary status (paid/hold/reverted)
▼
GET
/api/gym-admin/trainer-salaries
List all salary records
▼
GET
/api/salary-slips/{salaryId}/download
Download salary slip PDF
▼
📊 Gym Admin Dashboard
GET
/api/gym-admin/dashboard
Gym admin dashboard overview
▼
✅ Success (200)
{"success": true, "data": {"members_count": 2, "active_members": 2, "trainers_count": 1, "monthly_earnings": "4000.00", "today_attendance": 3, "monthly_attendance": 45}}🏷️ Gym Sections / Sports Types Management
🔑 gym_id & corp_id are automatically set from X-User-Id
You do not pass
Use X-User-Id: 2 (Gym Admin of FitLife Gym → gym_id=1, corp_id=
You do not pass
gym_id in the request body. The server reads the authenticated user's gym from the X-User-Id header and scopes every section to that gym.Use X-User-Id: 2 (Gym Admin of FitLife Gym → gym_id=1, corp_id=
GYM-DEMO0001) for all section endpoints.
POST
/api/gym-admin/sections
Create a gym section or sports type (corp-scoped automatically)
▼
🔒 Auto-set from X-User-Id header (e.g. gym_id=1, corp_id=GYM-DEMO0001 for Gym Admin)
✅ Success (201)
{"success": true, "message": "Section created successfully", "data": {"id": 1, "gym_id": 1, "name": "Non A/C Gym", "type": "gym", "monthly_fee": "500.00", "yearly_fee": "5000.00", "status": "active"}}ℹ️ SaaS Scope
corp_id is auto-attached from the logged-in gym (no need to pass in request).
💡 Typical sections to create
• Non A/C Gym (type: gym) • Premium Gym (type: gym) • Ladies Gym (type: gym) • Badminton (type: sport)
GET
/api/gym-admin/sections
List all sections for this gym
▼
✅ Success (200)
{"success": true, "data": [{"id": 1, "name": "Non A/C Gym", "type": "gym", "monthly_fee": "500.00", "yearly_fee": "5000.00", "status": "active", "active_members_count": 12, "assigned_trainers_count": 2}]}
GET
/api/gym-admin/sections/{id}
Show a single section
▼
✅ Success (200)
{"success": true, "data": {"id": 1, "name": "Non A/C Gym", "type": "gym", "monthly_fee": "500.00", "yearly_fee": "5000.00", "status": "active", "active_members_count": 12, "assigned_trainers_count": 2}}
PUT
/api/gym-admin/sections/{id}
Update section name, fees or type
▼
✅ Success (200)
{"success": true, "message": "Section updated successfully", "data": {"id": 1, "name": "Non A/C Gym", "monthly_fee": "600.00"}}
PATCH
/api/gym-admin/sections/{id}/activate
Activate a section
▼
PATCH
/api/gym-admin/sections/{id}/deactivate
Deactivate a section
▼
DELETE
/api/gym-admin/sections/{id}
Delete a section (blocked if any members exist)
▼
🧑🏫 Section Trainers
🔑 gym_id is auto-scoped from X-User-Id — only trainers belonging to the same gym can be assigned to sections. Use X-User-Id: 2 (Gym Admin).
POST
/api/gym-admin/sections/{id}/trainers
Assign a trainer to a section
▼
✅ Success (201)
{"success": true, "message": "Trainer assigned to section", "data": {"id": 1, "section_id": 1, "trainer_id": 3, "status": "active", "trainer": {"id": 3, "name": "John Trainer", "email": "trainer@gym.com"}}}
DELETE
/api/gym-admin/sections/{id}/trainers/{trainerId}
Remove a trainer from a section
▼
GET
/api/gym-admin/sections/{id}/trainers
List trainers assigned to a section
▼
GET
/api/gym-admin/sections/{id}/members
List members enrolled in a section
▼
✅ Success (200)
{"success": true, "data": {"data": [{"id": 1, "member": {"id": 4, "name": "Alice", "email": "alice@gym.com"}, "trainer": null, "plan": "monthly", "expiry_date": "2026-05-24", "status": "active"}]}}
POST
/api/gym-admin/sections/{id}/members
Assign one or more members to section (program alias supported)
▼
✅ Success (201)
{"success":true,"message":"Members assigned to section successfully","data":{"created_memberships":[{"id":12,"section_id":1,"member_id":4,"status":"active"}],"skipped_members":[],"section":{"id":1,"name":"Yoga","members_count":3,"trainers_count":1}}}
DELETE
/api/gym-admin/sections/{id}/members/{memberId}
Unassign member from section (cancels active membership)
▼
🪪 Section Memberships
🔑 gym_id is auto-set from X-User-Id — you do not pass
section_id and member_id must both belong to the same gym. Use X-User-Id: 2 (Gym Admin).
gym_id in the body. The enrollment is automatically scoped to the gym admin's gym.section_id and member_id must both belong to the same gym. Use X-User-Id: 2 (Gym Admin).
POST
/api/gym-admin/section-memberships
Enroll a member in a section (trainer-assigned or self)
▼
🔒 Auto-set from X-User-Id header — section & member must belong to the same gym
✅ Success (201)
{"success": true, "message": "Member enrolled in section successfully", "data": {"id": 1, "section": {"id": 1, "name": "Non A/C Gym", "type": "gym"}, "member": {"id": 4, "name": "Alice"}, "trainer": null, "member_type": "self", "plan": "monthly", "amount": "500.00", "start_date": "2026-04-24", "expiry_date": "2026-05-24", "status": "active"}}❌ Already enrolled (422)
{"success": false, "message": "Member is already actively enrolled in this section. Use payment endpoint to extend expiry."}
GET
/api/gym-admin/section-memberships
List all section memberships with filters
▼
GET
/api/gym-admin/section-memberships/expiring
Members whose section membership is expiring soon
▼
GET
/api/gym-admin/section-memberships/dues
Members with expired section memberships (auto-marks them expired)
▼
GET
/api/gym-admin/section-memberships/{id}
Show a single section membership with payment history
▼
PUT
/api/gym-admin/section-memberships/{id}
Update membership plan, trainer, or expiry date
▼
PATCH
/api/gym-admin/section-memberships/{id}/expiry
Manual expiry override for section membership
▼
PATCH
/api/gym-admin/section-memberships/{id}/cancel
Cancel a section membership
▼
PATCH
/api/gym-admin/section-memberships/{id}/assign-trainer
Assign a trainer to a member's section membership
▼
PATCH
/api/gym-admin/section-memberships/{id}/remove-trainer
Remove trainer from a membership (switches to self)
▼
💰 Section Membership Payments
🔑 gym_id is auto-scoped from X-User-Id — the
section_membership_id must belong to a membership within the same gym. Use X-User-Id: 2 (Gym Admin).
POST
/api/gym-admin/section-membership-payments
Record payment & extend section membership expiry
▼
🔒 Auto-set from X-User-Id — payment is scoped to the gym admin's gym
✅ Success (201)
{"success": true, "message": "Payment recorded. Membership extended to 2026-06-24", "data": {"payment": {"id": 1, "amount": "500.00", "payment_mode": "cash", "plan": "monthly", "valid_from": "2026-05-24", "valid_to": "2026-06-24"}, "membership": {"id": 1, "expiry_date": "2026-06-24", "status": "active"}, "validity": {"base_start": "2026-05-24", "new_expiry": "2026-06-24"}}}
GET
/api/gym-admin/section-membership-payments
List all section membership payments
▼
GET
/api/gym-admin/section-membership-payments/{id}
Show a single section payment record
▼
📱 Flutter v1 / Mobile APIs
GET
/api/v1/gym-admin/programs
Paginated program list with stable counts
▼
GET
/api/v1/gym-admin/programs/{programId}/members
Program member assignments with assignment_id
▼
POST
/api/v1/gym-admin/programs/{programId}/members
Create program member assignment
▼
GET
/api/v1/gym-admin/lookup/members
Searchable member picker endpoint
▼
GET
/api/v1/gym-admin/auth-policy
Gym QR/password policy
▼
PUT
/api/v1/gym-admin/auth-policy
Update gym auth policy
▼
GET
/api/v1/gym-admin/qr/live
Fetch active rotating QR
▼
GET
/api/v1/mobile/auth/eligibility
Public eligibility check with reason codes
▼
POST
/api/v1/mobile/auth/qr/scan
Validate QR and mark attendance
▼
POST
/api/v1/gym-admin/attendance/mark
Manual admin attendance entry
▼
GET
/api/v1/gym-admin/audit-logs
Audit stream for assignment, policy, QR, and attendance changes
▼
GymOps API v1.0 • Built with Laravel • Multi-Tenant SaaS Gym Management
Seed Users: Super Admin (ID: 1) • Gym Admin (ID: 2) • Trainer (ID: 3) • Member Alice (ID: 4) • Member Bob (ID: 5)