Auth Service API

Base URL: https://auth.stashly.io

The auth service handles OTP-based login, JWT issuance, and session management. All apps authenticate through this service.


POST/auth/send-otp

Send a one-time password to the provided email address. Rate-limited to 5 requests per 15 minutes per IP.

Request Body

NameTypeDescription
email*stringThe email address to send the OTP to
200OTP sent
{ "success": true, "message": "OTP sent to your email" }
429Rate limited
{ "success": false, "message": "Too many OTP requests. Try again in 15 minutes." }
POST/auth/verify-otp

Verify an OTP and receive a JWT access token. A refresh token is set as an HTTP-only cookie.

Request Body

NameTypeDescription
email*stringThe email used to request the OTP
otp*string6-digit OTP received via email
200Authenticated
{
  "success": true,
  "data": {
    "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "user": {
      "id": "usr_01j9",
      "email": "you@example.com",
      "role": "admin",
      "tenantId": "ten_abc123"
    }
  }
}
401Invalid OTP
{ "success": false, "message": "Invalid or expired OTP" }
GET/auth/meJWT Required

Get the currently authenticated user's profile. Used by all apps to hydrate user state on load.

200Current user
{
  "success": true,
  "data": {
    "id": "usr_01j9",
    "email": "you@example.com",
    "role": "admin",
    "tenantId": "ten_abc123",
    "createdAt": "2025-01-15T10:00:00Z"
  }
}
401Unauthorized
{ "success": false, "message": "Access token is missing or invalid" }
POST/auth/refresh

Use the refresh token cookie to get a new access token. The refresh token is read from the HTTP-only cookie automatically.

200New access token
{
  "success": true,
  "data": { "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." }
}
401Refresh token invalid
{ "success": false, "message": "Refresh token is invalid or expired" }
POST/auth/logoutJWT Required

Log out the current user. Clears the refresh token cookie and invalidates the session.

200Logged out
{ "success": true, "message": "Logged out successfully" }