Emailit.Client.v2
2.1.1
See the version list below for details.
dotnet add package Emailit.Client.v2 --version 2.1.1
NuGet\Install-Package Emailit.Client.v2 -Version 2.1.1
<PackageReference Include="Emailit.Client.v2" Version="2.1.1" />
<PackageVersion Include="Emailit.Client.v2" Version="2.1.1" />
<PackageReference Include="Emailit.Client.v2" />
paket add Emailit.Client.v2 --version 2.1.1
#r "nuget: Emailit.Client.v2, 2.1.1"
#:package Emailit.Client.v2@2.1.1
#addin nuget:?package=Emailit.Client.v2&version=2.1.1
#tool nuget:?package=Emailit.Client.v2&version=2.1.1
Emailit.Client v2
A .NET client library for the Emailit API v2, built on top of Flurl HTTP.
The client covers emails, domains, API keys, audiences, subscribers, templates, suppressions, email verification, contacts, events, and webhooks.
Current package version prepared in this repository: 2.1.1.
Current State
This package is tested against the live production Emailit API, not only against mocked responses.
The client now includes compatibility handling for several production response quirks:
- booleans returned as
true/false,0/1, or string equivalents - numbers returned as strings
- timestamps returned in mixed formats, including empty strings
- recipient fields returned as either a single string or an array
- email attachments returned as either
attachmentsordata - legacy
ResendEmailAsyncfalling back toRetryEmailAsyncwhen/resendis unavailable
Stable production integration coverage currently includes:
- connection check and rate limits
- domains and API keys
- audiences, subscribers, contacts, and suppressions
- templates
- emails and email sub-resources
- events
- single email verification
Some production endpoints are still inconsistent on the server side and are isolated as unstable integration coverage:
- webhooks
- verification list/results/export endpoints
- retry/resend behavior as standalone production checks
Installation
dotnet add package Emailit.Client.v2
Target frameworks:
- .NET 8.0
- .NET 9.0
- .NET 10.0
Configuration
appsettings.json
{
"Emailit": {
"ApiKey": "em_your_api_key_here",
"BaseUrl": "https://api.emailit.com",
"TimeoutSeconds": 30
}
}
using Emailit.Client.DependencyInjection;
builder.Services.AddEmailitClient(builder.Configuration);
Manual configuration
using var client = new EmailitClient(new EmailitClientOptions
{
ApiKey = "em_your_api_key_here",
BaseUrl = "https://api.emailit.com",
TimeoutSeconds = 30
});
Multi-tenant factory
builder.Services.AddEmailitClientFactory(options =>
{
options.BaseUrl = "https://api.emailit.com";
options.TimeoutSeconds = 30;
});
Quick Usage
Send an email
var response = await client.SendEmailAsync(new SendEmailRequest
{
From = "sender@yourdomain.com",
To = ["recipient@example.com"],
Subject = "Hello from Emailit",
Html = "<h1>Welcome</h1><p>This is a test email.</p>"
});
Console.WriteLine($"{response.Id} - {response.Status}");
Send with template
var response = await client.SendEmailAsync(new SendEmailRequest
{
From = "sender@yourdomain.com",
To = ["recipient@example.com"],
TemplateId = "tpl_abc123",
Variables = new Dictionary<string, object>
{
["first_name"] = "John"
}
});
Schedule, update, and cancel
var scheduled = await client.SendEmailAsync(new SendEmailRequest
{
From = "sender@yourdomain.com",
To = ["recipient@example.com"],
Subject = "Scheduled email",
Html = "<p>Scheduled</p>",
ScheduledAt = "2026-12-25T10:00:00Z"
});
await client.UpdateScheduledEmailAsync(scheduled.Id, new UpdateScheduledEmailRequest
{
ScheduledAt = "2026-12-26T10:00:00Z"
});
await client.CancelEmailAsync(scheduled.Id);
Email sub-resources
var meta = await client.GetEmailMetaAsync("em_abc123");
var body = await client.GetEmailBodyAsync("em_abc123");
var raw = await client.GetEmailRawAsync("em_abc123");
var attachments = await client.GetEmailAttachmentsAsync("em_abc123");
Retry a failed email
var retried = await client.RetryEmailAsync("em_failed123");
Console.WriteLine($"{retried.Id} - {retried.Status}");
Verify a single email
var verification = await client.VerifyEmailAsync(new VerifyEmailRequest
{
Email = "user@example.com"
});
Console.WriteLine($"{verification.Email} - {verification.Result}");
Manage domains
var domain = await client.CreateDomainAsync(new CreateDomainRequest
{
Name = "yourdomain.com",
TrackLoads = true,
TrackClicks = true
});
await client.UpdateDomainAsync(domain.Id, new UpdateDomainRequest
{
TrackLoads = true,
TrackClicks = false
});
await client.VerifyDomainAsync(domain.Id);
Note:
UpdateDomainAsyncusesPOSTagainst the production API.
Manage audiences and subscribers
var audience = await client.CreateAudienceAsync(new CreateAudienceRequest
{
Name = "Newsletter"
});
var subscriber = await client.AddSubscriberAsync(audience.Id, new AddSubscriberRequest
{
Email = "john@example.com",
FirstName = "John",
LastName = "Doe"
});
Manage templates
var template = await client.CreateTemplateAsync(new CreateTemplateRequest
{
Name = "Welcome Email",
Alias = "welcome-email",
Subject = "Welcome",
From = "noreply@yourdomain.com",
Html = "<h1>Hello</h1>",
Editor = "html"
});
await client.PublishTemplateAsync(template.Id);
Manage contacts
var contact = await client.CreateContactAsync(new CreateContactRequest
{
Email = "user@example.com",
FirstName = "John",
LastName = "Doe"
});
await client.UpdateContactAsync(contact.Id, new UpdateContactRequest
{
Unsubscribed = true
});
Manage webhooks
var webhook = await client.CreateWebhookAsync(new CreateWebhookRequest
{
Name = "Production Webhook",
Url = "https://yourapp.com/webhooks/emailit",
AllEvents = true
});
Verify webhook signatures
using Emailit.Client.Webhooks;
var isValid = WebhookSignatureValidator.ValidateSignature(
payload,
signature,
timestamp,
webhookSecret,
clockTolerance: TimeSpan.FromMinutes(5));
Error Handling
using Emailit.Client.Exceptions;
try
{
await client.SendEmailAsync(request);
}
catch (EmailitValidationException ex)
{
Console.WriteLine(ex.Message);
}
catch (EmailitAuthenticationException)
{
}
catch (EmailitNotFoundException)
{
}
catch (DailyLimitExceededException ex)
{
Console.WriteLine(ex.RateLimitInfo?.DailyRemaining);
}
catch (RateLimitExceededException ex)
{
Console.WriteLine(ex.RateLimitInfo?.RetryAfterSeconds);
}
catch (EmailitException ex)
{
Console.WriteLine($"{ex.StatusCode}: {ex.Message}");
}
Rate Limits
Rate limit metadata is exposed on:
EmailResponse.RateLimitInfoafter send operationsIEmailitClient.LastRateLimitInfoafter any request, includingTestConnectionAsync
var info = await client.TestConnectionAsync();
Console.WriteLine(client.LastRateLimitInfo?.DailyRemaining);
Integration Tests
The repository contains two test projects:
tests/Emailit.Client.Tests- unit tests with mocked HTTPtests/Emailit.Client.IntegrationTests- production integration tests
Required environment variables
$env:EMAILIT_INTEGRATION_API_KEY = "em_or_secret_key"
$env:EMAILIT_INTEGRATION_DOMAIN = "yourdomain.com"
$env:EMAILIT_INTEGRATION_TO_EMAIL = "you@example.com"
Optional:
$env:EMAILIT_INTEGRATION_BASE_URL = "https://api.emailit.com"
$env:EMAILIT_INTEGRATION_TIMEOUT_SECONDS = "60"
$env:EMAILIT_INTEGRATION_ENABLE_UNSTABLE = "true"
Run unit tests
dotnet test tests/Emailit.Client.Tests/Emailit.Client.Tests.csproj -c Release
Run stable production integration tests
dotnet test tests/Emailit.Client.IntegrationTests/Emailit.Client.IntegrationTests.csproj -c Release --filter "Stability!=Unstable"
Run unstable production integration tests too
dotnet test tests/Emailit.Client.IntegrationTests/Emailit.Client.IntegrationTests.csproj -c Release
Building the NuGet Package
Only the library project is packaged.
Both test projects are excluded from packaging because their .csproj files set:
<IsPackable>false</IsPackable>
Recommended packaging command:
dotnet pack src/Emailit.Client/Emailit.Client.csproj -c Release -o nupkg
This avoids packing the solution and guarantees that integration tests do not enter the NuGet package.
Supported Endpoints
Emails
SendEmailAsyncGetEmailAsyncListEmailsAsyncUpdateScheduledEmailAsyncCancelEmailAsyncRetryEmailAsyncResendEmailAsync(legacy compatibility path)GetEmailMetaAsyncGetEmailBodyAsyncGetEmailRawAsyncGetEmailAttachmentsAsync
Domains
CreateDomainAsyncGetDomainAsyncListDomainsAsyncUpdateDomainAsyncVerifyDomainAsyncDeleteDomainAsync
API Keys
CreateApiKeyAsyncGetApiKeyAsyncListApiKeysAsyncUpdateApiKeyAsyncDeleteApiKeyAsync
Audiences and Subscribers
CreateAudienceAsyncGetAudienceAsyncListAudiencesAsyncUpdateAudienceAsyncDeleteAudienceAsyncAddSubscriberAsyncGetSubscriberAsyncListSubscribersAsyncUpdateSubscriberAsyncDeleteSubscriberAsync
Templates
CreateTemplateAsyncGetTemplateAsyncListTemplatesAsyncUpdateTemplateAsyncPublishTemplateAsyncDeleteTemplateAsync
Suppressions
CreateSuppressionAsyncGetSuppressionAsyncListSuppressionsAsyncUpdateSuppressionAsyncDeleteSuppressionAsync
Verification
VerifyEmailAsyncCreateVerificationListAsyncGetVerificationListAsyncListVerificationListsAsyncGetVerificationResultsAsyncExportVerificationResultsAsync
Contacts
CreateContactAsyncGetContactAsyncListContactsAsyncUpdateContactAsyncDeleteContactAsync
Events
ListEventsAsyncGetEventAsync
Webhooks
CreateWebhookAsyncGetWebhookAsyncListWebhooksAsyncUpdateWebhookAsyncDeleteWebhookAsync
Resources
License
MIT
| Product | Versions 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 is compatible. 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 is compatible. 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. |
-
net10.0
- Flurl (>= 4.0.0)
- Flurl.Http (>= 4.0.2)
- Microsoft.Extensions.Configuration.Abstractions (>= 8.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Options (>= 8.0.0)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 8.0.0)
-
net8.0
- Flurl (>= 4.0.0)
- Flurl.Http (>= 4.0.2)
- Microsoft.Extensions.Configuration.Abstractions (>= 8.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Options (>= 8.0.0)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 8.0.0)
-
net9.0
- Flurl (>= 4.0.0)
- Flurl.Http (>= 4.0.2)
- Microsoft.Extensions.Configuration.Abstractions (>= 8.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Options (>= 8.0.0)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 8.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
v2.1.1 - Production compatibility hardening and integration coverage
Compatibility fixes:
- tolerant parsing for booleans, numeric strings, mixed DateTime formats, and string-or-array recipients
- GetEmailAttachmentsAsync now handles production responses that return attachment payloads under data
- ResendEmailAsync now falls back to RetryEmailAsync when the legacy resend route is unavailable
- UpdateDomainAsync now uses the production-compatible POST route
- TestConnectionAsync now preserves cancellation and updates LastRateLimitInfo
Quality:
- added production integration tests
- split stable and unstable integration coverage so server-side inconsistencies do not block core client validation