Here you'll find documentation related to the Sinch .NET SDK, including how to install it, initialize it, and start developing .NET code using Sinch services.
To use Sinch services, you'll need a Sinch account and access keys. You can sign up for an account and create access keys at dashboard.sinch.com.
- Prerequisites
- Documentation
- Installation
- Supported APIs
- Getting started
- Logging
- Handling exceptions
- Custom HTTP client implementation
- Third-party dependencies
- Examples
- Changelog & Migration
- License
- Contact
- .NET 6.0, .NET 7.0, or .NET 8.0
- NuGet or the
dotnetCLI - Sinch account
Warning: This SDK is intended for server-side (backend) use only. Do not use it in front-end or client-side applications (web, mobile, or desktop), regardless of language or framework. Doing so can expose your Sinch credentials to end-users.
For more information on the SDK, refer to the dedicated .NET SDK documentation.
For the SDK's programmatic API surface, see the online SDK reference.
For broader Sinch product documentation, including the underlying REST APIs, visit the official Sinch developer portal.
Run the following command to install the SDK:
dotnet add package Sinch| API Category | API Name |
|---|---|
| Messaging | Conversation API |
| SMS API | |
| Voice and Video | Voice API |
| Numbers | Numbers API |
| Verification | Verification API |
| Fax | Fax API |
Note: The SMS API is end-of-sale. New integrations should use the Conversation API instead, which supports SMS and many other channels.
To start using the SDK, initialize the main client class. This client gives you access to all the SDK services:
using Sinch;
// Warning: not all APIs support project authentication. Check the section for each API before using this snippet.
var sinch = new SinchClient(
"SINCH_PROJECT_ID",
"SINCH_KEY_ID",
"SINCH_KEY_SECRET");Get SINCH_PROJECT_ID, SINCH_KEY_ID and SINCH_KEY_SECRET from the Access keys page in your Sinch dashboard (SINCH_KEY_SECRET is shown only once, at creation time). It's highly recommended to not hardcode these credentials: load them from environment variables for local development, and from a secret manager in production.
This snippet is the common starting point for project-based APIs. Some APIs need a different initialization or extra parameters (for example, a region or application credentials), see the section for each API below.
With ASP.NET dependency injection:
// SinchClient is thread safe so it's okay to add it as a singleton
builder.Services.AddSingleton<ISinchClient>(_ => new SinchClient(
builder.Configuration["Sinch:ProjectId"],
builder.Configuration["Sinch:KeyId"],
builder.Configuration["Sinch:KeySecret"]));The Conversation API is regionalized. To use this API, the conversation_region parameter is required:
using Sinch;
using Sinch.Conversation;
var sinch = new SinchClient(
"SINCH_PROJECT_ID",
"SINCH_KEY_ID",
"SINCH_KEY_SECRET",
options =>
{
options.ConversationRegion = ConversationRegion.Eu;
});The Conversation API delivers asynchronous Sinch Events to the Event Destination URL you configure for your app in the Conversation dashboard. ValidateAuthenticationHeader confirms a request comes from Sinch and ParseEvent turns its payload into a typed event object; headers and body are the incoming request's headers and raw body:
using System.Text.Json.Nodes;
using Sinch.Conversation.Hooks;
var headers = Request.Headers.ToDictionary(h => h.Key, h => h.Value);
var body = /* raw JSON body as JsonNode */;
bool validAuth = sinch.Conversation.Webhooks.ValidateAuthenticationHeader(headers, body, sinchEventsSecret);
ICallbackEvent callbackEvent = sinch.Conversation.Webhooks.ParseEvent(body);sinchEventsSecret is set per app in the Conversation dashboard. ParseEvent works without validating the request, but then its origin can't be verified, so validating is recommended in production.
You can find a complete example in examples/WebApi/Controllers/ReceiveConversationCallbackController.cs.
Warning: the SMS API is end-of-sale. For new integrations, prefer the Conversation API.
The SMS API is regionalized: set sms_region to the region where your SMS account is hosted. The accepted values depend on which credentials you use:
- Project access keys: available only in the
usandeuregions. Use the sameproject_id,key_idandkey_secretas the common client, plussms_region:
using Sinch;
using Sinch.SMS;
var sinch = new SinchClient(
"SINCH_PROJECT_ID",
"SINCH_KEY_ID",
"SINCH_KEY_SECRET",
options =>
{
options.SmsRegion = SmsRegion.Us;
});SMS authentication for new projects
Projects created after the SMS API end-of-sale (
15/04/26) cannot use project access keys. The SMS API requests return401 Unauthorized.If you encounter this issue, consider the following options:
- Use service plan credentials (
service_plan_id+sms_api_token)- Use the Conversation API, which works with project access keys.
- Contact your account manager
- Service plan: available in all regions (
us,eu,au,br,ca). Use aservice_plan_idandsms_api_token, both available on the Service APIs dashboard:
using Sinch;
using Sinch.SMS;
var sinch = new SinchClient(default, default, default,
options =>
{
options.UseServicePlanIdWithSms(
"SINCH_SERVICE_PLAN_ID",
"SINCH_SMS_API_TOKEN",
SmsServicePlanIdRegion.Us);
});Note: if you use both the SMS and the Conversation API from the same client, set
sms_regionandconversation_regionto the same region. Mismatched regions cause delivery failures.
The SMS API delivers asynchronous Sinch Events to an Event Destination, whose URL is set per batch with the callback_url parameter on the send, update and replace operations. The SDK provides typed models for deserializing inbound callbacks, such as IncomingTextSms and RecipientDeliveryReport:
using Sinch.SMS.Hooks;
// In an ASP.NET controller, model binding deserializes the payload automatically:
[HttpPost]
public async Task HandleInbound([FromBody] IncomingTextSms incomingSms)
{
// handle inbound SMS event
}Signature authentication for SMS events must be enabled for your account by your account manager. Until it is activated, signature headers will not be present. See the SMS events documentation.
You can find a complete example in examples/WebApi/Controllers/InboundSmsController.cs.
The Voice API uses application credentials. Set application_key and application_secret, both available on the Apps dashboard; voice_region is optional and defaults to a global region:
using Sinch;
using Sinch.Voice;
var voiceClient = sinch.Voice(
"SINCH_APPLICATION_KEY",
"SINCH_APPLICATION_SECRET",
VoiceRegion.Global);The Voice API delivers synchronous Sinch Events to the Event Destination URL configured for your app. Requests are signed with your application credentials, so validation requires the HTTP verb and URI of the controller handling the request, in addition to the headers and raw body:
using Sinch.Voice.Hooks;
bool validAuth = voiceClient.ValidateAuthenticationHeader(
HttpMethod.Post,
"/webhooks/voice",
Request.Headers.ToDictionary(h => h.Key, h => h.Value.AsEnumerable()),
rawBody);
IVoiceEvent voiceEvent = voiceClient.ParseEvent(rawBody);Some events (for example an incoming call) expect a SVAML response: build it from the business layer and return it from your controller.
You can find a complete example in examples/WebApi/Controllers/HandleIncomingIceEventController.cs.
The Verification API uses application credentials. Set application_key and application_secret, both available on the Apps dashboard:
using Sinch;
var verificationClient = sinch.Verification(
"SINCH_APPLICATION_KEY",
"SINCH_APPLICATION_SECRET");The Verification API delivers synchronous Sinch Events to the Event Destination URL configured for your app. Requests are signed with your application credentials, so validation requires the HTTP verb and URI of the controller handling the request, in addition to the headers and raw body:
using System.Text.Json;
using Sinch.Verification.Hooks;
bool validAuth = verificationClient.ValidateAuthenticationHeader(
HttpMethod.Post,
"/webhooks/verification",
Request.Headers.ToDictionary(h => h.Key, h => h.Value.AsEnumerable()),
rawBody);
var verificationEvent = JsonSerializer.Deserialize<VerificationRequestEvent>(rawBody);Some events expect a response: build it from the business layer and return it to Sinch.
The Numbers API needs no extra parameters, use the common client shown above.
The Numbers API delivers asynchronous Sinch Events to the Event Destination you configure through sinch.Numbers.Callbacks. ValidateAuthenticationHeader confirms a request comes from Sinch; headers and body are the incoming request's headers and raw body:
using System.Text.Json;
using Sinch.Numbers.Hooks;
bool validAuth = sinch.Numbers.ValidateAuthenticationHeader(sinchEventsSecret, rawBody, Request.Headers);
var numbersEvent = JsonSerializer.Deserialize<Event>(rawBody);sinchEventsSecret is the HmacSecret value configured on the Event Destination. Deserializing the payload works without validating the request, but then its origin can't be verified, so validating is recommended in production.
The Fax API needs no extra parameters beyond the common client shown above. Optionally set fax_region in SinchOptions to select the regional endpoint.
The Fax API delivers asynchronous Sinch Events to the incoming webhook URL you configure per service in the Fax dashboard. The SDK provides typed event models such as IncomingFaxEvent and CompletedFaxEvent for deserializing the payload:
using Sinch.Fax.Hooks;
[HttpPost]
public IActionResult HandleFaxEvent([FromBody] IFaxEvent faxEvent)
{
// handle fax event
}No request signature validation is implemented for the Fax API. You can find a complete example in examples/WebApi/Controllers/HandleFaxEventController.cs.
Once your client is configured, you can send your first message. The example below uses the Conversation API to send a simple text message over SMS. Replace CONVERSATION_APP_ID with your app ID, SINCH_VIRTUAL_PHONE_NUMBER with your Sinch number and RECIPIENT_PHONE_NUMBER with the recipient's phone number:
using Sinch.Conversation;
using Sinch.Conversation.Common;
using Sinch.Conversation.Messages;
using Sinch.Conversation.Messages.Message;
using Sinch.Conversation.Messages.Send;
var response = await sinch.Conversation.Messages.Send(new SendMessageRequest
{
AppId = "CONVERSATION_APP_ID",
Recipient = new Identified
{
IdentifiedBy = new IdentifiedBy
{
ChannelIdentities = new List<ChannelIdentity>
{
new()
{
Channel = ConversationChannel.Sms,
Identity = "RECIPIENT_PHONE_NUMBER"
}
}
}
},
Message = new AppMessage(new TextMessage("Hello from the Sinch .NET SDK!")),
ChannelProperties = new Dictionary<string, string>
{
["SMS_SENDER"] = "SINCH_VIRTUAL_PHONE_NUMBER"
}
});The SDK uses Microsoft.Extensions.Logging. Provide an ILoggerFactory through SinchOptions when initializing the client:
using Sinch;
var sinch = new SinchClient(
"SINCH_PROJECT_ID",
"SINCH_KEY_ID",
"SINCH_KEY_SECRET",
options =>
{
options.LoggerFactory = LoggerFactory.Create(config =>
{
config.AddConsole();
});
});If no logger factory is provided, the SDK does not emit log output.
For an unsuccessful API call, SinchApiException will be thrown. It exposes the HTTP status code, a status string, a detailed message, and any additional error details:
using Sinch;
using Sinch.SMS.Batches.Send;
try
{
var batch = await sinch.Sms.Batches.Send(new SendTextBatchRequest
{
Body = "Hello, World!",
To = new List<string> { "+123456789" }
});
}
catch (SinchApiException e)
{
logger.LogError("API exception. Status: {status}. Detailed message: {message}", e.Status, e.DetailedMessage);
}Authentication failures throw SinchAuthException from the Sinch.Auth namespace.
By default, the SDK creates and manages its own HttpClient. To provide your own instance (for example, to configure a proxy or reuse a shared client), pass it through SinchOptions:
using Sinch;
var sinch = new SinchClient(
"SINCH_PROJECT_ID",
"SINCH_KEY_ID",
"SINCH_KEY_SECRET",
options =>
{
options.HttpClient = new HttpClient();
});For additional configuration options such as API URL overrides, see SinchOptions.
The SDK relies on the following third-party dependencies:
- Microsoft.Extensions.Http: HTTP client factory integration.
- Microsoft.Extensions.Primitives: Primitive types used across the SDK.
- System.Text.Json: JSON serialization and deserialization.
You can find:
- a C# example of selected API operations in the snippets folder.
- console application examples in the examples/Console folder.
- an ASP.NET web application for handling Sinch Events in the examples/WebApi folder.
For information about the latest changes in the SDK, please refer to the GitHub releases page.
This project is licensed under the Apache License. See the LICENSE file for the license text.
Developer Experience engineering team: team-developer-experience@sinch.com