Skip to main content

Overview

The Bila C# SDK provides convenient access to the Bila REST API from applications written in C#. It is generated with Stainless.

Strongly Typed

Typed request and response models for every endpoint.

Async Methods

Every method returns a Task, following standard .NET async conventions.

Comprehensive

Access to all Bila API features: Accounts, Transfers, Collections, and more.

Stainless Generated

Consistently structured and always up-to-date with the latest API changes.

Installation

Install the package from NuGet:
dotnet add package Usebila
This library requires .NET Standard 2.0 or later.

Quick Start

using System;
using Usebila;
using Usebila.Models.Accounts;
 
BilaClient client = new()
{
    ApiKey = "Your API key",
    BaseUrl = EnvironmentUrl.Sandbox, // either EnvironmentUrl.Production or EnvironmentUrl.Sandbox
};
 
AccountListParams parameters = new();
 
AccountListResponse accounts = await client.Accounts.List(parameters);
 
Console.WriteLine(accounts);
Configure the client using environment variables, so you don’t need to pass ApiKey explicitly:
using Usebila;
 
// Configured using the BILA_API_KEY and BILA_BASE_URL environment variables
BilaClient client = new();
PropertyEnvironment variableRequiredDefault value
ApiKeyBILA_API_KEYtrue-
BaseUrlBILA_BASE_URLtrue"https://api.usebila.com"

API Classes

The SDK is organized into resources, each handling a specific domain:
ResourceDescription
AccountsRetrieve accounts, list accounts, and check balances
TransferRecipientsManage payout recipients for bank and mobile money transfers
TransfersSend payouts via bank transfer and mobile money
CollectionsCollect payments via mobile money
TransactionsRetrieve and list transaction history
WebhooksConfigure webhooks and manage delivery history
BanksList supported banks and financial institutions
ResolveVerify bank account and mobile money details

Accounts

Manage your Bila wallets and check balances.

Methods

client.Accounts.Retrieve(id) Retrieve details for a specific account.
const string accountId = "68f11209-451f-4a15-bfcd-d916eb8b09f4";
 
AccountRetrieveResponse account = await client.Accounts.Retrieve(accountId);
Console.WriteLine("retrieve: {0}", account);
Returns: Task<AccountRetrieveResponse> client.Accounts.List(params) List all accounts associated with your profile.
AccountListParams listParams = new() { Page = 1, PerPage = 50 };
 
AccountListResponse accounts = await client.Accounts.List(listParams);
Console.WriteLine("list: {0}", accounts);
Returns: Task<AccountListResponse> client.Accounts.GetBalance(id) Check the real-time balance of an account.
AccountGetBalanceResponse balance = await client.Accounts.GetBalance(accountId);
Console.WriteLine("getBalance: {0}", balance);
Returns: Task<AccountGetBalanceResponse>

TransferRecipients

Manage payout recipients for bank and mobile money transfers.

Methods

client.TransferRecipients.Retrieve(id) Retrieve details for a specific transfer recipient.
const string transferRecipientId = "68f11209-451f-4a15-bfcd-d916eb8b09f4";
 
TransferRecipientRetrieveResponse recipient = await client.TransferRecipients.Retrieve(
    transferRecipientId
);
Console.WriteLine("retrieve: {0}", recipient);
Returns: Task<TransferRecipientRetrieveResponse> client.TransferRecipients.List(params) List all transfer recipients.
TransferRecipientListParams listParams = new()
{
    Page = 1,
    PerPage = 50,
    Type = Usebila.Models.TransferRecipients.Type.BankAccount,
};
 
TransferRecipientListResponse recipients = await client.TransferRecipients.List(listParams);
Console.WriteLine("list: {0}", recipients);
Returns: Task<TransferRecipientListResponse> client.TransferRecipients.CreateBankAccount(params) Create a new bank account transfer recipient.
TransferRecipientCreateBankAccountParams bankParams = new()
{
    AccountNumber = "1234567890",
    BankID = "bank-001",
    AccountName = "John Doe",
    Country = Country.Zm,
};
 
TransferRecipientCreateBankAccountResponse bankRecipient =
    await client.TransferRecipients.CreateBankAccount(bankParams);
