🔐 Authentication
Authentication Method: Bearer token via Laravel Sanctum.
After login/register, include the token in all protected requests:
Tokens are valid until manually revoked (no expiration by default). To revoke, use logout.
After login/register, include the token in all protected requests:
Authorization: Bearer {your_token}Tokens are valid until manually revoked (no expiration by default). To revoke, use logout.
POST
/register
Create a new user account.
📝 Request Body
{
"name": "John Doe",
"email": "john@example.com",
"password": "secret123",
"password_confirmation": "secret123"
}
✅ Example Response (201)
{
"user": {
"id": 1,
"name": "John Doe",
"email": "john@example.com",
"role": 1,
"type": null,
"wallet_balance": 0,
"membership_validity_from": null,
"membership_validity_to": null,
"created_at": "2025-03-28T10:00:00.000000Z",
"updated_at": "2025-03-28T10:00:00.000000Z"
},
"token": "1|abc123def456..."
}
POST
/login
Authenticate and get a token.
📝 Request Body
{
"email": "john@example.com",
"password": "secret123"
}
✅ Example Response (200)
{
"user": { ... },
"token": "2|xyz789..."
}
POST
/forgot-password
Send password reset link to email.
📝 Request Body
{"email": "john@example.com"}
✅ Example Response (200)
{"message": "We have emailed your password reset link!"}
POST
/reset-password
Reset password using token from email.
📝 Request Body
{
"token": "reset_token_here",
"email": "john@example.com",
"password": "newpassword",
"password_confirmation": "newpassword"
}
✅ Example Response (200)
{"message": "Your password has been reset!"}
POST
/logout
Revoke the current access token.
📝 Headers
Authorization: Bearer {token}
✅ Example Response (200)
{"message": "Logged out successfully"}
GET
/user
Get the authenticated user's profile.
✅ Example Response (200)
{
"id": 1,
"name": "John Doe",
"email": "john@example.com",
"role": 1,
"wallet_balance": 45.00,
"membership_validity_to": "2025-12-31"
}
🌍 Public Endpoints
No authentication required.
GET
/courses
Get all active courses with categories and packages.
🔍 Query Parameters
search(string) – Search by title or short description.category(int) – Filter by category ID.
✅ Example Response (200)
{
"courses": [
{
"id": 5,
"title": "Yoga for Beginners",
"slug": "yoga-for-beginners",
"plan": "one-time",
"price": 49.99,
"discounted_price": 39.99,
"banner": "https://...",
...
}
],
"categories": [{"id":1,"name":"Beginner"}],
"packages": [...]
}
GET
/courses/{identifier}
Get detailed course information or slug.
✅ Example Response (200)
{
"course": {...},
"offers": [...],
"reviews": [...]
}
GET
/packages/{slug}
Get package details including associated courses.
GET
/membership
List all memberships and membership-only courses.
POST
/coupon/check-course/{course}
Validate a coupon code for a specific course.
📝 Request Body
{"code": "SAVE10"}
✅ Example Response (200)
{
"valid": true,
"code": "SAVE10",
"type": "percentage",
"value": 10,
"message": "10% discount applied!"
}
GET
/course/{id}/reviews
List all reviews for a course.
GET
/membership
List all memberships.
👤 User Endpoints
All endpoints require authentication (Bearer token).
GET
/dashboard
Get dashboard statistics, recent certificates, and courses with progress.
✅ Example Response
{
"active_courses": 3,
"completed_courses": 5,
"total_certificates": 2,
"recent_certificates": [...],
"recent_learning": [...],
"courses": [ ... ] // with progress, total_sessions, completed_sessions
}
GET
/my-courses
List all courses the user has access to (direct purchase, package, membership) with progress.
GET
/my-classes
List courses where user is instructor or co-instructor.
GET
/certificates
List all certificates earned by the user.
GET
/learning-history
List all paid course orders (learning history).
GET
/my-membership
Get current membership details.
POST
/membership/cancel
Cancel active membership and get pro-rated refund added to wallet.
✅ Example Response
{"message": "Membership cancelled. 45.50 added to wallet."}
GET
/transactions
List user's transactions (wallet, refunds, etc.).
POST
/course/{id}/review
Submit a review for a course.
📝 Request Body
{
"rating": 5,
"review": "Amazing course!",
"name": "John Doe",
"email": "john@example.com"
}
📘 Course Content
GET
/courses/{course}/preview
Get course details including outline for enrolled users.
GET
/courses/{course}/discussion/messages
Fetch discussion messages (pagination via
last_id).🔍 Query Parameters
last_id – Get messages older than this ID (for loading more).
POST
/courses/{course}/discussion/messages
Post a new message or file in course discussion.
📝 Form Data
message(string, optional)file(file, max 10MB, optional)
✅ Example Response
{
"message": {
"id": 42,
"user_id": 1,
"course_id": 5,
"message": "Great class!",
"file_path": null,
"created_at": "...",
"user": { "id":1, "name":"John Doe" }
}
}
POST
/courses/{course}/zoom-create
Create a Zoom meeting (for instructors).
GET
/zoom/recording
Get Zoom recording links for a meeting.
🔍 Query Parameters
meeting_id (required), class_time (optional, for specific session).
✅ Example Response
{
"success": true,
"share_url": "https://zoom.us/rec/share/...",
"password": "123456",
"recordings": [{"play_url":"...","download_url":"..."}]
}
POST
/certificate/{order}
Upload PDF certificate for a completed course.
📝 Form Data
certificate (PDF file, max 10MB)
✅ Example Response
{
"message": "Certificate uploaded successfully",
"certificate_url": "https://.../certificate_123456.pdf"
}
💰 Checkout & Payments
POST
/checkout/course
Create an order for a course.
📝 Request Body
{
"name": "John Doe",
"email": "john@example.com",
"course_id": 5,
"payment_method": "stripe", // or "paypal"
"platform": "android", // optional; use "ios" for App Store builds
"coupon_code": "SAVE10" // optional
}
✅ Example Response (paid course)
{
"order": { "id": 101, "amount": 39.99, "payment_status": "pending" },
"payment_links": {
"stripe": "https://checkout.stripe.com/...",
"paypal": "https://www.paypal.com/checkoutnow?token=..."
}
}
✅ Example Response (iOS in-app purchase)
{
"order": { "id": 101, "amount": 39.99, "payment_status": "pending" },
"in_app_purchase": {
"provider": "app_store",
"product_id": "65b53e03e4b04982091eb2ad",
"status": "client_purchase_required"
}
}
🍎 Complete App Store Purchase
POST
/checkout/course/{order}/app-store/complete
{
"product_id": "65b53e03e4b04982091eb2ad",
"receipt_data": "{StoreKit serverVerificationData}",
"transaction_id": "{StoreKit transaction id}"
}
✅ Example Response (free/membership course)
{
"order": { "id": 102, "payment_status": "completed" },
"redirect": "/order/success/102"
}
GET
/payment/stripe/{order}
Initiate Stripe Checkout session, returns payment URL. Do not use this route from iOS App Store builds; use App Store in-app purchase instead.
✅ Example Response
{"redirect_url": "https://checkout.stripe.com/..."}
GET
/payment/paypal/redirect/{order}
Initiate PayPal payment, returns approval URL.
GET
/order/success/{order}
Get order details after successful payment (Stripe/PayPal call this automatically).
🎫 Support Tickets
GET
/tickets
List user's tickets.
POST
/tickets
Create new ticket.
📝 Request Body
{
"subject": "Login issue",
"category": "Account Issue",
"message": "I can't reset my password."
}
GET
/tickets/{ticket}
View ticket with replies.
POST
/tickets/{ticket}/reply
Add reply to ticket.
📝 Request Body
{"message": "Here's more info..."}
📝 Quizzes
GET
/quizzes/available
List quizzes the user hasn't taken yet.
GET
/quiz/{quizId}/start
Get quiz questions and create attempt.
✅ Example Response
{
"quiz": {...},
"attempt": {...},
"questions": [...],
"progress": {...}
}
POST
/quiz/attempt/{attemptId}/save-progress
Save partial progress (optional).
POST
/quiz/attempt/{attemptId}/submit
Submit final answers and get results.
📝 Request Body
{
"answers": {
"1": 3, // for multiple choice
"2": ["a","c"], // for multiple response
"3": "my answer" // for short answer
},
"time_spent": 120
}
GET
/quiz/result/{attemptId}
Get quiz result details.
GET
/quiz/leaderboard?quizId={optional}
View leaderboard for all quizzes or a specific one.
🔧 Admin Endpoints
Only users with role=0 (admin) can access these.
GET
/admin/tickets
List all tickets with filters (status, category, assigned).
POST
/admin/tickets/{ticket}/assign
Assign ticket to current admin/instructor.
POST
/admin/tickets/{ticket}/reassign
Reassign ticket to another user.
📝 Request Body
{"assigned_to": 5}
PATCH
/admin/tickets/{ticket}/status
Update ticket status (open, in_progress, resolved, closed).
📝 Request Body
{"status": "resolved"}
GET
/admin/logs
View application logs (file list).
POST
/admin/clear-cache
Clear Laravel cache (config, route, view).
⚠️ Error Handling
All errors return JSON with appropriate HTTP status codes.
| Status | Meaning | Example Response |
|---|---|---|
| 401 | Unauthorized – missing or invalid token | {"message": "Unauthenticated."} |
| 403 | Forbidden – insufficient permissions | {"message": "This action is unauthorized."} |
| 422 | Validation error | {"message": "The given data was invalid.", "errors": {"email": ["The email field is required."]}} |
| 500 | Server error | {"message": "Server Error"} |
Note: Paginated responses follow the structure:
{ "data": [...], "links": { "first": "...", "last": "...", "prev": null, "next": "..." }, "meta": { "current_page": 1, "from": 1, "last_page": 5, "per_page": 15, "to": 15, "total": 75 } }