Welcome to the GymBase API developer guide. This document provides complete coverage of all available endpoints, parameter shapes, authentication, rate limits, and request/response payloads.
GymBase is structured as a double-portal application:
- Web Console (React/Vite): Interactive dashboard for key retrieval and playground testing.
- API Engine (Node.js/Express/MongoDB): Delivers exercise JSON resources and records usage.
- Local Development:
http://localhost:5000 - Production Deployed: Serve from the Vercel app domain (e.g.,
https://gymbase-api.vercel.app)
The GymBase API uses two different authentication mechanisms depending on the route type.
Used for programmatic, non-session access to the Exercise database.
- Header Name:
x-api-key - Format:
gb_[a-f0-9]{48}(e.g.,gb_a7f9bc88aefc...) - Obtained via: Web Console dashboard (after email verification).
Used for session-based user interactions, including managing checkouts and retrieving personal api billing/usage stats.
- Header Name:
Authorization - Format:
Bearer <JWT_TOKEN_STRING>
Rate limits are enforced on all exercise endpoints. The client is identified by their API Key or JWT Bearer token.
| Tier | Daily Limit | Monthly Limit |
|---|---|---|
| Free | 50 calls | 500 calls |
| Developer Pro | 500 calls | 5,000 calls |
| Business | Unlimited | Unlimited |
When a limit is reached, the server responds with a 429 status code:
{
"error": "Daily API limit exceeded. Current plan: free. Limit: 50 calls/day",
"plan": "free",
"limit": 50
}These endpoints manage user registration, validation, login, and password resets. They do not require authentication headers.
- Method & Path:
POST /api/auth/register - Request Body:
{ "email": "developer@example.com", "password": "strongpassword123" } - Success Response (201 Created):
{ "message": "User registered successfully. Please verify your email.", "userId": "c0a80101-0000-0000-0000-000000000001" }
- Method & Path:
GET /api/auth/verify-email/:token - Parameters:
token(String, from email link) - Success Response (200 OK):
{ "message": "Email successfully verified. You can now login." }
- Method & Path:
POST /api/auth/login - Request Body:
{ "email": "developer@example.com", "password": "strongpassword123" } - Success Response (200 OK):
{ "message": "Login successful", "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ey..." }
- Method & Path:
POST /api/auth/forgot-password - Request Body:
{ "email": "developer@example.com" } - Success Response (200 OK):
{ "message": "Password reset link sent to email" }
- Method & Path:
POST /api/auth/reset-password/:token - Parameters:
token(String, reset token from email link) - Request Body:
{ "password": "newstrongpassword456" } - Success Response (200 OK):
{ "message": "Password has been updated successfully" }
- Required Header:
x-api-key: <API_KEY>orAuthorization: Bearer <JWT> - Enforced: Email verification check, daily/monthly tier rate limiter.
- Method & Path:
GET /api/exercises - Success Response (200 OK): Returns list of exercises with absolute image URLs.
[ { "id": "1", "name": "3/4 Sit-Up", "description": "A beginner level strength exercise targeting the abdominals.", "steps": [ "Lie down on the floor and secure your feet...", "Flex your hips and spine to raise your torso toward your knees..." ], "image": "http://localhost:5000/images/1.jpg", "ytLink": "https://www.youtube.com/results?search_query=how+to+do+3/4+Sit-Up", "musclesAffected": [ "abdominals" ] } ]
- Method & Path:
GET /api/exercises/id/:id - Success Response (200 OK):
{ "id": "1", "name": "3/4 Sit-Up", "description": "A beginner level strength exercise targeting the abdominals.", "image": "http://localhost:5000/images/1.jpg", ... } - Error Response (404 Not Found):
{ "error": "Exercise not found" }
- Method & Path:
GET /api/exercises/name/:name - Success Response (200 OK): Case-insensitive match. Returns a single exercise.
- Method & Path:
GET /api/exercises/muscle/:muscle - Success Response (200 OK): Returns array of exercises affecting the requested muscle (e.g.
abdominals,hamstrings,chest).
- Required Header:
Authorization: Bearer <JWT>
- Method & Path:
GET /api/usage - Success Response (200 OK):
{ "daily": { "used": 12, "limit": 50 }, "monthly": { "used": 87, "limit": 500 }, "plan": "free", "history": [ { "date": "2026-06-05", "day": "Fri", "calls": 8 }, { "date": "2026-06-06", "day": "Sat", "calls": 4 } ], "api_key": "gb_a7f9bc88aefc...", "subscription_start_date": null, "subscription_end_date": null, "last_payment_receipt_url": null }
- Required Header:
Authorization: Bearer <JWT>
- Method & Path:
POST /api/payment/create-checkout-session - Request Body:
{ "planId": "developer-pro" } - Success Response (200 OK):
{ "sessionId": "cs_test_a1...", "url": "https://checkout.stripe.com/c/pay/cs_test_..." }
- Method & Path:
GET /api/payment/confirm-payment/:sessionId - Success Response (200 OK): Updates user subscription tier and records billing.
{ "success": true, "plan": "pro", "subscription_end_date": "2026-07-06T12:00:00.000Z" }
- Method & Path:
POST /api/payment/webhook - Auth: Validated using Stripe Signature headers (
stripe-signature). Takes raw payload. - Success Response (200 OK):
{ "received": true }
curl -X GET "http://localhost:5000/api/exercises" \
-H "x-api-key: gb_your_copied_api_key"const response = await fetch('http://localhost:5000/api/exercises/id/1', {
headers: {
'x-api-key': 'gb_your_copied_api_key'
}
});
const data = await response.json();
console.log(data);import requests
url = "http://localhost:5000/api/exercises/muscle/chest"
headers = {"x-api-key": "gb_your_copied_api_key"}
response = requests.get(url, headers=headers)
exercises = response.json()