Multi-Tenancy
FWallet is multi-tenant by design. Every piece of data — wallets, ledger entries, fee schedules, approval policies — belongs to exactly one tenant (organization). Tenants are fully isolated from each other.
What is a Tenant?
A tenant represents a business or organization using FWallet. When you create a tenant via POST /v1/tenants, you define:
- Name and slug — human-readable identifier for the organization
- Default currency — the currency used when none is specified (e.g.,
UGX) - Allowed currencies — which currencies this tenant can operate in (e.g.,
["UGX", "USD"]) - Max transaction amount — upper bound on a single transaction (in the smallest currency unit)
curl -X POST https://api.fwallet.co.ug/v1/tenants \ -H "Content-Type: application/json" \ -H "X-System-Key: $SYSTEM_KEY" \ -d '{ "name": "Kampala Remittances Ltd", "slug": "kampala-remit", "config": { "defaultCurrency": "UGX", "allowedCurrencies": ["UGX", "KES", "USD"], "maxTransactionAmount": 100000000 } }'Response:
{ "id": "tn_01JQHXYZ...", "name": "Kampala Remittances Ltd", "slug": "kampala-remit", "config": { "defaultCurrency": "UGX", "allowedCurrencies": ["UGX", "KES", "USD"], "maxTransactionAmount": 100000000 }, "createdAt": "2026-03-18T10:00:00.000Z"}How Scoping Works
Every database table in FWallet has a tenant_id column. Every query is scoped by tenant. There is no way for a tenant’s API key to access another tenant’s data.
The scoping happens at two levels:
- API key resolution — When a request includes an
X-API-Keyheader, FWallet resolves the key to a tenant. All subsequent database queries in that request are automatically scoped to that tenant. - Database constraints — Foreign keys and unique constraints include
tenant_id, so even at the database level, data cannot leak across tenants.
Two Authentication Modes
FWallet has two header-based authentication modes:
X-API-Key — Tenant-Scoped
Required for all tenant-scoped endpoints: wallets, transfers, deposits, payouts, journal entries, tenant admin.
curl https://api.fwallet.co.ug/v1/wallets \ -H "X-API-Key: fwk_test_a1b2c3d4e5f6..."The API key determines which tenant the request operates on. You never pass a tenant_id explicitly — it is derived from the key.
X-System-Key — Platform-Level
Required for /v1/system/* endpoints and tenant provisioning (POST /v1/tenants, POST /v1/tenants/{id}/api-keys). This is the platform operator’s key.
curl https://api.fwallet.co.ug/v1/system/stats \ -H "X-System-Key: $SYSTEM_KEY"Tenant Isolation Guarantees
Each tenant gets its own:
| Resource | Isolation |
|---|---|
| Wallets | Scoped by tenant_id. A tenant can only see and operate on its own wallets. |
| Ledger entries | Journal entries and lines are scoped by tenant_id. One tenant’s ledger is invisible to others. |
| Fee schedules | Each tenant defines its own fee rules (percentage, flat, min/max bounds, per-currency). |
| Approval policies | Tenants configure their own approval thresholds and workflows. |
| System accounts | Each tenant gets its own set of system accounts (momo-float, bank-float, suspense, revenue:fees). |
| API keys | Keys belong to a single tenant and cannot be used to access other tenants. |
Configurable Per Tenant
Beyond the initial configuration, each tenant can customize:
- Fee schedules — Percentage + flat fee, min/max bounds, per-currency overrides
- Approval thresholds — Transactions above a certain amount require manual approval
- Transaction limits — Max amount per transaction, daily limits
- Allowed currencies — Which currencies the tenant can operate in
This makes FWallet suitable for a white-label / resale model where a platform operator onboards multiple businesses, each with their own rules.