### ASP.NET Integration Setup Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/api-reference/webhooks.md Example of how to set up webhook validation in an ASP.NET Core application's Program.cs file. ```APIDOC ## ASP.NET Integration ### Setup in Program.cs ```csharp var builder = WebApplication.CreateBuilder(args); // Configure webhook validator builder.Services.Configure(options => { options.Secret = builder.Configuration["Resend:WebhookSecret"]; }); builder.Services.AddScoped(); builder.Services.AddControllers(); var app = builder.Build(); app.MapControllers(); app.Run(); ``` ``` -------------------------------- ### Start Temporal CLI Source: https://github.com/resend/resend-dotnet/blob/main/examples/AsyncTemporal/README.md Starts the Temporal server and UI. Ensure the Temporal CLI is downloaded and accessible. ```bash > go CLI 1.2.0 (Server 1.26.2, UI 2.34.0) Server: localhost:7233 UI: http://localhost:8233 Metrics: http://localhost:63482/metrics ``` -------------------------------- ### Install Resend.Webhooks via .NET CLI Source: https://github.com/resend/resend-dotnet/blob/main/src/Resend.Webhooks/README.md Install the Resend.Webhooks NuGet package using the .NET command-line interface. ```bash > dotnet add package Resend.Webhooks ``` -------------------------------- ### Install Resend .NET SDK Source: https://github.com/resend/resend-dotnet/blob/main/README.md Install the Resend .NET SDK using the dotnet CLI. This command adds the necessary package to your project. ```bash > dotnet add package Resend ``` -------------------------------- ### Install Resend.FluentEmail via Package Manager Console Source: https://github.com/resend/resend-dotnet/blob/main/src/Resend.FluentEmail/README.md Install the Resend.FluentEmail NuGet package using the Package Manager Console in Visual Studio. ```powershell PM> Install-Package Resend.FluentEmail ``` -------------------------------- ### Dependency Injection Usage Example Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/api-reference/resend-client.md Example of how to register and inject the `IResend` service in an ASP.NET Core application. ```csharp // With token string builder.Services.AddResend("re_xxx"); // With configuration action builder.Services.AddResend(options => { options.ApiToken = Environment.GetEnvironmentVariable("RESEND_API_KEY"); options.ApiUrl = "https://api.resend.com"; options.ThrowExceptions = true; }); public class MyService { public MyService(IResend resend) { _resend = resend; } } ``` -------------------------------- ### Install Resend.FluentEmail via .NET CLI Source: https://github.com/resend/resend-dotnet/blob/main/src/Resend.FluentEmail/README.md Add the Resend.FluentEmail NuGet package to your project using the .NET command-line interface. ```bash > dotnet add package Resend.FluentEmail ``` -------------------------------- ### Configure ResendClientOptions Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/index.md Provides an example of how to configure the `ResendClientOptions` with an API token and optional API URL and exception handling behavior. ```csharp var options = new ResendClientOptions { ApiToken = "re_xxx", // Required ApiUrl = "https://api.resend.com", // Default ThrowExceptions = true // Default }; ``` -------------------------------- ### Install Resend.Webhooks via Package Manager Console Source: https://github.com/resend/resend-dotnet/blob/main/src/Resend.Webhooks/README.md Install the Resend.Webhooks NuGet package using the Visual Studio Package Manager Console. ```powershell PM> Install-Package Resend.Webhooks ``` -------------------------------- ### Install Resend NuGet Package (Package Manager Console) Source: https://github.com/resend/resend-dotnet/blob/main/src/Resend/README.md Install the Resend NuGet package using the Visual Studio Package Manager Console. ```powershell PM> Install-Package Resend ``` -------------------------------- ### Set Resend API Token and Run .NET App Source: https://github.com/resend/resend-dotnet/blob/main/examples/RenderLiquid/README.md Environment variable setup for the Resend API token and command to run the .NET web application. ```bash set RESEND_APITOKEN=re_8m9gwsVG_6n94KaJkJ42Yj6qSeVvLq9xF dotnet run ``` -------------------------------- ### Run the .NET Web Application Source: https://github.com/resend/resend-dotnet/blob/main/examples/AsyncHangfire/README.md Compiles and runs the Resend .NET web application. This command starts the server, allowing access to the test and Hangfire job UIs. ```bash dotnet run ``` -------------------------------- ### Configure Resend SDK with API Token Source: https://github.com/resend/resend-dotnet/blob/main/README.md Configure the Resend SDK in your application's startup by adding the Resend service and providing your API token. The API token should be securely stored, for example, as an environment variable. ```csharp using Resend; builder.Services.AddResend( o => { o.ApiToken = Environment.GetEnvironmentVariable( "RESEND_APITOKEN" )!; } ); ``` -------------------------------- ### ASP.NET Core Webhook Setup Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/api-reference/webhooks.md Sets up webhook validation services in an ASP.NET Core application's `Program.cs`. It configures the `WebhookValidatorOptions` and registers the `WebhookValidator`. ```csharp var builder = WebApplication.CreateBuilder(args); // Configure webhook validator builder.Services.Configure(options => { options.Secret = builder.Configuration["Resend:WebhookSecret"]; }); builder.Services.AddScoped(); builder.Services.AddControllers(); var app = builder.Build(); app.MapControllers(); app.Run(); ``` -------------------------------- ### Using ResendResponse Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/types.md Example of how to check the success status of an API response and access error details or rate limit information if the call failed. ```csharp var response = await resend.EmailSendAsync(message); if (!response.Success) { Console.WriteLine($"Error: {response.Exception.Message}"); var limits = response.Limits; } ``` -------------------------------- ### ResendException Usage Example Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/errors.md Demonstrates how to catch ResendException, check specific error types like ValidationError and RateLimitExceeded, and determine if an error is transient for retries. ```csharp try { var response = await resend.EmailSendAsync(message); } catch (ResendException ex) { // Check error type if (ex.ErrorType == ErrorType.ValidationError) { Console.WriteLine("Fix validation errors and retry"); } else if (ex.ErrorType == ErrorType.RateLimitExceeded) { var delay = ex.Limits?.RetryAfter ?? 60; Console.WriteLine($"Rate limited, retry in {delay}s"); } // Check if safe to retry if (ex.IsTransient) { await Task.Delay(1000); // retry operation } Console.WriteLine($"Status: {ex.StatusCode}"); Console.WriteLine($"Error: {ex.ErrorType}"); Console.WriteLine($"Message: {ex.Message}"); } ``` -------------------------------- ### Send Email with Resend .NET Client Source: https://github.com/resend/resend-dotnet/blob/main/src/Resend/README.md Example of sending an email using the injected IResend instance. This demonstrates constructing an EmailMessage and calling the EmailSendAsync method. ```csharp using Resend; public class FeatureImplementation { private readonly IResend _resend; public FeatureImplementation( IResend resend ) { _resend = resend; } public async Task Execute() { var message = new EmailMessage(); message.From = "onboarding@resend.dev"; message.To.Add( "delivered@resend.dev" ); message.Subject = "Hello!"; message.HtmlBody = "
Greetings 👋🏻 from .NET
"; await _resend.EmailSendAsync( message ); } } ``` -------------------------------- ### Handle Batch Email Errors in Strict and Permissive Modes Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/errors.md This example shows how to handle errors when sending batch emails. Strict mode fails the entire batch on any error, while permissive mode allows partial success. ```csharp var emails = new List { /* ... */ }; // Strict mode (all or nothing) var strictResponse = await client.EmailBatchAsync(emails); if (!strictResponse.Success) { Console.WriteLine($"Batch failed: {strictResponse.Exception.ErrorType}"); } // Permissive mode (partial success) var permissiveResponse = await client.EmailBatchAsync( emails, EmailBatchValidationMode.Permissive); if (permissiveResponse.Success) { var result = permissiveResponse.Content; Console.WriteLine($"Succeeded: {result.Succeeded.Count}"); Console.WriteLine($"Failed: {result.Failed.Count}"); foreach (var failure in result.Failed) { Console.WriteLine($"Error: {failure.Message}"); } } ``` -------------------------------- ### Webhook Validation and Event Processing Example Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/api-reference/webhooks.md Demonstrates how to validate an incoming webhook request using a validator and process the event if validation is successful. It shows accessing event details and handling specific event types like EmailSent. ```csharp var context = await validator.ValidateAsync(request); if (context.IsValid) { var @event = context.Event; Console.WriteLine($"Event type: {@event.EventType}"); Console.WriteLine($"Message ID: {context.MessageId}"); Console.WriteLine($"Timestamp: {context.Timestamp}"); // Process event switch (@event.EventType) { case WebhookEventType.EmailSent: var emailData = @event.DataAs(); Console.WriteLine($"Email sent: {emailData.Email}"); break; } } else { Console.WriteLine($"Validation failed: {context.Exception?.Message}"); } ``` -------------------------------- ### Create Resend Client with Options Object Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/configuration.md Initialize the Resend client by providing a configuration object with API token, API URL, and exception handling preferences. ```csharp var options = new ResendClientOptions { ApiToken = "re_xxx", ApiUrl = "https://api.resend.com", ThrowExceptions = true }; IResend client = ResendClient.Create(options); ``` -------------------------------- ### Validate Webhook in Controller Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/quick-reference.md Example of how to validate an incoming webhook request within an ASP.NET Core controller using the `WebhookValidator`. ```APIDOC ## Validate Webhook in Controller ### Description Example of how to validate an incoming webhook request within an ASP.NET Core controller using the `WebhookValidator`. ### Method ```csharp [HttpPost("/api/webhooks/resend")] public async Task HandleWebhook( [FromServices] WebhookValidator validator, CancellationToken cancellationToken) { Request.EnableBuffering(); var context = await validator.ValidateAsync(Request, cancellationToken); if (!context.IsValid) return Unauthorized(); var @event = context.Event; Console.WriteLine($"Event: {@event.EventType}"); return Ok(); } ``` ### Parameters #### Request Body - **validator** (WebhookValidator) - Injected service for validating webhook requests. - **cancellationToken** (CancellationToken) - Cancellation token for the request. ``` -------------------------------- ### Create a Topic Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/quick-reference.md Creates a new topic for managing subscriptions. Requires a name, description, and default subscription type. ```csharp var data = new TopicData { Name = "Weekly Newsletter", Description = "Product updates and tips", DefaultSubscription = SubscriptionType.OptIn }; var response = await resend.TopicCreateAsync(data); ``` -------------------------------- ### Get Rate Limits Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/quick-reference.md Retrieves rate limit information from the response headers, including remaining requests and reset time. ```APIDOC ## Get Rate Limits ### Description Retrieves rate limit information from the response headers, including remaining requests and reset time. ### Method ```csharp // Assuming 'response' is the result of an API call if (response.Limits != null) { Console.WriteLine($"Remaining: {response.Limits.Remaining}"); Console.WriteLine($"Reset in: {response.Limits.Reset}s"); } ``` ### Response #### Rate Limit Information - **Limits.Remaining** (int) - The number of requests remaining in the current rate limit window. - **Limits.Reset** (int) - The time in seconds until the rate limit window resets. ``` -------------------------------- ### Create Resend Client from Environment Variable Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/configuration.md Initialize the Resend client using the API key stored in the RESEND_API_KEY environment variable. Throws an exception if the variable is not set. ```csharp // Throws if RESEND_API_KEY not set IResend client = ResendClient.Create(); ``` -------------------------------- ### Set Environment Variable and Run Console App Source: https://github.com/resend/resend-dotnet/blob/main/examples/ConsoleCalendar/README.md Demonstrates setting the Resend API token as an environment variable and running the .NET console application. Ensure the API token is set before execution. ```bash > set RESEND_APITOKEN=re_8m9gwsVG_6n94KaJkJ42Yj6qSeVvLq9xF > dotnet run ``` -------------------------------- ### Get Rate Limits from Response Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/quick-reference.md Accesses rate limit information from the response object, including remaining requests and the time until reset. ```csharp if (response.Limits != null) { Console.WriteLine($"Remaining: {response.Limits.Remaining}"); Console.WriteLine($"Reset in: {response.Limits.Reset}s"); } ``` -------------------------------- ### Create Topic Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/api-reference/resend-client.md Creates a new topic with the provided topic data. ```csharp Task> TopicCreateAsync( TopicData topic, CancellationToken cancellationToken = default) ``` -------------------------------- ### Casting Webhook Event Data Example Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/api-reference/webhooks.md Shows how to use the DataAs() method to cast the event data to a specific type, such as EmailEventData, and access its properties. ```csharp if (@event.EventType == WebhookEventType.EmailSent) { var data = @event.DataAs(); Console.WriteLine($"Email: {data.Email}"); Console.WriteLine($"Status: {data.Status}"); } ``` -------------------------------- ### Create ResendClient using Environment Variables Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/configuration.md Create a Resend client instance using static factory methods, automatically picking up the API key from environment variables. ```csharp // Requires RESEND_API_KEY or RESEND_APITOKEN to be set var client = ResendClient.Create(); ``` -------------------------------- ### Configure Resend .NET SDK with Dependency Injection Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/index.md Set up the Resend SDK for use with dependency injection in your .NET application. Configure the API token using environment variables. ```csharp // In Program.cs builder.Services.AddResend(options => { options.ApiToken = Environment.GetEnvironmentVariable("RESEND_API_KEY"); }); // In service public class EmailService { public EmailService(IResend resend) => _resend = resend; } ``` -------------------------------- ### Validate Webhook in Controller Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/quick-reference.md Example of how to validate an incoming webhook request within an ASP.NET Core controller using the WebhookValidator. Ensures the request is legitimate before processing. ```csharp [HttpPost("/api/webhooks/resend")] public async Task HandleWebhook( [FromServices] WebhookValidator validator, CancellationToken cancellationToken) { Request.EnableBuffering(); var context = await validator.ValidateAsync(Request, cancellationToken); if (!context.IsValid) return Unauthorized(); var @event = context.Event; Console.WriteLine($"Event: {@event.EventType}"); return Ok(); } ``` -------------------------------- ### Send Email with Resend .NET SDK Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/index.md Demonstrates basic email sending using the `ResendClient`. Ensure you have the Resend API token. ```csharp using Resend; // Create client var resend = ResendClient.Create("re_xxx"); // Send email var message = new EmailMessage { From = "sender@example.com", Subject = "Hello", TextBody = "Hello, world!" }; message.To.Add("recipient@example.com"); var response = await resend.EmailSendAsync(message); if (response.Success) { Console.WriteLine($"Email sent: {response.Content}"); } ``` -------------------------------- ### Create ResendClient with Options Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/api-reference/resend-client.md Instantiate the ResendClient using explicit configuration options and an optional custom HttpClient. This is useful for providing API tokens and URLs directly. ```csharp var options = new ResendClientOptions { ApiToken = "re_xxx", ApiUrl = "https://api.resend.com" }; var resend = ResendClient.Create(options); ``` -------------------------------- ### Webhook Endpoint in Controller Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/api-reference/webhooks.md Implement a webhook endpoint within a .NET controller to receive and process incoming webhook events. This example demonstrates signature validation and handling different event types. ```csharp [ApiController] [Route("api/webhooks")] public class WebhookController : ControllerBase { private readonly WebhookValidator _validator; private readonly ILogger _logger; public WebhookController( WebhookValidator validator, ILogger logger) { _validator = validator; _logger = logger; } [HttpPost("resend")] public async Task HandleResendWebhook( CancellationToken cancellationToken) { // Enable buffering to read body multiple times Request.EnableBuffering(); // Validate signature var context = await _validator.ValidateAsync(Request, cancellationToken); if (!context.IsValid) { _logger.LogWarning( "Invalid webhook signature: {Error}", context.Exception?.Code); return Unauthorized(); } _logger.LogInformation( "Webhook received: {Type} at {Timestamp}", context.Event.EventType, context.Timestamp); // Handle specific event types await HandleEvent(context.Event); return Ok(); } private async Task HandleEvent(WebhookEvent @event) { switch (@event.EventType) { case WebhookEventType.EmailSent: { var data = @event.DataAs(); _logger.LogInformation( "Email sent to {Email}", data.Email); break; } case WebhookEventType.EmailDelivered: { var data = @event.DataAs(); _logger.LogInformation( "Email delivered to {Email}", data.Email); break; } case WebhookEventType.EmailOpened: { var data = @event.DataAs(); _logger.LogInformation( "Email opened by {Email}", data.Email); break; } case WebhookEventType.EmailBounced: { var data = @event.DataAs(); _logger.LogWarning( "Email bounced for {Email}: {Error}", data.Email, data.Error); break; } case WebhookEventType.ContactCreated: { var data = @event.DataAs(); _logger.LogInformation( "Contact created: {Email}", data.Email); break; } } } } ``` -------------------------------- ### Basic Pagination Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/quick-reference.md Implements basic pagination for fetching lists of resources, using `Limit` and `After` cursor parameters. ```APIDOC ## Basic Pagination ### Description Implements basic pagination for fetching lists of resources, using `Limit` and `After` cursor parameters. ### Method ```csharp var query = new PaginatedQuery { Limit = 20, After = lastCursor }; var response = await resend.EmailListAsync(query); if (response.Success) { var items = response.Content.Data; var hasMore = response.Content.HasMore; } ``` ### Parameters #### Query Parameters - **Limit** (int) - Optional - The maximum number of items to return per page. - **After** (string) - Optional - The cursor for the next page of results. Use the `NextCursor` from a previous response. ### Response #### Success Response - **Content.Data** (List) - A list of items for the current page. - **Content.HasMore** (bool) - Indicates if there are more results available. - **Content.NextCursor** (string) - The cursor for the next page of results. ``` -------------------------------- ### Create Valid Email Attachment in .NET Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/errors.md Ensure email attachments include either 'Content' (byte array) or 'Path' (URL) to be valid. This example shows the correct way to define an attachment. ```csharp // Good var attachment = new EmailAttachment { Filename = "report.pdf", Content = pdfBytes // or Path = "https://example.com/file.pdf" }; // Bad var attachment = new EmailAttachment { Filename = "report.pdf" // Missing both Content and Path }; ``` -------------------------------- ### Unit Test Webhook Validation Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/api-reference/webhooks.md Use this C# code to unit test the validation of incoming webhook payloads. It includes setup for the validator and a test method for deserializing and asserting event details. ```csharp using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.Extensions.Options; using Resend.Webhooks; using System.Threading.Tasks; [TestClass] public class WebhookTests { private WebhookValidator _validator; [TestInitialize] public void Setup() { var options = Options.Create(new WebhookValidatorOptions { Secret = "test_secret" }); _validator = new WebhookValidator(options); } [TestMethod] public void TestWebhookDeserialization() { var payload = @"{ ""type"": ""email.sent"", ""created_at"": ""2024-05-23T12:00:00Z"", ""data"": { ""id"": ""00000000-0000-0000-0000-000000000000"", ""email"": ""test@example.com"", ""status"": ""sent"" } }"; var context = _validator.Validate( CreateMockRequest(), payload); Assert.IsTrue(context.IsValid); var @event = context.Event; Assert.AreEqual(WebhookEventType.EmailSent, @event.EventType); } // Helper method to create a mock request (implementation not shown in original source) private MockHttpRequest CreateMockRequest() { // This is a placeholder. In a real test, you would mock an HttpRequest. return new MockHttpRequest(); } } // Placeholder classes for compilation if not available in the test environment public class MockHttpRequest {} public enum WebhookEventType { EmailSent } public class WebhookValidatorOptions { public string Secret { get; set; } } public class WebhookValidator { public WebhookValidator(Microsoft.Extensions.Options.IOptions options) { /* ... */ } public WebhookValidationContext Validate(MockHttpRequest request, string payload) { /* ... */ return new WebhookValidationContext { IsValid = true, Event = new WebhookEvent { EventType = WebhookEventType.EmailSent } }; } } public class WebhookValidationContext { public bool IsValid { get; set; } public WebhookEvent Event { get; set; } } public class WebhookEvent { public WebhookEventType EventType { get; set; } } ``` -------------------------------- ### Create an API Key Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/quick-reference.md Generates a new API key with specified permissions. The token should be saved immediately as it will not be shown again. ```csharp var response = await resend.ApiKeyCreateAsync( "Production Key", Permission.SendingAccess); Console.WriteLine($"Token: {response.Content.Token}"); // Save immediately! ``` -------------------------------- ### Create Resend Client Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/quick-reference.md Instantiate the Resend client using an API token, an options object, or by reading from an environment variable. ```csharp // 1. With token string var resend = ResendClient.Create("re_xxx"); ``` ```csharp // 2. With options object var options = new ResendClientOptions { ApiToken = "re_xxx" }; var resend = ResendClient.Create(options); ``` ```csharp // 3. From environment variable (RESEND_API_KEY) var resend = ResendClient.Create(); ``` -------------------------------- ### Create Webhook Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/api-reference/resend-client.md Creates a new webhook with the provided webhook data. ```csharp Task> WebhookCreateAsync( WebhookData webhook, CancellationToken cancellationToken = default) ``` -------------------------------- ### Configure DI Container for Resend Webhooks Source: https://github.com/resend/resend-dotnet/blob/main/src/Resend.Webhooks/README.md Configure the Dependency Injection container in your application's startup to use Resend Webhooks. This is a work-in-progress. ```csharp WIP ``` -------------------------------- ### WebhookCreateAsync Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/api-reference/resend-client.md Creates a new webhook subscription. Requires webhook configuration details. ```APIDOC ## WebhookCreateAsync ### Description Creates a webhook. ### Method POST ### Endpoint /webhooks ### Parameters #### Request Body - **webhook** (WebhookData) - Required - The data object for the new webhook. - **cancellationToken** (CancellationToken) - Optional - Token to monitor for cancellation requests. ### Response #### Success Response (200) - **ResendResponse** - Contains the details of the newly created webhook. ``` -------------------------------- ### Create Resend Client with Token String Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/configuration.md A simpler way to create the Resend client by directly passing the API token as a string. ```csharp IResend client = ResendClient.Create("re_xxx"); ``` -------------------------------- ### Paginate Email Lists Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/index.md Illustrates how to retrieve lists of emails with pagination, including setting the limit and checking if more items are available. ```csharp var query = new PaginatedQuery { Limit = 20 }; var response = await resend.EmailListAsync(query); if (response.Success) { var items = response.Content.Data; var hasMore = response.Content.HasMore; } ``` -------------------------------- ### Local Webhook Testing with ngrok Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/api-reference/webhooks.md Use ngrok to expose your local development server to the internet, allowing you to test webhooks by providing a public URL for the Resend service to send events to. ```bash # Start ngrok ngrok http 5000 # Use forwarding URL as webhook endpoint # https://abc123.ngrok.io/api/webhooks/resend ``` -------------------------------- ### Create a Webhook Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/quick-reference.md Creates a new webhook endpoint to receive event notifications. Requires the endpoint URL and a list of events to subscribe to. Remember to store the signing secret securely. ```csharp var data = new WebhookData { Endpoint = "https://example.com/webhooks/resend", Events = new() { WebhookEventType.EmailSent, WebhookEventType.EmailBounced, WebhookEventType.EmailOpened } }; var response = await resend.WebhookCreateAsync(data); // response.Content.SigningSecret = store this securely! ``` -------------------------------- ### List Webhooks Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/quick-reference.md Retrieves a list of all configured webhooks. ```csharp var response = await resend.WebhookListAsync(); var webhooks = response.Content.Data; ``` -------------------------------- ### Configure Resend Client and Sender in DI Source: https://github.com/resend/resend-dotnet/blob/main/src/Resend.FluentEmail/README.md Configure the dependency injection container to use ResendClient and ResendSender. Ensure the Resend API token is set in environment variables. ```csharp using FluentEmail.Core.Interfaces; using Resend; using Resend.FluentEmail; builder.Services.AddOptions(); builder.Services.AddHttpClient(); builder.Services.Configure( o => { o.ApiToken = Environment.GetEnvironmentVariable( "RESEND_APITOKEN" )!; } ); builder.Services.AddTransient(); builder.Services.AddTransient(); ``` -------------------------------- ### Create API Key Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/quick-reference.md Creates a new API key with a specified name and permissions. The token should be saved immediately as it will not be shown again. ```APIDOC ## Create API Key ### Description Creates a new API key with a specified name and permissions. The token should be saved immediately as it will not be shown again. ### Method ```csharp resend.ApiKeyCreateAsync(string name, Permission permission) ``` ### Parameters #### Path Parameters - **name** (string) - Required - The name for the API key (e.g., "Production Key"). - **permission** (Permission) - Required - The permission level for the API key (e.g., `Permission.SendingAccess`). ### Response #### Success Response - **Content.Token** (string) - The generated API key token. Save this immediately. ``` -------------------------------- ### Create Automation Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/api-reference/resend-client.md Creates a new automation with the provided automation data. ```csharp Task> AutomationCreateAsync( AutomationCreateData data, CancellationToken cancellationToken = default) ``` -------------------------------- ### Configure Resend Client Source: https://github.com/resend/resend-dotnet/blob/main/examples/AsyncTemporal/README.md Switches between using the actual Resend client and a mock client that simulates failures for testing purposes. ```csharp // From builder.Services.AddTransient(); // To builder.Services.AddTransient(); ``` -------------------------------- ### Send Email using ResendSender with FluentEmail Source: https://github.com/resend/resend-dotnet/blob/main/src/Resend.FluentEmail/README.md Demonstrates sending an email using FluentEmail, with the ResendSender configured. Includes HTML and plaintext alternative bodies. ```csharp using FluentEmail.Core.Interfaces; public class FeatureImplementation { private readonly ISender _sender; public FeatureImplementation( ISender sender ) { _sender_ = sender; } public async Task Execute() { var email = Email .From( "onboarding@resend.dev" ) .To( "delivered@resend.dev" ) .Subject( "Hello!" ) .Body( "
Greetings 👋🏻 from .NET
", true ) .PlaintextAlternativeBody( "Greetigs from .NET" ); email.Sender = _sender; var response = await email.SendAsync(); } } ``` -------------------------------- ### Integrate Polly for Automatic Retries with Resend Exceptions Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/errors.md This snippet demonstrates how to use the Polly library to automatically retry transient Resend exceptions with exponential backoff. ```csharp var retryPolicy = Policy .Handle(ex => ex.IsTransient) .WaitAndRetryAsync( retryCount: 3, sleepDurationProvider: attempt => { var baseDelay = Math.Pow(2, attempt); return TimeSpan.FromSeconds(baseDelay); }, onRetry: (outcome, delay, count, context) => { var ex = outcome.InnerException as ResendException; Console.WriteLine($"Attempt {count} failed, retrying in {delay.TotalSeconds}s"); }); var client = ResendClient.Create("re_xxx"); var result = await retryPolicy.ExecuteAsync( async () => await client.EmailSendAsync(message)); ``` -------------------------------- ### Basic Pagination Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/quick-reference.md Implements basic pagination for API requests by specifying a limit and an optional cursor for 'after'. Useful for retrieving data in chunks. ```csharp var query = new PaginatedQuery { Limit = 20, After = lastCursor }; var response = await resend.EmailListAsync(query); if (response.Success) { var items = response.Content.Data; var hasMore = response.Content.HasMore; } ``` -------------------------------- ### Add Resend Service with Options Configuration Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/api-reference/resend-client.md Configures the `IResend` service for dependency injection using an action to set `ResendClientOptions`. ```csharp public static IHttpClientBuilder AddResend( this IServiceCollection services, Action configureOptions) ``` -------------------------------- ### Create a Broadcast Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/quick-reference.md Creates a new broadcast campaign. Requires a name, segment ID, sender email, subject, and HTML body. ```csharp var data = new BroadcastData { Name = "Summer Sale", SegmentId = segmentId, From = "marketing@example.com", Subject = "50% Off This Weekend!", HtmlBody = "