Console.WriteLine("createBankAccount: {0}", bankRecipient);
Returns: Task<TransferRecipientCreateBankAccountResponse> client.TransferRecipients.CreateMobileMoney(params) Create a new mobile money transfer recipient. This uses the resource-specific TransferRecipientCreateMobileMoneyParamsCountry enum rather than the shared Country enum.
TransferRecipientCreateMobileMoneyParams mobileParams = new()
{
    Country = TransferRecipientCreateMobileMoneyParamsCountry.Zm,
    Operator = Operator.Airtel,
    Phone = "0977433571",
    AccountName = "Jane Doe",
};
 
TransferRecipientCreateMobileMoneyResponse mobileRecipient =
    await client.TransferRecipients.CreateMobileMoney(mobileParams);
Console.WriteLine("createMobileMoney: {0}", mobileRecipient);
Returns: Task<TransferRecipientCreateMobileMoneyResponse>

Transfers

Send funds to bank accounts or mobile money wallets.

Methods

client.Transfers.Retrieve(id) Retrieve details for a specific transfer.
const string transferId = "68f11209-451f-4a15-bfcd-d916eb8b09f4";
 
TransferRetrieveResponse transfer = await client.Transfers.Retrieve(transferId);
Console.WriteLine("retrieve: {0}", transfer);
Returns: Task<TransferRetrieveResponse> client.Transfers.List(params) List all transfers.
TransferListParams listParams = new()
{
    AccountID = "68f11209-451f-4a15-bfcd-d916eb8b09f4",
    StartDate = "2024-01-01T00:00:00Z",
    EndDate = "2024-12-31T23:59:59Z",
    Page = 1,
    PerPage = 50,
    Status = Status.Pending,
    Type = Usebila.Models.Transfers.Type.BankAccount,
};
 
TransferListResponse transfers = await client.Transfers.List(listParams);
Console.WriteLine("list: {0}", transfers);
Returns: Task<TransferListResponse> client.Transfers.GetStatusByReference(reference) Get the status of a transfer by its reference.
const string bankReference = "transfer-001";
 
TransferGetStatusByReferenceResponse status = await client.Transfers.GetStatusByReference(
    bankReference
);
Console.WriteLine("getStatusByReference: {0}", status);
Returns: Task<TransferGetStatusByReferenceResponse> client.Transfers.InitiateBankTransfer(params) Initiate a bank transfer.
TransferInitiateBankTransferParams bankParams = new()
{
    AccountID = "68f11209-451f-4a15-bfcd-d916eb8b09f4",
    Amount = 1000,
    Reference = "transfer-001",
    AccountNumber = "1234567890",
    BankID = "bank-001",
    Country = Country.Zm,
    Narration = "Payment for services",
    RecipientName = "Jane Doe",
    TransferRecipientID = "68f11209-451f-4a15-bfcd-d916eb8b09f4",
    WalletID = "68f11209-451f-4a15-bfcd-d916eb8b09f4",
};
 
TransferInitiateBankTransferResponse bankTransfer = await client.Transfers.InitiateBankTransfer(
    bankParams
);
Console.WriteLine("initiateBankTransfer: {0}", bankTransfer);
Returns: Task<TransferInitiateBankTransferResponse> client.Transfers.InitiateMobileMoneyTransfer(params) Initiate a mobile money transfer.
TransferInitiateMobileMoneyTransferParams mobileParams = new()
{
    Amount = 250,
    Country = TransferInitiateMobileMoneyTransferParamsCountry.Zm,
    Operator = Operator.Airtel,
    Phone = "0977433571",
    Reference = "mobile-transfer-001",
    Narration = "Mobile money payout",
    RecipientName = "Jane Doe",
    WalletID = "68f11209-451f-4a15-bfcd-d916eb8b09f4",
};
 
TransferInitiateMobileMoneyTransferResponse mobileTransfer =
    await client.Transfers.InitiateMobileMoneyTransfer(mobileParams);
Console.WriteLine("initiateMobileMoneyTransfer: {0}", mobileTransfer);
Returns: Task<TransferInitiateMobileMoneyTransferResponse>

Collections

Accept mobile money payments from customers.

Methods

client.Collections.Retrieve(id) Retrieve details for a specific collection.
const string collectionId = "68f11209-451f-4a15-bfcd-d916eb8b09f4";
 
CollectionRetrieveResponse collection = await client.Collections.Retrieve(collectionId);
Console.WriteLine("retrieve: {0}", collection);
Returns: Task<CollectionRetrieveResponse> client.Collections.List(params) List all collections.
CollectionListParams listParams = new()
{
    AccountID = "68f11209-451f-4a15-bfcd-d916eb8b09f4",
    StartDate = "2024-01-01T00:00:00Z",
    EndDate = "2024-12-31T23:59:59Z",
    Page = 1,
    PerPage = 50,
    Status = Status.Pending,
};
 
