22
33[ ![ CI] ( https://github.com/teesofttech/Termii.SDK/actions/workflows/ci.yml/badge.svg )] ( https://github.com/teesofttech/Termii.SDK/actions/workflows/ci.yml )
44
5- A .NET SDK for the Termii messaging, token, and insights APIs.
5+ A .NET SDK for the Termii messaging, sender ID, Number API, Token API, and Insights APIs.
66
7- > This SDK is in early development. The first milestones establish the client, tests, examples, API coverage matrix, and package structure before endpoint support is added feature by feature.
7+ ## Installation
88
9- ## Current Status
10-
11- The initial repository setup includes:
12-
13- - A ` Termii ` SDK project targeting ` netstandard2.0 ` and ` net8.0 ` .
14- - A lightweight unit test project.
15- - An examples project for developer-facing usage.
16- - An API coverage matrix in ` docs/API_COVERAGE.md ` .
17-
18- ## Usage
19-
20- Install the package:
9+ Install from NuGet:
2110
2211``` bash
2312dotnet add package Termii.SDK
2413```
2514
15+ Then import the SDK namespace:
16+
2617``` csharp
2718using Termii ;
19+ ```
2820
21+ ## Configuration
22+
23+ Create a client manually:
24+
25+ ``` csharp
2926var client = new TermiiClient (new TermiiOptions
3027{
3128 ApiKey = " your-termii-api-key"
3229});
3330```
3431
35- The default base URL is ` https://api.ng.termii.com ` .
32+ The default base URL is ` https://api.ng.termii.com ` . Override it only when your Termii account or environment requires a different base URL:
33+
34+ ``` csharp
35+ var client = new TermiiClient (new TermiiOptions
36+ {
37+ ApiKey = " your-termii-api-key" ,
38+ BaseUrl = new Uri (" https://api.ng.termii.com" ),
39+ Timeout = TimeSpan .FromSeconds (30 )
40+ });
41+ ```
3642
37- For ASP.NET Core applications, register the SDK with dependency injection:
43+ For ASP.NET Core applications, register ` TermiiClient ` with dependency injection:
3844
3945``` csharp
4046builder .Services .AddTermii (options =>
@@ -43,7 +49,35 @@ builder.Services.AddTermii(options =>
4349});
4450```
4551
46- Send a message:
52+ Use it from a service or endpoint:
53+
54+ ``` csharp
55+ public sealed class NotificationService
56+ {
57+ private readonly TermiiClient _termii ;
58+
59+ public NotificationService (TermiiClient termii )
60+ {
61+ _termii = termii ;
62+ }
63+
64+ public Task <TermiiMessageResponse > SendAsync (string phoneNumber , string message )
65+ {
66+ return _termii .Messaging .SendAsync (new SendMessageRequest
67+ {
68+ To = phoneNumber ,
69+ From = " Termii" ,
70+ Sms = message ,
71+ Channel = TermiiMessageChannel .Generic ,
72+ Type = TermiiMessageType .Plain
73+ });
74+ }
75+ }
76+ ```
77+
78+ ## Messaging
79+
80+ Send a single SMS:
4781
4882``` csharp
4983var response = await client .Messaging .SendAsync (new SendMessageRequest
@@ -56,22 +90,50 @@ var response = await client.Messaging.SendAsync(new SendMessageRequest
5690});
5791```
5892
59- Fetch sender IDs :
93+ Send a bulk SMS :
6094
6195``` csharp
62- var senderIds = await client .SenderIds .GetAsync ();
96+ var response = await client .Messaging .SendBulkAsync (new SendBulkMessageRequest
97+ {
98+ To = new [] { " 2348012345678" , " 2348098765432" },
99+ From = " Termii" ,
100+ Sms = " Hello everyone" ,
101+ Channel = TermiiMessageChannel .Generic ,
102+ Type = TermiiMessageType .Plain
103+ });
63104```
64105
65106Send through the Number API:
66107
67108``` csharp
68- var numberMessage = await client .Numbers .SendAsync (new SendNumberMessageRequest
109+ var response = await client .Numbers .SendAsync (new SendNumberMessageRequest
69110{
70111 To = " 2348012345678" ,
71112 Sms = " Hello from a dedicated Termii number"
72113});
73114```
74115
116+ ## Sender IDs
117+
118+ Fetch sender IDs:
119+
120+ ``` csharp
121+ var senderIds = await client .SenderIds .GetAsync ();
122+ ```
123+
124+ Request a sender ID:
125+
126+ ``` csharp
127+ var request = await client .SenderIds .RequestAsync (new RequestSenderIdRequest
128+ {
129+ SenderId = " Termii" ,
130+ UseCase = " Transactional alerts" ,
131+ Company = " Example Ltd"
132+ });
133+ ```
134+
135+ ## Tokens and OTP
136+
75137Send an OTP token:
76138
77139``` csharp
@@ -88,12 +150,115 @@ var token = await client.Tokens.SendAsync(new SendTokenRequest
88150});
89151```
90152
153+ Verify an OTP token:
154+
155+ ``` csharp
156+ var verification = await client .Tokens .VerifyAsync (new VerifyTokenRequest
157+ {
158+ PinId = token .PinId ! ,
159+ Pin = " 123456"
160+ });
161+ ```
162+
163+ Generate an in-app OTP:
164+
165+ ``` csharp
166+ var generated = await client .Tokens .GenerateAsync (new GenerateTokenRequest
167+ {
168+ PhoneNumber = " 2348012345678" ,
169+ PinType = TermiiTokenPinType .Numeric ,
170+ PinAttempts = 3 ,
171+ PinTimeToLive = 10 ,
172+ PinLength = 6
173+ });
174+ ```
175+
176+ The token client also supports voice OTP, voice call OTP, email OTP, and WhatsApp OTP through ` SendVoiceAsync ` , ` CallAsync ` , ` SendEmailAsync ` , and ` SendWhatsAppAsync ` .
177+
178+ ## Insights
179+
91180Check account balance:
92181
93182``` csharp
94183var balance = await client .Insights .GetBalanceAsync ();
95184```
96185
186+ Check DND status:
187+
188+ ``` csharp
189+ var dnd = await client .Insights .CheckDndAsync (new CheckDndRequest
190+ {
191+ PhoneNumber = " 2348012345678"
192+ });
193+ ```
194+
195+ Query number intelligence:
196+
197+ ``` csharp
198+ var number = await client .Insights .QueryNumberAsync (new QueryNumberRequest
199+ {
200+ PhoneNumber = " 2348012345678" ,
201+ CountryCode = " NG"
202+ });
203+ ```
204+
205+ Fetch message history:
206+
207+ ``` csharp
208+ var history = await client .Insights .GetMessageHistoryAsync (new GetMessageHistoryRequest
209+ {
210+ Page = 0 ,
211+ Size = 15 ,
212+ Sender = " Termii" ,
213+ Receiver = " 2348012345678"
214+ });
215+ ```
216+
217+ ## Error Handling
218+
219+ The SDK throws ` TermiiApiException ` for non-success HTTP responses from Termii:
220+
221+ ``` csharp
222+ try
223+ {
224+ await client .Messaging .SendAsync (new SendMessageRequest
225+ {
226+ To = " 2348012345678" ,
227+ From = " Termii" ,
228+ Sms = " Hello from .NET" ,
229+ Channel = TermiiMessageChannel .Generic
230+ });
231+ }
232+ catch (TermiiApiException ex )
233+ {
234+ Console .WriteLine ($" HTTP status: {(int )ex .StatusCode }" );
235+ Console .WriteLine ($" Termii code: {ex .TermiiCode }" );
236+ Console .WriteLine ($" Termii message: {ex .TermiiMessage }" );
237+ }
238+ ```
239+
240+ Request models also validate required fields before sending. Missing required values throw ` ArgumentException ` , and invalid numeric ranges throw ` ArgumentOutOfRangeException ` .
241+
242+ ## Supported APIs
243+
244+ Implemented in the current SDK:
245+
246+ - Messaging: send single, WhatsApp conversational, and bulk messages.
247+ - Sender IDs: list and request sender IDs.
248+ - Number API: send message through a dedicated Termii number.
249+ - Tokens: send, verify, generate, voice, email, and WhatsApp OTP flows.
250+ - Insights: balance, DND status, number intelligence, and message history.
251+
252+ Deferred or not yet implemented:
253+
254+ - WhatsApp template/device message APIs.
255+ - Campaign phonebook APIs.
256+ - Product notification email APIs.
257+ - Webhook event models.
258+ - ` /api/sms/history/analytics ` , pending additional verification.
259+
260+ See [ docs/API_COVERAGE.md] ( docs/API_COVERAGE.md ) for the detailed coverage matrix.
261+
97262## Examples
98263
99264Run the examples project after setting your Termii API key:
@@ -103,10 +268,17 @@ export TERMII_API_KEY="your-termii-api-key"
103268dotnet run --project examples/Termii.Examples
104269```
105270
106- To send a live Number API example message, opt in explicitly :
271+ Run a live balance example:
107272
108273``` bash
109- export TERMII_SEND_NUMBER_MESSAGE=" true"
274+ export TERMII_EXAMPLE_ACTION=" balance"
275+ dotnet run --project examples/Termii.Examples
276+ ```
277+
278+ Send a live Number API example message:
279+
280+ ``` bash
281+ export TERMII_EXAMPLE_ACTION=" number-message"
110282export TERMII_EXAMPLE_PHONE_NUMBER=" 2348012345678"
111283dotnet run --project examples/Termii.Examples
112284```
@@ -128,20 +300,15 @@ export TERMII_TEST_PHONE_NUMBER="2348012345678"
128300dotnet test tests/Termii.IntegrationTests
129301```
130302
131- As endpoint support is added, integration tests should remain credential-gated so normal CI can run without network access or Termii credits.
132-
133- ## Roadmap
303+ ## Release
134304
135- Development is tracked through GitHub issues:
305+ Releases are published from version tags through GitHub Actions. See [ docs/RELEASING.md ] ( docs/RELEASING.md ) for the checklist.
136306
137- - SDK foundation and HTTP pipeline.
138- - Messaging APIs.
139- - Sender ID and number APIs.
140- - Token/OTP APIs.
141- - Insights APIs.
142- - CI, documentation, NuGet packaging, and GitHub Releases.
307+ ## Links
143308
144- Official Termii documentation: https://developer.termii.com/
309+ - Termii developer docs: https://developer.termii.com/
310+ - NuGet package: https://www.nuget.org/packages/Termii.SDK
311+ - API coverage: [ docs/API_COVERAGE.md] ( docs/API_COVERAGE.md )
145312
146313## License
147314
0 commit comments