Summer Sale

" }; var response = await resend.BroadcastAddAsync(data); var broadcastId = response.Content; ``` -------------------------------- ### Automation Summary Class Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/types.md Provides a lightweight summary of an automation. ```csharp public class AutomationSummary { public Guid Id { get; set; } public string Name { get; set; } public string Status { get; set; } public DateTime MomentCreated { get; set; } public DateTime MomentUpdated { get; set; } } ``` -------------------------------- ### Create Topic Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/quick-reference.md Creates a new topic for managing contact subscriptions, with options for name, description, and default subscription type. ```APIDOC ## Create Topic ### Description Creates a new topic for managing contact subscriptions, with options for name, description, and default subscription type. ### Method ```csharp resend.TopicCreateAsync(TopicData data) ``` ### Parameters #### Request Body - **data** (TopicData) - Required - An object containing the topic details. - **Name** (string) - Required - The name of the topic. - **Description** (string) - Optional - A description for the topic. - **DefaultSubscription** (SubscriptionType) - Optional - The default subscription type for the topic (e.g., OptIn, OptOut). ``` -------------------------------- ### Configure HTTP Client with Dependency Injection Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/configuration.md Customize the HTTP client used by the Resend SDK when integrating with ASP.NET Core's dependency injection. Set timeouts and default headers. ```csharp builder.Services.AddResend("re_xxx") .ConfigureHttpClient(http => { http.Timeout = TimeSpan.FromSeconds(60); http.DefaultRequestHeaders.Add("User-Agent", "MyApp/1.0"); }); ``` -------------------------------- ### Automation Run Summary Class Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/types.md Provides a summary of an automation run. ```csharp public class AutomationRunSummary { public Guid Id { get; set; } public Guid AutomationId { get; set; } public Guid ContactId { get; set; } public string Status { get; set; } public DateTime MomentCreated { get; set; } public DateTime? MomentCompleted { get; set; } } ``` -------------------------------- ### AutomationCreateAsync Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/api-reference/resend-client.md Creates a new automation. Requires automation data including triggers and actions. ```APIDOC ## AutomationCreateAsync ### Description Creates a new automation. ### Method POST ### Endpoint /automations ### Parameters #### Request Body - **data** (AutomationCreateData) - Required - The data object for the new automation. - **cancellationToken** (CancellationToken) - Optional - Token to monitor for cancellation requests. ### Response #### Success Response (200) - **ResendResponse** - Contains the unique identifier of the newly created automation. ``` -------------------------------- ### List Webhooks Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/quick-reference.md Retrieves a list of all configured webhooks. ```APIDOC ## List Webhooks ### Description Retrieves a list of all configured webhooks. ### Method ```csharp resend.WebhookListAsync() ``` ### Response #### Success Response - **Content.Data** (List) - A list of webhook objects. ``` -------------------------------- ### List API Keys Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/quick-reference.md Retrieves a list of all API keys associated with your account. ```csharp var response = await resend.ApiKeyListAsync(); var keys = response.Content; ``` -------------------------------- ### ApiKeyCreateAsync Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/api-reference/resend-client.md Creates a new API key with optional permissions and domain restrictions. ```APIDOC ## ApiKeyCreateAsync ### Description Create a new API key. ### Method POST ### Endpoint /api-keys ### Parameters #### Request Body - **keyName** (string) - Required - Display name for the key - **permission** (Permission) - Optional - `FullAccess` or `SendingAccess` - **domainId** (Guid) - Optional - Restrict key to specific domain ### Request Example ```csharp var response = await resend.ApiKeyCreateAsync("Production Key", Permission.SendingAccess); ``` ### Response #### Success Response (200) - **content** (ApiKeyData) - An object containing the newly created API key's token and details. The token is only available at creation. ``` -------------------------------- ### Configure Resend with Dependency Injection Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/quick-reference.md Register the Resend client with the .NET dependency injection system, either directly with a token or via configuration. ```csharp // In Program.cs builder.Services.AddResend("re_xxx"); // Or with configuration builder.Services.AddResend(options => { options.ApiToken = Environment.GetEnvironmentVariable("RESEND_API_KEY"); }); // In service/controller public MyService(IResend resend) { } ``` -------------------------------- ### Configure Resend API Key using User Secrets (Development) Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/configuration.md Set the Resend API key using the `dotnet user-secrets` command for local development and access it via configuration. ```bash # Set secret dotnet user-secrets set "Resend:ApiToken" "re_xxx" ``` ```csharp builder.Services.AddResend(options => { options.ApiToken = builder.Configuration["Resend:ApiToken"]; }); ``` -------------------------------- ### List All API Keys Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/api-reference/resend-client.md Retrieves a list of all API keys associated with your Resend account. ```csharp Task>> ApiKeyListAsync( CancellationToken cancellationToken = default) ``` -------------------------------- ### List Event Definitions Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/api-reference/resend-client.md Lists all available event definitions. Supports pagination via an optional query parameter. ```csharp Task>> EventListAsync( PaginatedQuery? query = null, CancellationToken cancellationToken = default) ``` -------------------------------- ### Publish an Email Template Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/quick-reference.md Make a created or updated email template active and ready for use. ```csharp await resend.TemplatePublishAsync(templateId); ``` -------------------------------- ### Create a New API Key Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/api-reference/resend-client.md Generates a new API key with a specified name and optional permissions or domain restrictions. The token is only available at creation. ```csharp Task> ApiKeyCreateAsync( string keyName, Permission? permission = null, Guid? domainId = null, CancellationToken cancellationToken = default) ``` ```csharp var response = await resend.ApiKeyCreateAsync( "Production Key", Permission.SendingAccess); if (response.Success) { Console.WriteLine($"Token: {response.Content.Token}"); } ``` -------------------------------- ### ResendClient Static Factory Methods Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/api-reference/resend-client.md Provides static methods to create instances of the ResendClient, allowing for flexible configuration via options, API token, or environment variables. ```APIDOC ## Create with Options ### Description Creates a `ResendClient` instance using provided `ResendClientOptions` and an optional `HttpClient`. ### Method Signature `public static IResend Create(ResendClientOptions options, HttpClient? http = null)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```csharp var options = new ResendClientOptions { ApiToken = "re_xxx", ApiUrl = "https://api.resend.com" }; var resend = ResendClient.Create(options); ``` ## Create with API Token ### Description Creates a `ResendClient` instance using only the Resend API token. ### Method Signature `public static IResend Create(string apiToken)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```csharp var resend = ResendClient.Create("re_xxx"); ``` ## Create from Environment ### Description Creates a `ResendClient` instance using the `RESEND_API_KEY` environment variable. ### Method Signature `public static IResend Create()` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Throws `InvalidOperationException` if `RESEND_API_KEY` environment variable is not set ### Request Example ```csharp // Requires RESEND_API_KEY environment variable var resend = ResendClient.Create(); ``` ``` -------------------------------- ### List All User Domains Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/api-reference/resend-client.md Retrieve a list of all domains authenticated under the user's account. This is useful for managing and verifying domain configurations. ```csharp Task>> DomainListAsync( CancellationToken cancellationToken = default) ``` ```csharp var response = await resend.DomainListAsync(); if (response.Success) { var domains = response.Content; } ``` -------------------------------- ### ApiKeyListAsync Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/api-reference/resend-client.md Lists all API keys associated with the account. ```APIDOC ## ApiKeyListAsync ### Description List all API keys for the account. ### Method GET ### Endpoint /api-keys ### Response #### Success Response (200) - **content** (List) - A list of API key objects. ``` -------------------------------- ### List Topics Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/api-reference/resend-client.md Retrieves a paginated list of topics. Optional query parameters can be provided for filtering and pagination. ```csharp Task>> TopicListAsync( PaginatedQuery? query = null, CancellationToken cancellationToken = default) ``` -------------------------------- ### AddResend Extension with HttpClient Configuration Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/configuration.md Configure the Resend service and its underlying HttpClient using the AddResend extension. Allows for custom timeouts or Polly policies. ```csharp builder.Services.AddResend("re_xxx") .ConfigureHttpClient(client => { client.Timeout = TimeSpan.FromSeconds(30); }) .AddPolicyHandler(/* your Polly policy */); ``` -------------------------------- ### Verify a Domain Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/quick-reference.md Verifies a domain that has already been added and had its DNS records configured. Requires the domain ID. ```csharp await resend.DomainVerifyAsync(domainId); ``` -------------------------------- ### List Email Templates Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/api-reference/resend-client.md Lists email templates with pagination support. Requires a PaginatedQuery object. ```csharp Task>> TemplateListAsync( PaginatedQuery? query = null, CancellationToken cancellationToken = default) ``` -------------------------------- ### Import Webhooks Namespace Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/api-reference/webhooks.md Import the necessary namespace for webhook integration in your C# project. ```csharp using Resend.Webhooks; ``` -------------------------------- ### API Key Creation Response Class Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/types.md Response structure when creating an API key. The token is only available at the time of creation. ```csharp public class ApiKeyData { public Guid Id { get; set; } public string Token { get; set; } } ``` -------------------------------- ### Try-Catch with Exceptions Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/quick-reference.md Demonstrates how to handle potential exceptions during API calls using a try-catch block. It checks for transient exceptions to determine if a retry is safe. ```APIDOC ## Try-Catch with Exceptions ### Description Demonstrates how to handle potential exceptions during API calls using a try-catch block. It checks for transient exceptions to determine if a retry is safe. ### Method ```csharp try { await resend.EmailSendAsync(message); } catch (ResendException ex) { if (ex.IsTransient) { // Safe to retry await Task.Delay(1000); } else { // Log and handle Console.WriteLine($"{ex.ErrorType}: {ex.Message}"); } } ``` ### Parameters #### Exception Handling - **ResendException** - Catches exceptions specific to the Resend API. - **IsTransient** (bool) - Indicates if the error is temporary and safe to retry. - **ErrorType** (string) - The type of error that occurred. - **Message** (string) - A descriptive message about the error. ``` -------------------------------- ### Create Email Template Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/api-reference/resend-client.md Creates a new email template. Requires TemplateData. ```csharp Task> TemplateCreateAsync( TemplateData template, CancellationToken cancellationToken = default) ``` -------------------------------- ### TopicCreateAsync Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/api-reference/resend-client.md Creates a new topic within the Resend platform. Requires topic data including name and configuration. ```APIDOC ## TopicCreateAsync ### Description Creates a new topic. ### Method POST ### Endpoint /topics ### Parameters #### Request Body - **topic** (TopicData) - Required - The data object for the new topic. - **cancellationToken** (CancellationToken) - Optional - Token to monitor for cancellation requests. ### Response #### Success Response (200) - **ResendResponse** - Contains the unique identifier of the newly created topic. ``` -------------------------------- ### Configure ResendClient for Production Source: https://github.com/resend/resend-dotnet/blob/main/examples/AsyncHangfire/README.md Configures the application to use the actual ResendClient for sending emails. This is typically used in production environments. ```csharp // From builder.Services.AddTransient(); ``` -------------------------------- ### Verify Sender Address for Resend Emails Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/errors.md Illustrates correct and incorrect formats for the 'From' address to avoid `InvalidFromAddress` errors, emphasizing the need for a verified domain. ```csharp // Good message.From = "noreply@example.com"; // verified domain message.From = "John Doe "; // Bad message.From = "invalid@.com"; // invalid format message.From = "test@unverified.com"; // unverified domain ``` -------------------------------- ### Publish Template by ID or Alias Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/api-reference/resend-client.md Use this method to publish a template. You can identify the template by its ID or alias. ```csharp Task TemplatePublishAsync( Guid templateId, CancellationToken cancellationToken = default) Task TemplatePublishAsync( string templateAlias, CancellationToken cancellationToken = default) ``` -------------------------------- ### List Automation Runs Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/api-reference/resend-client.md Lists runs for a given automation ID. An optional query can be provided for pagination. ```csharp Task>> AutomationRunListAsync( Guid automationId, AutomationRunListQuery? query = null, CancellationToken cancellationToken = default) ``` -------------------------------- ### List Automations Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/api-reference/resend-client.md Retrieves a paginated list of automations with support for filtering. Optional query parameters can be provided. ```csharp Task>> AutomationListAsync( AutomationListQuery? query = null, CancellationToken cancellationToken = default) ``` -------------------------------- ### Create a New Email Template Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/quick-reference.md Define and create a new email template with a name, alias, sender, subject, and body content. The response contains the new template ID. ```csharp var data = new TemplateData { Name = "Order Confirmation", Alias = "order-confirmation", From = "orders@example.com", Subject = "Order {{order_id}} confirmed", HtmlBody = "

