C# / .NET SDK
The official .NET SDK for Sent provides first-class C# support with native async/await, dependency injection integration, and full compatibility with .NET Standard 2.0+.
Requirements
This library requires .NET Standard 2.0 or later.
Installation
dotnet add package SentdmInstall-Package Sentdm<PackageReference Include="Sentdm" Version="0.7.0" />Quick Start
Initialize the client
using Sentdm;
// Configured using the SENT_DM_API_KEY environment variable
SentDmClient client = new();Send your first message
using Sentdm;
using Sentdm.Models.Messages;
using System.Collections.Generic;
SentDmClient client = new();
MessageSendParams parameters = new()
{
To = new List<string> { "+1234567890" },
Channels = new List<string> { "sms", "whatsapp" },
Template = new MessageSendParamsTemplate
{
Id = "7ba7b820-9dad-11d1-80b4-00c04fd430c8",
Name = "welcome",
Parameters = new Dictionary<string, string>()
{
{ "name", "John Doe" },
{ "order_id", "12345" }
}
}
};
var response = await client.Messages.SendAsync(parameters);
Console.WriteLine($"Sent: {response.Data.Messages[0].Id}");
Console.WriteLine($"Status: {response.Data.Messages[0].Status}");Client configuration
Configure the client using environment variables or explicitly:
| Property | Environment variable | Required | Default value |
|---|---|---|---|
ApiKey | SENT_DM_API_KEY | true | - |
BaseUrl | SENT_DM_BASE_URL | true | "https://api.sent.dm" |
using Sentdm;
// Using environment variables
SentDmClient client = new();
// Or explicit configuration
SentDmClient client = new()
{
ApiKey = "your_api_key",
};
// Or a combination
SentDmClient client = new()
{
ApiKey = "your_api_key", // Explicit
// Other settings from environment
};Modifying configuration
To temporarily use a modified client configuration, while reusing the same connection and thread pools, call WithOptions:
var clientWithOptions = client.WithOptions(options =>
options with
{
BaseUrl = "https://example.com",
MaxRetries = 5,
}
);Using a with expression makes it easy to construct the modified options.
Send Messages
Send a message
using Sentdm.Models.Messages;
MessageSendParams parameters = new()
{
To = new List<string> { "+1234567890" },
Channels = new List<string> { "sms", "whatsapp" },
Template = new MessageSendParamsTemplate
{
Id = "7ba7b820-9dad-11d1-80b4-00c04fd430c8",
Name = "welcome",
Parameters = new Dictionary<string, string>()
{
{ "name", "John Doe" },
{ "order_id", "12345" }
}
}
};
var response = await client.Messages.SendAsync(parameters);
Console.WriteLine($"Message ID: {response.Data.Messages[0].Id}");
Console.WriteLine($"Status: {response.Data.Messages[0].Status}");Test mode
Use TestMode = true to validate requests without sending real messages:
MessageSendParams parameters = new()
{
To = new List<string> { "+1234567890" },
Template = new MessageSendParamsTemplate
{
Id = "7ba7b820-9dad-11d1-80b4-00c04fd430c8",
Name = "welcome"
},
TestMode = true // Validates but doesn't send
};
var response = await client.Messages.SendAsync(parameters);
// Response will have test data
Console.WriteLine($"Validation passed: {response.Data.Messages[0].Id}");Error handling
The SDK throws custom unchecked exception types:
| Status | Exception |
|---|---|
| 400 | SentDmBadRequestException |
| 401 | SentDmUnauthorizedException |
| 403 | SentDmForbiddenException |
| 404 | SentDmNotFoundException |
| 422 | SentDmUnprocessableEntityException |
| 429 | SentDmRateLimitException |
| 5xx | SentDm5xxException |
try
{
var response = await client.Messages.SendAsync(parameters);
Console.WriteLine($"Sent: {response.Data.Messages[0].Id}");
}
catch (SentDmNotFoundException e)
{
Console.WriteLine($"Not found: {e.Message}");
}
catch (SentDmRateLimitException e)
{
Console.WriteLine($"Rate limited. Retry after delay");
}
catch (SentDmApiException e)
{
Console.WriteLine($"API Error: {e.Message}");
}Raw responses
To access response headers, status code, or raw body, prefix any HTTP method call with WithRawResponse:
var response = await client.WithRawResponse.Messages.SendAsync(parameters);
var statusCode = response.StatusCode;
var headers = response.Headers;
// Deserialize if needed
var deserialized = await response.Deserialize();Retries
The SDK automatically retries 2 times by default, with a short exponential backoff between requests.
Only the following error types are retried:
- Connection errors
- 408 Request Timeout
- 409 Conflict
- 429 Rate Limit
- 5xx Internal
using Sentdm;
// Configure for all requests
SentDmClient client = new() { MaxRetries = 3 };
// Or per-request
await client
.WithOptions(options => options with { MaxRetries = 3 })
.Messages.SendAsync(parameters);Timeouts
Requests time out after 1 minute by default.
using System;
using Sentdm;
// Configure for all requests
SentDmClient client = new() { Timeout = TimeSpan.FromSeconds(30) };
// Or per-request
await client
.WithOptions(options => options with { Timeout = TimeSpan.FromSeconds(30) })
.Messages.SendAsync(parameters);Contacts
Create and manage contacts:
using Sentdm.Models.Contacts;
// Create a contact
ContactCreateParams createParams = new()
{
PhoneNumber = "+1234567890"
};
var contact = await client.Contacts.CreateAsync(createParams);
Console.WriteLine($"Contact ID: {contact.Data.Id}");
// List contacts
ContactListParams listParams = new()
{
Limit = 100
};
var contacts = await client.Contacts.ListAsync(listParams);
foreach (var c in contacts.Data.Data)
{
Console.WriteLine($"{c.PhoneNumber} - {c.AvailableChannels}");
}
// Get a contact
var contact = await client.Contacts.GetAsync("contact-uuid");
// Update a contact
ContactUpdateParams updateParams = new()
{
PhoneNumber = "+1987654321"
};
var updated = await client.Contacts.UpdateAsync("contact-uuid", updateParams);
// Delete a contact
await client.Contacts.DeleteAsync("contact-uuid");Templates
List and retrieve templates:
using Sentdm.Models.Templates;
// List templates
var templates = await client.Templates.ListAsync();
foreach (var template in templates.Data.Data)
{
Console.WriteLine($"{template.Name} ({template.Status}): {template.Id}");
}
// Get a specific template
var template = await client.Templates.GetAsync("template-uuid");
Console.WriteLine($"Name: {template.Data.Name}");
Console.WriteLine($"Status: {template.Data.Status}");ASP.NET Core Integration
Dependency Injection Setup
// Program.cs
using Sentdm;
var builder = WebApplication.CreateBuilder(args);
// Add Sent client
builder.Services.AddSentDm(options =>
{
options.ApiKey = builder.Configuration["Sent:ApiKey"]!;
});
var app = builder.Build();Minimal API Example
// Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSentDm(options =>
{
options.ApiKey = builder.Configuration["Sent:ApiKey"]!;
});
var app = builder.Build();
// Send message endpoint
app.MapPost("/api/send-message", async (
MessageSendParams req,
SentDmClient client,
CancellationToken ct) =>
{
try
{
var result = await client.Messages.SendAsync(req, ct);
return Results.Ok(new
{
MessageId = result.Data.Messages[0].Id,
Status = result.Data.Messages[0].Status,
});
}
catch (SentDmApiException ex)
{
return Results.BadRequest(new { Error = ex.Message });
}
});
app.Run();MVC Controller
// Controllers/MessagesController.cs
using Microsoft.AspNetCore.Mvc;
using Sentdm;
using Sentdm.Models.Messages;
namespace MyApp.Controllers;
[ApiController]
[Route("api/[controller]")]
public class MessagesController : ControllerBase
{
private readonly SentDmClient _client;
private readonly ILogger<MessagesController> _logger;
public MessagesController(SentDmClient client, ILogger<MessagesController> logger)
{
_client = client;
_logger = logger;
}
[HttpPost("send")]
public async Task<IActionResult> SendMessage([FromBody] MessageSendParams request)
{
try
{
var result = await _client.Messages.SendAsync(request);
return Ok(new
{
MessageId = result.Data.Messages[0].Id,
Status = result.Data.Messages[0].Status
});
}
catch (SentDmApiException ex)
{
_logger.LogError(ex, "Failed to send message");
return BadRequest(new { Error = ex.Message });
}
}
}Client configuration from appsettings.json
{
"Sent": {
"ApiKey": "your_api_key_here",
"BaseUrl": "https://api.sent.dm",
"Timeout": 30,
"MaxRetries": 3
}
}// Program.cs
builder.Services.AddSentDm(options =>
{
var config = builder.Configuration.GetSection("Sent");
options.ApiKey = config["ApiKey"]!;
options.BaseUrl = config["BaseUrl"];
options.Timeout = TimeSpan.FromSeconds(config.GetValue<int>("Timeout"));
options.MaxRetries = config.GetValue<int>("MaxRetries");
});Source & Issues
- Version: 0.7.0
- GitHub: sentdm/sent-dm-csharp
- NuGet: Sentdm
- Issues: Report a bug
Getting Help
- Documentation: API Reference
- Troubleshooting: Common Issues
- Support: Email support@sent.dm with your request ID