API Design Patterns

Account Management

The authenticated user manages themselves through /account. No resource ID needed because the token identifies who they are.

  • GET /account/profile - fetch your own profile
  • PATCH /account/profile - partial update (name, etc.)
  • DELETE /account/profile - soft delete your account

PATCH because the client sends whichever fields they want to change. Email is excluded from PATCH /account/profile because changing it requires verification through a separate flow.

Email Change

Two-step flow. The user requests the change while authenticated, then confirms it from their new inbox.

  • POST /account/email - sends a confirmation link to the new address
  • POST /auth/change-email - consumes the token from the link, swaps the email

Both are POST because they're actions, not resource replacements. POST /account/email doesn't change the email, it triggers a confirmation. POST /auth/change-email consumes a token and has side effects (deletes old tokens, updates verified timestamp). The confirmation endpoint is unauthenticated because the token was sent to the new inbox, which may be opened on a different device.

Forgot Password

Same two-step pattern as email change. Fully unauthenticated since the user has lost access.

  • POST /auth/forgot-password - sends a reset link
  • POST /auth/reset-password - consumes the token, sets the new password

Both POST for the same reasons as email change. Action pairs always share a naming pattern: verb-noun, hyphenated (forgot-password/reset-password, change-email).

Email Verification

Proves the user can receive messages at their current address. Unlike email change and password reset, this uses short codes instead of links because verification can be multi-channel (email, SMS).

  • POST /account/verify - submit a verification code
  • POST /account/verify/resend - request a new code

Nested under /account/verify because resending is a sub-action of the verification flow, not a standalone feature.

Token Refresh

  • POST /auth/token/refresh - rotates the current Sanctum token

POST because it creates a new token and invalidates the old one. Not PUT because you're not replacing a known resource at a URI, you're triggering a rotation.

Authentication

  • POST /auth/login - creates a token
  • POST /auth/logout - revokes the current token
  • POST /auth/register - creates a new account

All actions. Login and register return tokens, logout destroys one.

Admin

Admins manage any resource. Routes are namespaced under /admin and controllers live in Controllers/Admin/. An admin middleware on the group requires admin or super role as a safety net before per-route policy checks.

  • GET /admin/users - list users (search, filter by role, filter trashed)
  • GET /admin/users/{id} - show a user
  • PATCH /admin/users/{id} - partial update (name fields)
  • DELETE /admin/users/{id} - soft delete
  • DELETE /admin/users/{id}/force - hard delete or anonymize (follows prune strategy)
  • PATCH /admin/users/{id}/restore - restore a soft-deleted user
  • DELETE /admin/users/{id}/avatar - remove a user's avatar
  • PATCH /admin/users/{id}/role - set or remove a user's role
  • POST /admin/users/{id}/password-reset - force a password reset with a temp password

Sub-resource actions get their own controller (UserAvatarController, UserRoleController, etc.) rather than extra methods on UserController. Each controller stays small and single-purpose.

PATCH for updates because the admin sends a subset of fields. POST for password reset because it triggers side effects (generates a temp password, revokes tokens, sends an email).

Naming Conventions

  • Resource endpoints use nouns: /account/profile, /admin/users
  • Action endpoints use verb phrases: /auth/login, /auth/forgot-password, /auth/change-email
  • Always hyphenated: /auth/forgot-password, not /auth/forgotPassword
  • Action pairs share a base noun: forgot-password/reset-password, /account/email/change-email

When POST, When PUT, When PATCH

  • POST for actions that trigger side effects: consuming tokens, sending emails, creating sessions
  • PUT for full replacement of a resource at a known URI
  • PATCH for partial updates where the client sends a subset of fields
  • If the endpoint doesn't directly change the resource (it sends a link, queues a job, etc.), it's POST regardless of what it eventually leads to
© Websanova 2026 About Privacy