Authorization header of each request. Save App supports two login methods: a direct phone/PIN login for testing and development, and Firebase Phone Authentication for production mobile apps.
How authentication works
- Your app sends a phone number and 4-digit PIN (or a Firebase ID token) to a login endpoint.
- The API returns a JWT bearer token along with the user’s name, role, and creator status.
- Your app includes the token on every subsequent request as
Authorization: Bearer <token>. - The token expires after 24 hours. After expiry, your app must log in again to get a new token.
sub claim. The API verifies the token on each request and loads the corresponding user record from the database.
Login methods
Phone and PIN login
UsePOST /api/auth/login to log in with a phone number and 4-digit numeric PIN. Phone numbers must be in Uganda format (+256XXXXXXXXX). This method is rate-limited.
Pass groupName to ensure the user belongs to the correct savings group. Pass loginType ("admin" or "member") to enforce role-based portal access — a member attempting admin login receives 403 Forbidden.
Firebase Phone Authentication
UsePOST /api/auth/firebase-login to log in with a Firebase ID token obtained after phone verification on the mobile client. This is the recommended flow for production apps because Firebase handles OTP delivery, SIM-swap detection, and phone number verification.
If the phone number does not already have an account, the API creates one automatically with role: member.
firebase-login endpoint is rate-limited to 10 requests per minute per IP.
Making authenticated requests
Include the token from the login response in theAuthorization header of every request that requires authentication:
401 Unauthorized.
Login response fields
Error codes
Member onboarding
When an admin adds a new member viaPOST /api/members, the member’s account is created with status: "pending" and a temporary password. The member must complete onboarding before they can log in normally.
1
Check phone number
The member’s app calls If the phone number is not found as pending in the specified group, the response returns
POST /api/auth/onboarding/check-phone to verify their phone number exists in the group as a pending account.success: false with a message asking the member to contact their admin.2
Set a password
The member calls After this step, the member can log in normally using
POST /api/auth/onboarding/set-password to choose their PIN. This activates the account (status changes from "pending" to "active") and returns a JWT token so the member is immediately logged in.POST /api/auth/login.The onboarding endpoints normalize Ugandan phone numbers automatically. A number entered as
0789876543 is treated the same as +256789876543.