Thank you {{customer_name}}!

" }; var response = await resend.TemplateCreateAsync(data); var templateId = response.Content; ``` -------------------------------- ### TemplateCreateAsync Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/api-reference/resend-client.md Creates a new email template. Requires template data. ```APIDOC ## TemplateCreateAsync ### Description Creates a new email template. ### Method Not applicable (SDK method) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **template** (TemplateData) - Required - The data for the new template. ### Request Example ```csharp var templateData = new TemplateData { Name = "WelcomeEmail", Subject = "Welcome!" }; var templateId = await resendClient.Templates.TemplateCreateAsync(templateData); ``` ### Response #### Success Response - **ResendResponse** - Contains the ID of the newly created template. #### Response Example (Success response structure depends on ResendResponse definition) ``` -------------------------------- ### List API Keys Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/quick-reference.md Retrieves a list of all API keys associated with the account. ```APIDOC ## List API Keys ### Description Retrieves a list of all API keys associated with the account. ### Method ```csharp resend.ApiKeyListAsync() ``` ### Response #### Success Response - **Content** (List) - A list of API key objects. ``` -------------------------------- ### Add Resend Service with API Token Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/api-reference/resend-client.md Configures the `IResend` service for dependency injection using an API token string. ```csharp public static IHttpClientBuilder AddResend( this IServiceCollection services, string apiToken) ``` -------------------------------- ### EventListAsync Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/api-reference/resend-client.md Lists all available event definitions, with support for pagination. ```APIDOC ## EventListAsync ### Description List event definitions. ### Method Not Applicable (SDK Method) ### Parameters #### Query Parameters - **query** (PaginatedQuery) - Optional - Query parameters for pagination. - **cancellationToken** (CancellationToken) - Optional - Token to monitor for cancellation requests. ``` -------------------------------- ### Handling Binary Attachments Source: https://github.com/resend/resend-dotnet/blob/main/docs/README.md Construct EmailAttachment for binary files by reading all bytes from the file. ```csharp // Binary attachment var bin = new EmailAttachment() { Filename = "image.png", Content = File.ReadAllBytes( "image.png" ), ContentType = "image/png", }; ``` -------------------------------- ### List Contact Topic Subscriptions Source: https://github.com/resend/resend-dotnet/blob/main/_autodocs/api-reference/resend-client.md Lists all topic subscriptions for a given contact. Supports pagination. ```csharp Task>> ContactListTopicsAsync( Guid contactId, PaginatedQuery? query = null, CancellationToken cancellationToken = default) ```