Skip to content

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)
Terminal window
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:

  1. API key resolution — When a request includes an X-API-Key header, FWallet resolves the key to a tenant. All subsequent database queries in that request are automatically scoped to that tenant.
  2. 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.

Terminal window
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.

Terminal window
curl https://api.fwallet.co.ug/v1/system/stats \
-H "X-System-Key: $SYSTEM_KEY"

Tenant Isolation Guarantees

Each tenant gets its own:

ResourceIsolation
WalletsScoped by tenant_id. A tenant can only see and operate on its own wallets.
Ledger entriesJournal entries and lines are scoped by tenant_id. One tenant’s ledger is invisible to others.
Fee schedulesEach tenant defines its own fee rules (percentage, flat, min/max bounds, per-currency).
Approval policiesTenants configure their own approval thresholds and workflows.
System accountsEach tenant gets its own set of system accounts (momo-float, bank-float, suspense, revenue:fees).
API keysKeys 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.