CollectionListResponse collections = await client.Collections.List(listParams);
Console.WriteLine("list: {0}", collections);
Returns: Task<CollectionListResponse> client.Collections.GetStatusByReference(reference) Get the status of a collection by its reference.
const string reference = "collection-001";
 
CollectionGetStatusByReferenceResponse status = await client.Collections.GetStatusByReference(
    reference
);
Console.WriteLine("getStatusByReference: {0}", status);
Returns: Task<CollectionGetStatusByReferenceResponse> client.Collections.InitiateMobileMoneyCollection(params) Initiate a mobile money collection. Use the Country, Operator, and Bearer constants rather than raw strings.
CollectionInitiateMobileMoneyCollectionParams initiateParams = new()
{
    Amount = 100.5,
    Country = Country.Zm,
    Operator = Operator.Airtel,
    Phone = "0977433571",
    Reference = "collection-001",
    WalletID = "68f11209-451f-4a15-bfcd-d916eb8b09f4",
    Bearer = Bearer.Customer,
    CustomerName = "John Doe",
    Narration = "Payment for subscription",
};
 
CollectionInitiateMobileMoneyCollectionResponse initiated =
    await client.Collections.InitiateMobileMoneyCollection(initiateParams);
Console.WriteLine("initiateMobileMoneyCollection: {0}", initiated);
Returns: Task<CollectionInitiateMobileMoneyCollectionResponse>

Transactions

View and manage transaction history.

Methods

client.Transactions.Retrieve(id) Retrieve details for a specific transaction.
const string transactionId = "68f11209-451f-4a15-bfcd-d916eb8b09f4";
 
TransactionRetrieveResponse transaction = await client.Transactions.Retrieve(transactionId);
Console.WriteLine("retrieve: {0}", transaction);
Returns: Task<TransactionRetrieveResponse> client.Transactions.List(params) List all transactions.
TransactionListParams listParams = new() { Page = 1, PerPage = 50 };
 
TransactionListResponse transactions = await client.Transactions.List(listParams);
Console.WriteLine("list: {0}", transactions);
Returns: Task<TransactionListResponse>

Webhooks

Configure endpoints to receive real-time event notifications.

Methods

client.Webhooks.Create(params) Register a new webhook endpoint. Note the field is UrlValue, and events use the Event enum.
WebhookCreateParams createParams = new()
{
    Events = [Event.PaymentCompleted, Event.WithdrawalCompleted, Event.TransferCompleted],
    UrlValue = "https://example.com/webhooks",
};
 
WebhookCreateResponse created = await client.Webhooks.Create(createParams);
Console.WriteLine("create: {0}", created);
Returns: Task<WebhookCreateResponse> client.Webhooks.Update(id, params) Update an existing webhook.
const string webhookId = "68f11209-451f-4a15-bfcd-d916eb8b09f4";
 
WebhookUpdateParams updateParams = new()
{
    Events =
    [
        WebhookUpdateParamsEvent.PaymentCompleted,
        WebhookUpdateParamsEvent.CollectionCompleted,
        WebhookUpdateParamsEvent.TransferFailed,
    ],
    UrlValue = "https://example.com/webhooks/v2",
    IsActive = true,
};
 
WebhookUpdateResponse updated = await client.Webhooks.Update(webhookId, updateParams);
Console.WriteLine("update: {0}", updated);
Returns: Task<WebhookUpdateResponse> client.Webhooks.List() List all registered webhooks.
WebhookListResponse webhooks = await client.Webhooks.List();
Console.WriteLine("list: {0}", webhooks);
Returns: Task<WebhookListResponse> client.Webhooks.Deactivate(id) Deactivate a webhook.
WebhookDeactivateResponse deactivated = await client.Webhooks.Deactivate(webhookId);
Console.WriteLine("deactivate: {0}", deactivated);
Returns: Task<WebhookDeactivateResponse> client.Webhooks.GetDeliveries(id, params) Get delivery history for a specific webhook.
WebhookGetDeliveriesParams deliveriesParams = new()
{
    StartDate = "2026-04-01T00:00:00.000Z",
    EndDate = "2026-04-30T23:59:59.999Z",
    EventType = "payment.completed",
    Page = 1,
    PerPage = 20,
    Status = "DELIVERED",
};
 
