Install, authenticate, request.
Three things you need from your Nomba dashboard: a client_id, a client_secret, and an account_id. The SDK handles the OAuth2 token exchange for you from there.
Install
uv add nomba-python
# or
pip install nomba-python
Sync client
Use Nomba for scripts, CLIs, or synchronous codebases. It opens one HTTP connection pool per instance — create one and reuse it, don't construct a new Nomba() per request.
from nomba import Nomba
nomba = Nomba(
client_id="...",
client_secret="...",
account_id="...",
sandbox=True, # set False for live
)
account = nomba.virtual_accounts.create_virtual_account(
account_ref="ref-123",
account_name="Jane Doe",
)
nomba.close()
Or as a context manager, which closes the connection pool automatically:
with Nomba(client_id=..., client_secret=..., account_id=...) as nomba:
nomba.virtual_accounts.fetch_a_virtual_account("ref-123")
Async client
Every resource is mirrored on AsyncNomba, built on httpx.AsyncClient. Same method names, same field names — just awaited.
import asyncio
from nomba import AsyncNomba
async def main():
async with AsyncNomba(
client_id="...",
client_secret="...",
account_id="...",
sandbox=True,
) as nomba:
transfer = await nomba.transfers.perform_bank_account_transfer_the_parent_account(
amount="5000.00",
account_number="0123456789",
account_name="John Doe",
bank_code="058",
merchant_tx_ref="txn-001",
sender_name="Jane Sender",
)
asyncio.run(main())
Error handling
All exceptions inherit from NombaError. The two you'll see most:
from nomba import NombaAPIError, NombaAuthError, NombaValidationError
try:
nomba.virtual_accounts.fetch_a_virtual_account("missing-ref")
except NombaAuthError as e:
print("auth failed:", e)
except NombaAPIError as e:
print("api error:", e.status_code, e.code, e.response_body)
except NombaValidationError as e:
print("bad request, caught locally before any network call:", e)
NombaValidationError is raised before any request goes out — it checks nested required fields (like everything inside an order={...} dict) against Nomba's own spec. See request validation.
Response shape
Every method returns a plain dict typed as a generated TypedDict, mirroring Nomba's actual JSON keys (camelCase, not snake_case):
account = nomba.virtual_accounts.create_virtual_account(
account_ref="ref-123",
account_name="Jane Doe",
)
print(account["data"]["accountNumber"])
print(account["code"], account["description"])