SmsFlow 0.2.0

dotnet add package SmsFlow --version 0.2.0
                    
NuGet\Install-Package SmsFlow -Version 0.2.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SmsFlow" Version="0.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SmsFlow" Version="0.2.0" />
                    
Directory.Packages.props
<PackageReference Include="SmsFlow" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add SmsFlow --version 0.2.0
                    
#r "nuget: SmsFlow, 0.2.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package SmsFlow@0.2.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=SmsFlow&version=0.2.0
                    
Install as a Cake Addin
#tool nuget:?package=SmsFlow&version=0.2.0
                    
Install as a Cake Tool

SMSFlow .NET SDK

NuGet version CI License: MIT

The SMSFlow .NET SDK makes it easy to send SMS messages and check SMS credit balance from C#, ASP.NET Core, workers, scheduled jobs, CRM integrations, ERP integrations, and other backend .NET applications.

Documentation: https://docs.smsflow.co.za/

Install

dotnet add package SmsFlow

Configuration

Store credentials in environment variables, user secrets, Azure Key Vault, or another secret manager.

$env:SMSFLOW_CLIENT_ID = "YOUR_CLIENT_ID"
$env:SMSFLOW_CLIENT_SECRET = "YOUR_CLIENT_SECRET"

Do not put SMSFlow Client Secrets in source code, browser apps, mobile apps, logs, screenshots, or public issues.

Usage

using SmsFlow;

var client = new SmsFlowClient(new SmsFlowClientOptions
{
    ClientId = Environment.GetEnvironmentVariable("SMSFLOW_CLIENT_ID")!,
    ClientSecret = Environment.GetEnvironmentVariable("SMSFLOW_CLIENT_SECRET")!,
    Timeout = TimeSpan.FromSeconds(30)
});

var response = await client.SendSmsAsync(new SendSmsRequest
{
    CampaignName = "SDK example",
    Messages =
    [
        new SmsMessage
        {
            Destination = "27000000000",
            Content = "Your SMSFlow .NET test message was sent successfully."
        }
    ]
});

Console.WriteLine(response.SendResponse?.EventId);

Bulk send

await client.SendSmsAsync(new SendSmsRequest
{
    CampaignName = "Order dispatch alerts",
    Messages =
    [
        new SmsMessage { Destination = "27000000000", Content = "Order 1001 has shipped." },
        new SmsMessage { Destination = "27000000001", Content = "Order 1002 has shipped." }
    ]
});

Check balance

var balance = await client.GetBalanceAsync();
Console.WriteLine(balance.Balance);

Error handling

try
{
    await client.SendSmsAsync(new SendSmsRequest
    {
        CampaignName = "Transactional SMS",
        Messages = [new SmsMessage { Destination = "27000000000", Content = "Hello from SMSFlow." }]
    });
}
catch (SmsFlowAuthenticationException)
{
    Console.Error.WriteLine("Check your SMSFlow Client ID and Client Secret.");
    throw;
}
catch (SmsFlowValidationException ex)
{
    Console.Error.WriteLine($"Fix the request before retrying. {ex.ErrorCode}: {ex.ResponseBody}");
    throw;
}
catch (SmsFlowException ex)
{
    Console.Error.WriteLine($"{(int)ex.StatusCode}: {ex.ErrorCode}; retryable={ex.Retryable}; {ex.ResponseBody}");
    throw;
}

ASP.NET Core

Register the SDK through HttpClient so your application uses normal .NET connection management:

builder.Services.AddHttpClient<SmsFlowClient>(client =>
{
    client.BaseAddress = new Uri("https://portal.smsflow.co.za/");
    client.Timeout = TimeSpan.FromSeconds(30);
});

Timeouts and retries

var client = new SmsFlowClient(new SmsFlowClientOptions
{
    ClientId = Environment.GetEnvironmentVariable("SMSFLOW_CLIENT_ID")!,
    ClientSecret = Environment.GetEnvironmentVariable("SMSFLOW_CLIENT_SECRET")!,
    Timeout = TimeSpan.FromSeconds(30),
    RetryCount = 2,
    RetryBaseDelay = TimeSpan.FromMilliseconds(250),
    RetryMaxDelay = TimeSpan.FromSeconds(2)
});

var balance = await client.GetBalanceAsync(); // Safe to retry temporary failures.

await client.SendSmsAsync(new SendSmsRequest
{
    CampaignName = "Transactional SMS",
    RetryTemporaryFailures = true, // Use only with your own idempotency or duplicate-send guard.
    Messages = [new SmsMessage { Destination = "27000000000", Content = "Hello from SMSFlow." }]
});

Retry only temporary network failures, 408, 429, and 5xx responses. Do not retry validation errors, authentication failures, or insufficient-balance responses until the underlying issue has been fixed. Store the returned eventId against your own transaction or notification record.

Delivery status

The public HTTPS API currently exposes authentication, send, and balance endpoints. Delivery-status helper methods will be added when a public delivery-status endpoint is available.

Features

  • Get and cache SMSFlow login tokens.
  • Send one or more SMS messages.
  • Schedule SMS messages using UTC delivery time.
  • Respect opt-out checks by default.
  • Check account balance.
  • Raise typed structured exceptions when the API returns an error.
  • Configure timeouts and opt-in retries for temporary failures.

Local test send

This command sends a real SMS and may consume test credits:

$env:SMSFLOW_CLIENT_ID = "YOUR_CLIENT_ID"
$env:SMSFLOW_CLIENT_SECRET = "YOUR_CLIENT_SECRET"
$env:SMSFLOW_DESTINATION = "27000000000"
dotnet run --project samples/SendSmsExample

Security

Never commit real credentials. Use environment variables, user secrets, Azure Key Vault, or another secret manager.

License

MIT

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net8.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.2.0 189 6/18/2026
0.1.0 135 6/17/2026