.NET SDK
The official C# / .NET SDK for Sendexa. One package, one client, every API — SMS, OTP, WhatsApp, Email, Voice, and Webhook verification.
Zero Dependencies
Uses only System.Net.Http and System.Text.Json — both built into .NET 6+.
DI-Friendly
Accepts an optional HttpClient for IHttpClientFactory integration in ASP.NET Core.
Fully Async
Every API method is async with CancellationToken support throughout.
Immutable Records
Request and response types use C# records with init-only properties and nullable annotations.
dotnet add package Sendexa.SDK
Requirements
System.Net.Http.HttpClient and System.Text.Json, both built into the .NET runtime.Register as a singleton in your DI container and inject it where needed — the client is thread-safe and manages its own connection pool.
// Program.csbuilder.Services.AddSingleton(new SendexaClient(new SendexaConfig{ApiKey = builder.Configuration["Sendexa:ApiKey"],ApiSecret = builder.Configuration["Sendexa:ApiSecret"],}));// Or with IHttpClientFactorybuilder.Services.AddHttpClient();builder.Services.AddSingleton<SendexaClient>(sp =>{var http = sp.GetRequiredService<IHttpClientFactory>().CreateClient("sendexa");return new SendexaClient(new SendexaConfig{ApiKey = builder.Configuration["Sendexa:ApiKey"],ApiSecret = builder.Configuration["Sendexa:ApiSecret"],}, http);});
Send single and bulk SMS messages with delivery tracking.
using Sendexa.Resources;// Send a single SMSvar resp = await client.Sms.SendAsync(new SendSmsRequest{To = "0244123456",From = "MyBrand",Message = "Your order #1234 has been confirmed!",});Console.WriteLine($"{resp.Data?.MessageId} {resp.Data?.Status}");// Send bulk SMSawait client.Sms.SendBulkAsync(new SendBulkSmsRequest{From = "MyBrand",Message = "Hello from MyBrand!", // shared fallbackMessages =[new BulkSmsMessage { To = "0244123456", Message = "Hi Alice!" },new BulkSmsMessage { To = "0555987654" }, // uses shared message],});// Check delivery statusvar status = await client.Sms.GetStatusAsync(resp.Data!.MessageId!);Console.WriteLine(status.Data?.Status); // "delivered"// Resend a failed messageawait client.Sms.ResendAsync(resp.Data.MessageId!);
All API errors throw a SendexaException with structured properties for easy branching.
using Sendexa;using Sendexa.Resources;try{await client.Sms.SendAsync(new SendSmsRequest{To = "0244123456", From = "MyBrand", Message = "Hi!",});}catch (SendexaException ex){Console.WriteLine(ex.Status); // HTTP status e.g. 403Console.WriteLine(ex.Code); // API code e.g. "SENDER_ID_NOT_APPROVED"Console.WriteLine(ex.Message); // Human text e.g. "Sender ID not approved"Console.WriteLine(ex.RequestId); // Trace ID for Sendexa support}
| Property | Type | Description |
|---|---|---|
| Status | int | HTTP status code (400, 401, 403, 429…) |
| Code | string | Machine-readable error code from the API |
| Message | string | Human-readable description of the error |
| RequestId | string? | Sendexa trace ID — include when contacting support |
| Raw | object? | Full raw error payload from the API |
Best Practices
- Register
SendexaClientas a singleton in your DI container — do not instantiate per request - Pass an
HttpClientfromIHttpClientFactoryto benefit from connection pooling and resiliency policies - Store credentials in environment variables or
appsettings.json/ Azure Key Vault, never in source code - Always
await client.Webhooks.Verify()before processing any webhook event - Pass
CancellationTokenfrom your controller/handler to every async call for graceful cancellation