Base URL: http://localhost:8080
Check if the server is running.
Response
{ "status": "healthy",
"database": "connected" }No authentication required.
Exchange a Firebase ID token for a custom JWT access token + refresh token. Creates the user in the database if they don't exist yet.
Request
{
"token": "<firebase_id_token>"
}Response
{
"access_token": "eyJ...",
"refresh_token": "eyJ...",
"expires_in": 604800,
"user": {
"id": 1,
"firebase_uid": "abc123",
"email": "user@example.com",
"firstname": "Tran",
"lastname": "Tran"
}
}Get a new access token using a refresh token.
Request
{
"refresh_token": "eyJ..."
}Response
{
"access_token": "eyJ...",
"refresh_token": "eyJ...",
"expires_in": 604800
}Requires Authorization: Bearer <access_token> header.
Register a device FCM token for push notifications.
Request
{
"token": "<fcm_device_token>"
}Remove a device FCM token.
Request
{
"token": "<fcm_device_token>"
}Send a test push notification to the authenticated user's devices.
Requires Authorization: Bearer <access_token> header. User must have is_admin = true in the database.
Returns 403 Forbidden if the user is not an admin.
Get all users.
Response
{
"data": [
{
"id": 1,
"firstname": "Tran",
"lastname": "Tran",
"email": "user@example.com",
"is_admin": true
}
]
}Promote a user to admin by email.
Request
{
"email": "user@example.com"
}Response
{
"data": {
"id": 1,
"firstname": "Tran",
"lastname": "Tran",
"email": "user@example.com",
"is_admin": true
}
}Demote a user from admin by email.
Request
{
"email": "user@example.com"
}Response
{
"data": {
"id": 1,
"firstname": "Tran",
"lastname": "Tran",
"email": "user@example.com",
"is_admin": false
}
}| Status | Meaning |
|---|---|
| 400 | Bad request — missing or invalid input |
| 401 | Unauthorized — missing or invalid token |
| 403 | Forbidden — not an admin |
| 404 | Not found |
| 500 | Internal server error |