Skip to content
Mock APIs

Guides

Authentication

Demo authentication lets you practice login forms, token storage, protected routes, token refresh, and role checks against real HTTP behavior.

For practice only

These flows are deliberately simple and use publicly documented demo accounts. Tokens are signed demo JWTs that only work with Mock APIs. Never use this API, these credentials, or these patterns to secure a real application, and never send real passwords to it.

Demo accounts

Demo credentials
RoleUsernamePasswordUse it to
adminemilycemilycpassAccess every demo route, including /auth/admin
usermichaelbmichaelbpassSee a 403 Forbidden on /auth/admin

Every seeded user can log in with the password <username>pass. You can log in with username or email.

The token flow

  1. POST /auth/login with credentials. You receive an accessToken (default 30 minutes; set expiresInMins between 1 and 1440) and a refreshToken (7 days).
  2. Send the access token on protected requests: Authorization: Bearer <accessToken>.
  3. When it expires you get 401 TOKEN_EXPIRED. Call POST /auth/refresh with the refresh token to get a new pair.

Practice expiry handling

Log in with "expiresInMins": 1 to get a token that expires after a minute, then exercise your refresh logic.

Registration

POST /auth/register validates the new account (including username and email conflicts with seeded users) and returns tokens for a simulated user. The account is not stored, but its access token works with /auth/me until it expires, so a sign-up form can complete its full flow.

Authentication errors

Failures use the standard error format. 401 responses include a WWW-Authenticate: Bearer header.

Authentication errors
StatusCodeWhen
401MISSING_TOKENNo Authorization header was sent.
401INVALID_AUTH_HEADERThe header is not in the form "Bearer <token>".
401INVALID_TOKENThe token is malformed, tampered with, signed by someone else, or the wrong type (e.g. a refresh token sent as an access token).
401TOKEN_EXPIREDThe token was valid but has expired. Refresh it or log in again.
401INVALID_CREDENTIALSWrong username/email or password on login.
403FORBIDDENThe token is valid but the user lacks the required role.

Where to keep tokens in your app

For learning purposes, keeping the access token in memory and the refresh token in sessionStorage is fine. Real applications should follow their platform's security guidance (for example HTTP-only cookies set by your own backend, or the platform keychain on mobile).

Log in (demo)

POST/api/v1/auth/login

Exchanges demo credentials for a short-lived demo access token and a refresh token. Use username or email. expiresInMins (1-1440) lets you practice token expiry.

Headers

Headers for Log in (demo)
NameInTypeDescription
Content-TyperequiredheaderstringMust be application/json.

Request body

Demo credentials.

Body fields for Log in (demo)
FieldTypeRequiredNotes
usernamestringNomin length 1, max length 100
emailstring (email)No
passwordstringYesmin length 1, max length 128
expiresInMinsintegerNomin 1, max 1440

Status codes

  • 200Tokens and the authenticated user.
  • 401Wrong username/email or password (INVALID_CREDENTIALS).
  • 422The JSON body failed validation (VALIDATION_ERROR).

Request

curl -X POST 'https://test.naimulhassan.me/api/v1/auth/login' \
  -H 'Content-Type: application/json' \
  -d '{
  "username": "emilyc",
  "password": "emilycpass",
  "expiresInMins": 30
}'

Example responses

Captured from the real API with the requests shown on this page.

200application/json
{
  "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.demo-payload.demo-signature",
  "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.demo-payload.demo-signature",
  "tokenType": "Bearer",
  "expiresIn": 1800,
  "demo": true,
  "notice": "Demo token for practice only. Do not use Mock APIs authentication to secure real applications.",
  "user": {
    "id": 1,
    "username": "emilyc",
    "email": "emily.carter@example.com",
    "firstName": "Emily",
    "lastName": "Carter",
    "role": "admin",
    "image": "https://test.naimulhassan.me/api/v1/images/users/1"
  }
}

Try it

POST
Headers
Open in playground
Send the request to see a live response.

Register (demo, simulated)

POST/api/v1/auth/register
Simulated - not persisted

Validates a registration request and returns tokens for a simulated new user. The account is not stored, but the returned access token works with /auth/me until it expires.

Headers

Headers for Register (demo, simulated)
NameInTypeDescription
Content-TyperequiredheaderstringMust be application/json.

Request body

New account details.

Body fields for Register (demo, simulated)
FieldTypeRequiredNotes
firstNamestringYesmin length 1, max length 50
lastNamestringYesmin length 1, max length 50
usernamestringYes
emailstring (email)Yes
passwordstringYesmin length 8, max length 72

Status codes

  • 201Tokens and the simulated user.
  • 409Username or email already taken by a seeded user (CONFLICT).
  • 422The JSON body failed validation (VALIDATION_ERROR).

Request

