Skip to main content
This file documents the authentication and account endpoints currently exposed by the application.

Table of Contents

  1. Overview
  2. Base URL and Headers
  3. Register
  4. Login
  5. Verify Email
  6. Resend Verification Email
  7. Send Forgot Password Email
  8. Reset Password
  9. Get Authenticated User
  10. Update Password
  11. Logout
  12. Logout From All Devices
  13. Delete My Account
  14. Restore Soft-Deleted User
  15. Admin Verify User Email
  16. Generate Impersonation Link
  17. Internal Reused Methods
  18. Known Implementation Notes

1. Overview

These endpoints cover:
  • account registration
  • login and token issuance
  • email verification
  • forgot-password and reset-password flow
  • current authenticated user payload
  • password changes
  • logout flows
  • self-account deletion
  • admin restore and admin email verification
  • admin impersonation link generation
The login flow uses Laravel Sanctum tokens.

2. Base URL and Headers

Base API URL:
Suggested Postman variables:
Default JSON headers:
Protected endpoints also need:

3. Register

Creates a new default user account and sends a verification email.

Request JSON

Success Response

Validation Error Example

Duplicate Email Example

Important notes:
  • this endpoint creates the account with role_id = 1
  • phone_number is optional
  • image_id is optional

4. Login

Authenticates the user and returns a Sanctum token.

Basic Request JSON

Success Response

Since 19/10/2026 (Auth User Super Fast, step 4) the success response also carries user: the same slim boot payload as GET /auth/user (§9), built by the same AuthUserPayloadService, so the apps paint the dashboard after one round trip instead of calling GET /auth/user right after the login. A staff login carries the profile, company, role.permissions and notifications only; a student login also has my_trainings, my_exams, validated_lesson_ids, certifications and cart_summary. Older app builds ignore the key. ?legacy=1 does not apply here.
The user block is abridged here: its full shape, key by key, is in §9.

2FA Request Example

2FA Required Example

Invalid Credentials Example

Unverified Email Example

Captcha Failure Example

Important notes:
  • if TURNSTILE_BYPASS=false, the initial login request also needs turnstileToken
  • if 2FA is enabled, you can use either 2fa_code or 2fa_recovery_code
  • blocked users are rejected

5. Verify Email

Marks the user email as verified through a signed URL. This route uses Laravel signed middleware, so Postman needs the full signed URL from the email.

Example Request

Already Verified Example

User Not Found Example

Important note:
  • on success, this endpoint returns an HTML verification view, not a JSON payload

6. Resend Verification Email

Resends the verification email.

Example Request

Success Response

Already Verified Example

Note:
  • this route is throttled with throttle:6,1

7. Send Forgot Password Email

Sends a reset-password email.

Example Request

Success Response

Failure Example


8. Reset Password

Resets the password using the token received by email.

Request JSON

Success Response

Failure Example


9. Get Authenticated User

Returns the boot payload of the apps: the current user, their company and role, the newest notifications and, for a student, one card per owned training / exam with the student’s progress and attempt summary computed server-side.
Changed on 19/10/2026 — slim payload (AuthUserPayloadService). The response went from ~1.5 MB to ~20 KB for the sample student: it carries no question banks, no lesson bodies, no order history and no attempt history any more. Removed keys: orders, cart, wishlist, lessons, quiz_student_attempts, reviews, trainings_as_instructor, images_uploaded, applied_coupons, classroom_joined_slugs, classroom_admin_slugs, owned_trainings, owned_exams, public_profile_website / _description / _phone_number / _location / _email. New keys (students): my_trainings, my_exams, validated_lesson_ids, cart_summary; certifications is flat (training_id / quiz_id). notifications holds the 3 newest items (was 10). Every date is Y-m-d H:i:s. Older app builds can keep the old shape with ?legacy=1 for one release. See Auth User Optimize for the full plan and what shipped.

Example Request

Response Shape

The body is never wrapped in a data key. Every role gets the first three groups; the student blocks are present only when role_id is 1. categories on the my_trainings[] and my_exams[] cards (since 01/11/2026) is the [{ "id", "label" }] list of the marketplace preview cards: one item, since a training or an exam has one category (Trainings → Assign categories, Quizzes & Exams §3.3), or [] when it has none. The apps use it for the My Trainings category filter and the My Exam Simulator groups. What is never in this payload: quiz_questions, is_correct, explanation, lesson content, revenue_percentage, the instructor’s email / default_revenue_percentage, order rows, attempt rows.

Case A — Student (role_id: 1)

Captured on 19/10/2026 against a local backend (lists shortened to one item; the card categories added on 01/11/2026):
Reading it: the student validated 4 of the 8 lessons of Business Analysis and passed 1 of its 2 quizzes, so the next thing to do is lesson 5 (“Documentation”); on PMP Mock Exam 1 they used 2 of 3 attempts (no reset yet), the best score is 80 % and the exam is passed; one exam sits in the cart.

Case B — Staff (instructor / content manager / admin / super-admin)

Same identity, company, role and notification keys; no my_trainings, my_exams, validated_lesson_ids, certifications or cart_summary. Staff screens use their own endpoints (instructor dashboard, admin lists). role.permissions carries the rows granted to that role in that company; a super-admin bypasses permission checks and may still get [].

Case C — Account with 2FA enabled

The only field that changes is two_factor_enabled (1). The TOTP secret and recovery codes are stored encrypted and never returned here; 2FA is enforced at /api/auth/login (§4).

Legacy shape (?legacy=1)

Returns the pre-19/10/2026 UserResource graph (orders[] with every chapter, lesson and question, cart, wishlist, lessons[], quiz_student_attempts[], nested certifications[].training / .quiz). Kept for one release so a stale mobile build keeps working; do not build anything new on it.

Error Response

Returned with HTTP 500 if the lookup throws. Since 19/10/2026 the raw exception text (which can carry SQL) is only echoed when APP_DEBUG is on; otherwise the message is a generic “Unable to load…” and the exception goes to the log / report().

10. Update Password

Changes the password for the authenticated account.

Request JSON

Success Response

Invalid Current Password Example


11. Logout

Deletes the current access token.

Success Response


12. Logout From All Devices

Deletes all personal access tokens for the target user.

Example Request

Success Response


13. Delete My Account

Soft-deletes the currently authenticated account.

Request JSON

Success Response

Forbidden Example

Wrong Password Example


14. Restore Soft-Deleted User

Restores a user deleted through Laravel soft delete.

Example Request

Success Response

Not Deleted Example

Unauthorized Example


15. Admin Verify User Email

Marks a target user’s email as verified.

Request JSON by User ID

Request JSON by Email

Success Response

Already Verified Example

Company Restriction Example


Generates a temporary signed impersonation URL for an admin or super-admin.

Request JSON by User ID

Request JSON by Email

Success Response

Forbidden Example


17. Internal Reused Methods

These methods are part of the same controller logic but do not have their own API route:
  • formatTrainings($trainings) Brief role: helper for nested training formatting inside authentication/account payload preparation.

18. Known Implementation Notes

  • verify_email returns an HTML view on success, not JSON.
  • adminVerifyEmail is declared outside the main authenticated route group, but the controller code expects an authenticated admin or super-admin.
  • generateImpersonateLink is also declared without explicit route middleware in api.php, but the controller expects an authenticated admin or super-admin.
  • Login uses Sanctum tokens even though the User model also implements JWTSubject.