PostKit 10.0.1

dotnet add package PostKit --version 10.0.1
                    
NuGet\Install-Package PostKit -Version 10.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="PostKit" Version="10.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="PostKit" Version="10.0.1" />
                    
Directory.Packages.props
<PackageReference Include="PostKit" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add PostKit --version 10.0.1
                    
#r "nuget: PostKit, 10.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package PostKit@10.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=PostKit&version=10.0.1
                    
Install as a Cake Addin
#tool nuget:?package=PostKit&version=10.0.1
                    
Install as a Cake Tool

Banner

PostKit

A MimeKit infused implementation of the Postmark API.

develop nuget downloads

Quickstart

Prerequisites

  • .NET 8.0 or later
  • A Postmark account with a Server API Token
  • Verified sender email addresses in your Postmark account

Installation

Install PostKit via NuGet:

dotnet add package PostKit

Configuration

Add PostKit to your services and configure your Postmark API token:

// Program.cs (Minimal API / Web App)
using PostKit;

var builder = WebApplication.CreateBuilder(args);

// Add PostKit to services
builder.Services.AddPostKit();

var app = builder.Build();

Configure your Postmark Server API Token in appsettings.json:

{
  "PostKit": {
    "ServerApiToken": "your-postmark-server-token-here"
  }
}

Or set it via environment variables:

PostKit__ServerApiToken=your-postmark-server-token-here

If you need multiple Postmark configurations (for example, separate servers or tenants), register keyed services with AddKeyedPostKit. Each keyed registration binds to PostKit:{configurationKey}; if you omit configurationKey, the serviceKey.ToString() value is used.

builder.Services.AddKeyedPostKit("Marketing"); // binds PostKit:Marketing
public enum PostmarkServer
{
    Development,
    Production
}

builder.Services.AddKeyedPostKit(PostmarkServer.Development); // binds PostKit:Development
builder.Services.AddKeyedPostKit(PostmarkServer.Production, "Default"); // binds PostKit:Default
{
  "PostKit": {
    "Marketing": { "ServerApiToken": "token-1" },
    "Development": { "ServerApiToken": "token-2" },
    "Default": { "ServerApiToken": "token-3" }
  }
}

Basic Usage

PostKit uses a fluent builder pattern with the following capabilities:

  • Email Addresses: Support for simple strings, name/address pairs, or MimeKit MailboxAddress objects
  • Multiple Recipients: Chain AlsoTo(), AlsoCc(), or AlsoBcc() to add additional recipients
  • Validation: Automatic validation of email addresses, character limits, and required fields
Simple Email
using PostKit;

// Inject IPostKitClient via dependency injection
public class EmailService
{
    private readonly IPostKitClient _postKitClient;

    public EmailService(IPostKitClient postKitClient)
    {
        _postKitClient = postKitClient;
    }

