Skip to the documentation
C#

Changelog

Every release of the package, newest first.

0.0.1

The first release of the .NET SDK, the Nextmail package on NuGet. It targets net8.0 and netstandard2.0, is safe to trim and to compile ahead of time, and on .NET 8 and later it has no dependencies. It has a method for each of the 684 methods of the TypeScript SDK, in the same 53 namespaces and under the same names in PascalCase with an Async suffix. They cover everything from sending and reading mail to contacts, broadcasts, automations, the calendar, booking pages, tasks and the settings of a workspace, and a parity check proves that each one sends the same request as its TypeScript twin.

  • new NextmailClient() reads NEXTMAIL_API_KEY, NEXTMAIL_ACCESS_TOKEN and NEXTMAIL_BASE_URL, and NextmailOptions takes ApiKey, AccessToken, AccessTokenProvider, BaseUrl, Timeout, MaxRetries, HttpClient, UserAgent and Headers. The client has a property for every namespace, such as Emails, Threads and Domains, and it is safe to share between threads.
  • Every method is asynchronous, ends in Async and takes a CancellationToken last. A request body is a Body, or any IReadOnlyDictionary<string, object?>, whose keys keep the camelCase names of the API, and a Body goes out in the order its keys were added. Options are named arguments such as limit:, cursor: and idempotencyKey:, and a response comes back as a JsonObject.
  • Every paginated resource has ListAsync, which returns one Page, ListAllAsync, which returns every item, and IterateAsync, which returns an IAsyncEnumerable<JsonObject> that fetches the next page only when it gets there.
  • An API refusal throws NextmailApiException, with Status, ErrorType, Code, Param, RequestId and checks such as IsValidation, IsNotFound and IsStepUpRequired to use in a when filter. No response at all throws NextmailNetworkException, with IsTimeout when the deadline passed, and both derive from NextmailException. A mistake in the call itself throws ArgumentException before anything is sent.
  • Reads, sends and every write that is safe to repeat are retried on 408, 500, 502, 503 and 504 with backoff, and on a 429 only when its Retry-After is a minute or less. Every send carries an idempotency key that its retries reuse, and idempotencyKey: sets your own.
  • AccessToken takes an OAuth access token, and AccessTokenProvider a function that returns one before every request, so the token can be renewed without a new client. When a change made with a token needs a verification code, the call throws with IsStepUpRequired, and Security.BeginStepUpAsync and VerifyStepUpAsync provide one.
  • NextmailClient.VerifyWebhookSignature() checks a webhook delivery in constant time, refuses one more than five minutes old and returns the event.
  • NextmailClient.CreateTempMail() opens disposable inboxes with no credential, and client.Raw.RequestAsync() calls an endpoint no method wraps, with the credential, timeout and retries of the client.
  • NextmailClient.ToBase64(), IsApiKey(), IsAccessToken(), IsSealed(), ResolveLanguage(), LanguageByCode() and IsRtlLanguage() are the helpers of the TypeScript SDK, and every set of values the API uses is a class in Nextmail.Constants.
  • The client sends a credential over plain http: only to a server on this machine, refuses a request path that leaves the API origin and never prints a credential. It never disposes an HttpClient it was handed, and shares one for the whole process when given none.