curl -X POST 'https://test.naimulhassan.me/api/v1/auth/register' \
  -H 'Content-Type: application/json' \
  -d '{
  "firstName": "Jordan",
  "lastName": "Lee",
  "username": "jordanlee",
  "email": "jordan.lee@example.com",
  "password": "supersecret1"
}'

Example responses

Captured from the real API with the requests shown on this page.

201application/json
{
  "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.demo-payload.demo-signature",
  "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.demo-payload.demo-signature",
  "tokenType": "Bearer",
  "expiresIn": 1800,
  "demo": true,
  "notice": "Demo token for practice only. Do not use Mock APIs authentication to secure real applications.",
  "user": {
    "id": 101,
    "username": "jordanlee",
    "email": "jordan.lee@example.com",
    "firstName": "Jordan",
    "lastName": "Lee",
    "role": "user",
    "image": null
  }
}

Try it

POST
Headers
Open in playground
Send the request to see a live response.

Get the current user

GET/api/v1/auth/me
Demo bearer token

Returns the user identified by the demo access token in the Authorization: Bearer <token> header.

Headers

Headers for Get the current user
NameInTypeDescription
AuthorizationrequiredheaderstringBearer <accessToken> from login or register.

Status codes

  • 200The authenticated user.
  • 401Missing header (MISSING_TOKEN), malformed header (INVALID_AUTH_HEADER), invalid token (INVALID_TOKEN), or expired token (TOKEN_EXPIRED).

Request

curl 'https://test.naimulhassan.me/api/v1/auth/me' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN'

Example responses

Captured from the real API with the requests shown on this page.

200application/json
{
  "id": 1,
  "username": "emilyc",
  "email": "emily.carter@example.com",
  "firstName": "Emily",
  "lastName": "Carter",
  "role": "admin",
  "image": "https://test.naimulhassan.me/api/v1/images/users/1"
}

Try it

GET
Headers

{{accessToken}} / {{refreshToken}} are replaced with a fresh demo token when you send.

Open in playground
Send the request to see a live response.

Refresh tokens

POST/api/v1/auth/refresh

Exchanges a valid refresh token for a new access token and refresh token.

Headers

Headers for Refresh tokens
NameInTypeDescription
Content-TyperequiredheaderstringMust be application/json.

Request body

The refresh token from login.

Body fields for Refresh tokens
FieldTypeRequiredNotes
refreshTokenstringYesmin length 1, max length 4096
expiresInMinsintegerNomin 1, max 1440

Status codes

  • 200New tokens and the user.
  • 401Invalid or expired refresh token (INVALID_TOKEN / TOKEN_EXPIRED).
  • 422The JSON body failed validation (VALIDATION_ERROR).

Request

curl -X POST 'https://test.naimulhassan.me/api/v1/auth/refresh' \
  -H 'Content-Type: application/json' \
  -d '{
  "refreshToken": "YOUR_REFRESH_TOKEN",
  "expiresInMins": 30
}'

Example responses

Captured from the real API with the requests shown on this page.

200application/json
{
  "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.demo-payload.demo-signature",
  "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.demo-payload.demo-signature",
  "tokenType": "Bearer",
  "expiresIn": 1800,
  "demo": true,
  "notice": "Demo token for practice only. Do not use Mock APIs authentication to secure real applications.",
  "user": {
    "id": 1,
    "username": "emilyc",
    "email": "emily.carter@example.com",
    "firstName": "Emily",
    "lastName": "Carter",
    "role": "admin",
    "image": "https://test.naimulhassan.me/api/v1/images/users/1"
  }
}

Try it

POST
Headers

{{accessToken}} / {{refreshToken}} are replaced with a fresh demo token when you send.

Open in playground
Send the request to see a live response.

Admin-only route

GET/api/v1/auth/admin
Demo bearer token

Practice role-based authorization. Returns 200 for users with the admin role and 403 for everyone else. Log in as michaelb to see a 403.

Headers

Headers for Admin-only route
NameInTypeDescription
AuthorizationrequiredheaderstringBearer <accessToken>.

Status codes

  • 200Access granted.
  • 401Missing or invalid token.
  • 403Authenticated, but not an admin (FORBIDDEN).

Request

curl 'https://test.naimulhassan.me/api/v1/auth/admin' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN'

Example responses

Captured from the real API with the requests shown on this page.

200application/json
{
  "message": "Welcome, Emily! You have access to this admin-only demo route.",
  "user": {
    "id": 1,
    "username": "emilyc",
    "email": "emily.carter@example.com",
    "firstName": "Emily",
    "lastName": "Carter",
    "role": "admin",
    "image": "https://test.naimulhassan.me/api/v1/images/users/1"
  }
}

Try it

GET
Headers

{{accessToken}} / {{refreshToken}} are replaced with a fresh demo token when you send.

Open in playground
Send the request to see a live response.