WebhookGetDeliveriesResponse deliveries = await client.Webhooks.GetDeliveries(
    webhookId,
    deliveriesParams
);
Console.WriteLine("getDeliveries: {0}", deliveries);
Returns: Task<WebhookGetDeliveriesResponse> client.Webhooks.ListEvents() List all supported webhook events.
WebhookListEventsResponse events = await client.Webhooks.ListEvents();
Console.WriteLine("listEvents: {0}", events);
Returns: Task<WebhookListEventsResponse> client.Webhooks.RotateSecret(id) Rotate the signing secret for a webhook.
WebhookRotateSecretResponse rotated = await client.Webhooks.RotateSecret(webhookId);
Console.WriteLine("rotateSecret: {0}", rotated);
Returns: Task<WebhookRotateSecretResponse>

Banks

Utilities for listing supported financial institutions.

Methods

client.Banks.List(params) List supported banks for a specific country. Note this resource takes a plain string for Country, unlike Transfers, Collections, and Resolve.
BankListParams listParams = new() { Country = "zm" };
 
BankListResponse banks = await client.Banks.List(listParams);
Console.WriteLine("list: {0}", banks);
Returns: Task<BankListResponse>

Resolve

Utilities for verifying account details.

Methods

client.Resolve.BankAccount(params) Verify the owner of a bank account.
ResolveBankAccountParams bankParams = new()
{
    AccountNumber = "1234567890",
    BankID = "bank-001",
    Country = Country.Zm,
};
 
ResolveBankAccountResponse resolution = await client.Resolve.BankAccount(bankParams);
Console.WriteLine("bankAccount: {0}", resolution);
Returns: Task<ResolveBankAccountResponse> client.Resolve.MobileMoney(params) Verify mobile money details. This uses the resource-specific ResolveMobileMoneyParamsCountry enum rather than the shared Country enum.
ResolveMobileMoneyParams mobileParams = new()
{
    Country = ResolveMobileMoneyParamsCountry.Zm,
    Operator = Operator.Airtel,
    Phone = "0977433571",
};
 
ResolveMobileMoneyResponse resolution = await client.Resolve.MobileMoney(mobileParams);
Console.WriteLine("mobileMoney: {0}", resolution);
Returns: Task<ResolveMobileMoneyResponse>

Raw Responses

The SDK defines methods that deserialize responses into instances of C# classes. To access response headers, status code, or the raw body, prefix any call with WithRawResponse:
var response = await client.WithRawResponse.Accounts.List();
var statusCode = response.StatusCode;
var headers = response.Headers;

Error Handling

The SDK throws custom unchecked exception types. BilaApiException is the base class for API errors:
using Usebila.Exceptions;
 
try
{
    await client.Accounts.Retrieve("invalid-id");
}
catch (BilaApiException ex)
{
    Console.Error.WriteLine($"Status: {ex.StatusCode}");
    Console.Error.WriteLine($"Message: {ex.Message}");
}
catch (Exception ex)
{
    Console.Error.WriteLine($"Unexpected error: {ex.Message}");
}
StatusException
400BilaBadRequestException
401BilaUnauthorizedException
403BilaForbiddenException
404BilaNotFoundException
422BilaUnprocessableEntityException
429BilaRateLimitException
5xxBila5xxException
othersBilaUnexpectedStatusCodeException
All 4xx errors inherit from Bila4xxException. BilaIOException is thrown for I/O networking errors, and BilaInvalidDataException for failures interpreting parsed data.

Best Practices

1

Use Environment Variables

Configure the client with no arguments to use BILA_API_KEY and BILA_BASE_URL automatically, rather than hardcoding credentials.
2

Check Which Resources Use Constants

Country, Operator, Bearer, Status, and Event constants are used for Transfers, Collections, TransferRecipients, Resolve, and Webhooks. Banks is the exception — its Country field takes a plain string. Some resources also define their own scoped country enum (e.g. ResolveMobileMoneyParamsCountry, TransferRecipientCreateMobileMoneyParamsCountry) rather than reusing the shared Country enum, so check the specific params class.
3

Reuse the Client

Create a single BilaClient instance and reuse it across requests, or use WithOptions to temporarily override settings without creating a new client.
4

Handle Errors Gracefully

Catch BilaApiException separately from generic exceptions to distinguish API-level errors from network failures.

Next Steps

SDK Quickstart

Complete integration guide with examples

Transfers

Learn about initiating transfers

Webhooks

Set up webhook notifications

API Reference

Complete REST API documentation