    public async Task SendWelcomeEmailAsync()
    {
        var email = Email.CreateBuilder()
            .From("noreply@yourapp.com")
            .To("user@example.com")
            .WithSubject("Welcome to Our Service!")
            .WithTextBody("Thank you for signing up!")
            .Build();

        await _postKitClient.SendEmailAsync(email);
    }
}
Rich HTML Email
var email = Email.CreateBuilder()
    .From("Sarah Johnson", "sarah@company.com")
    .To("customer@example.com")
    .WithSubject("Your Order Confirmation")
    .WithHtmlBody(@"
        <h1>Order Confirmed!</h1>
        <p>Thank you for your purchase. Your order #12345 has been confirmed.</p>
        <a href='https://yourapp.com/orders/12345'>View Order Details</a>
    ")
    .WithTextBody("Order Confirmed! Thank you for your purchase. Your order #12345 has been confirmed. View details at: https://yourapp.com/orders/12345")
    .Build();

await _postKitClient.SendEmailAsync(email);
Multiple Recipients
var email = Email.CreateBuilder()
    .From("notifications@company.com")
    .To(new[] { "user1@example.com", "user2@example.com" })
    .Cc("manager@company.com")
    .Bcc("admin@company.com")
    .WithSubject("Team Update")
    .WithTextBody("Important team announcement...")
    .Build();

await _postKitClient.SendEmailAsync(email);
Batch Sending
var welcomeEmail = Email.CreateBuilder()
    .From("noreply@yourapp.com")
    .To("user1@example.com")
    .WithSubject("Welcome!")
    .WithTextBody("Thanks for signing up")
    .Build();

var reminderEmail = Email.CreateBuilder()
    .From("noreply@yourapp.com")
    .To("user2@example.com")
    .WithSubject("Complete Your Profile")
    .WithTextBody("Finish setting up your account")
    .Build();

var batchResult = await _postKitClient.SendEmailBatchAsync(new[] { welcomeEmail, reminderEmail });

if (!batchResult.IsSuccessful)
{
    foreach (var result in batchResult.Results.Where(result => !result.IsSuccessful))
    {
        // Inspect result.Email and result.Message to handle the failure.
    }
}
Advanced Features
var email = Email.CreateBuilder()
    .From("newsletter@company.com")
    .To("subscriber@example.com")
    .ReplyTo("support@company.com")
    .WithSubject("Monthly Newsletter")
    .WithHtmlBody("<h1>Newsletter</h1><p>Check out our latest updates!</p>")
    .WithTag("newsletter")
    .WithMetadata("campaign", "monthly-2024")
    .WithMetadata("segment", "premium-users")
    .WithOpenTracking(true)
    .WithLinkTracking(LinkTracking.HtmlAndText)
    .UsingMessageStream(MessageStream.Broadcast)
    .WithHeader("X-Campaign-ID", "CAMP-001")
    .Build();

await _postKitClient.SendEmailAsync(email);
Attachments and Inline Images
var invoice = Attachment.Create(
    name: "invoice.pdf",
    contentType: "application/pdf",
    content: await File.ReadAllBytesAsync("invoice.pdf"));

var logo = Attachment.Create(
    name: "logo.png",
    contentType: "image/png",
    content: await File.ReadAllBytesAsync("logo.png"),
    contentId: "logo@yourapp.com");

var email = Email.CreateBuilder()
    .From("billing@company.com")
    .To("customer@example.com")
    .WithSubject("Your Monthly Invoice")
    .WithHtmlBody($"<p>Please find your invoice attached.</p><img src=\"{logo.ContentId}\" alt=\"Company Logo\" />")
    .WithAttachment(invoice)
    .WithAttachment(logo)
    .Build();

await _postKitClient.SendEmailAsync(email);

Size Limits

Postmark limits TextBody and HtmlBody to 5 MB each, and total message size (including attachments) to 10 MB. When batching, Postmark accepts up to 500 emails per batch and batch payloads are limited to 50 MB. PostKit uses a conservative estimate to prevent grossly oversized requests. Actual size limits will be enforced by the Postmark API.

Error Handling

PostKit uses LightResults for error handling. SendEmailAsync returns a Result<SendEmailResponse> that contains either the response or error information:

var result = await _postKitClient.SendEmailAsync(email);

if (result.IsSuccess(out var response, out var error))
{
    // Email sent successfully
    Console.WriteLine($"Email sent with MessageId: {response.MessageId}");
}
else
{
    // Handle the error
    Console.WriteLine($"Failed to send email: {error.Message}");
}
Error Types

PostKit may return different types of errors depending on the failure scenario:

HttpError - Returned for HTTP-level failures (network issues, timeouts, non-422 status codes):

if (error is HttpError httpError)
{
    Console.WriteLine($"HTTP error: {httpError.StatusCode} - {httpError.Message}");
}

PostmarkError - Returned for Postmark API validation errors (422 status code):

if (error is PostmarkError postmarkError)
{
    Console.WriteLine($"Postmark error: {postmarkError.ErrorCode} - {postmarkError.Message}");

    // Handle specific error codes
    switch (postmarkError.ErrorCode)
    {
        case PostmarkErrorCode.SenderSignatureNotFound:
            // The From address doesn't have a verified sender signature
            break;
        case PostmarkErrorCode.InvalidEmailRequest:
            // The email request validation failed
            break;
        case PostmarkErrorCode.NotAllowedToSend:
            // Account has run out of credits
            break;
    }
}

See PostmarkErrorCode enum for the complete list of possible Postmark error codes.

Message Streams

Postmark supports different message streams for different types of emails:

// For transactional emails (default)
.UsingMessageStream(MessageStream.Transactional)

// For broadcast/marketing emails
.UsingMessageStream(MessageStream.Broadcast)

// Or use a custom stream ID
.UsingMessageStream("custom-stream-id")

Complete Console Application Example

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using PostKit;

var builder = Host.CreateApplicationBuilder(args);

// Add PostKit
builder.Services.AddPostKit();

var host = builder.Build();

// Get the PostKit client
var postKitClient = host.Services.GetRequiredService<IPostKitClient>();

// Create and send an email
var email = Email.CreateBuilder()
    .From("test@yourapp.com")
    .To("recipient@example.com")
    .WithSubject("Test Email from PostKit")
    .WithTextBody("Hello from PostKit! This email was sent using the PostKit library.")
    .WithHtmlBody("<h1>Hello from PostKit!</h1><p>This email was sent using the <strong>PostKit</strong> library.</p>")
    .Build();

await postKitClient.SendEmailAsync(email);

Console.WriteLine("Email sent successfully!");

Development

The following tables track development progress and map the different Postmark API endpoints to their respective methods in PostKit.

Email API

Endpoint Implementation
Send a single email IPostKitClient.SendEmailAsync
Send batch emails IPostKitClient.SendEmailBatchAsync

Bulk Email

Endpoint Implementation
✏️ Send bulk emails BETA
✏️ Get the status/details of a bulk API request BETA

Bounce API

Endpoint Implementation
✏️ Get delivery stats
✏️ Get bounces
✏️ Get a single bounce
✏️ Get bounce dump
✏️ Activate a bounce
✏️ Bounce types
✏️ Rebound

Templates API

Endpoint Implementation
Send email with template IPostKitClient.SendEmailAsync
Send batch with templates IPostKitClient.SendEmailBatchAsync
✏️ Push templates to another server
✏️ Get a template
✏️ Create a template
✏️ Edit a template
✏️ List templates
✏️ Delete a template
✏️ Validate a template

Server API

Endpoint Implementation
✏️ Get the server
✏️ Edit the server

Servers API

Endpoint Implementation
✏️ Get a server
✏️ Create a server
✏️ Edit a server
✏️ List servers
✏️ Delete a server

Message Streams API

Endpoint Implementation
✏️ List message streams
✏️ Get a message stream
✏️ Edit a message stream
✏️ Create a message stream
✏️ Archive a message stream
✏️ Unarchive a message stream

Messages API

Endpoint Implementation
✏️ Outbound message search
✏️ Outbound message details
✏️ Outbound message dump
✏️ Inbound message search
✏️ Inbound message details
✏️ Bypass rules for a blocked inbound message
✏️ Retry a failed inbound message for processing
✏️ Message opens
✏️ Opens for a single message
✏️ Message clicks
✏️ Clicks for a single message

Domains API

Endpoint Implementation
✏️ List domains
✏️ Get domain details
✏️ Create domain
✏️ Edit domain
✏️ Delete domain
✏️ Verify DKIM
✏️ Verify Return-Path
✏️ Verify an SPF record
✏️ Rotate DKIM keys

Sender signatures API

Endpoint Implementation
✏️ List sender signatures
✏️ Get sender signature
✏️ Create a signature
✏️ Edit a signature
✏️ Delete a signature
✏️ Resend a confirmation
✏️ Verify an SPF record
✏️ Request a new DKIM

Stats API

Endpoint Implementation
✏️ Get outbound overview
✏️ Get sent counts
✏️ Get bounce counts
✏️ Get spam complaints
✏️ Get tracked email counts
✏️ Get email open counts
✏️ Get email platform usage
✏️ Get email client usage
✏️ Get click counts
✏️ Get browser usage
✏️ Get browser platform usage
✏️ Get click location

Triggers: Inbound rules

Endpoint Implementation
✏️ List inbound rule triggers
✏️ Create an inbound rule trigger
✏️ Delete a single trigger

Webhooks API

Endpoint Implementation
✏️ List webhooks
✏️ Get a webhook
✏️ Create a webhook
✏️ Edit a webhook
✏️ Delete a webhook

Suppressions API

Endpoint Implementation
✏️ Suppression dump
✏️ Create a Suppression
✏️ Delete a Suppression

Data Removal API

Endpoint Implementation
✏️ Create a Data Removal request
✏️ Check a Data Removal request status
Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
10.0.1 218 12/22/2025
10.0.0 270 12/16/2025
10.0.0-preview.1 543 11/15/2025
9.0.0-preview.7 363 10/13/2025
9.0.0-preview.6 134 10/13/2025
9.0.0-preview.5 629 10/8/2025
9.0.0-preview.4 154 9/24/2025
9.0.0-preview.3 141 9/24/2025
9.0.0-preview.2 896 12/22/2024
9.0.0-preview.1 91 12/21/2024