Every Save App API endpoint that reads or modifies group data requires authentication. You authenticate by exchanging credentials for a short-lived JWT token, then include that token in theDocumentation Index
Fetch the complete documentation index at: https://docs.digiflecttech.dev/llms.txt
Use this file to discover all available pages before exploring further.
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
| Field | Type | Description |
|---|---|---|
token | string | JWT bearer token. Include in Authorization: Bearer <token> on every request. |
name | string | Display name of the authenticated user. |
role | string | Either "admin" or "member". Determines which endpoints the user can access. |
is_creator | boolean | true if this admin was the first to register under their group name. Creators have additional privileges over group configuration. |
Error codes
| Code | Meaning |
|---|---|
401 Unauthorized | Missing or invalid token, wrong password, or account not found. |
403 Forbidden | Valid token but insufficient permissions — for example, a member attempting to access an admin-only endpoint, or a user logging in to the wrong group. |
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.
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.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.