Skip to content
Last updated

C# / .NET SDK

The official .NET wrapper for the Mailjet API is published on NuGet as Mailjet.Api and developed on GitHub at mailjet/mailjet-apiv3-dotnet.

Current release: 4.0.1

Compatibility

Since 4.0.0 the library targets .NET Standard 2.0, which reduces the dependency surface and removes the security warnings raised by the older .NET Framework target.

RuntimeMinimum version
.NET5.0
.NET Core2.0
.NET Framework4.6.2
Mono5.4
Xamarin.iOS10.14
Xamarin.Android8.0
Universal Windows Platform10.0.16299

Dependencies:

  • NETStandard.Library >= 2.0.3
  • Newtonsoft.Json >= 13.0.4

Note: release 4.0.1 fixes a MissingMethodException on PostAsync / PutAsync that occurred when an older Newtonsoft.Json (13.0.0–13.0.3) was resolved at runtime instead of 13.0.4. If you pin Newtonsoft.Json in your project, make sure the runtime actually loads 13.0.4 or later.

Installation

PM> Install-Package Mailjet.Api

Or clone the repository directly if you need to build from source.

Authentication

The Email API authenticates with your API key and secret. Store them outside of your code — for example as machine-level environment variables:

setx -m MJ_APIKEY_PUBLIC "your API key"
setx -m MJ_APIKEY_PRIVATE "your API secret"
MailjetClient client = new MailjetClient(
    Environment.GetEnvironmentVariable("MJ_APIKEY_PUBLIC"),
    Environment.GetEnvironmentVariable("MJ_APIKEY_PRIVATE"));

The SMS API uses a bearer token instead — see SMS API.

Send your first email

TransactionalEmailBuilder builds a strongly typed message, so you get compile-time checking instead of hand-assembled JSON.

using Mailjet.Client;
using Mailjet.Client.TransactionalEmails;
using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        var client = new MailjetClient(
            Environment.GetEnvironmentVariable("MJ_APIKEY_PUBLIC"),
            Environment.GetEnvironmentVariable("MJ_APIKEY_PRIVATE"));

        var email = new TransactionalEmailBuilder()
            .WithFrom(new SendContact("pilot@example.com", "Mailjet Pilot"))
            .WithTo(new SendContact("passenger@example.com", "Passenger 1"))
            .WithSubject("Your email flight plan!")
            .WithHtmlPart("<h3>Dear passenger, welcome to Mailjet!</h3>")
            .WithTextPart("Dear passenger, welcome to Mailjet!")
            .Build();

        var response = await client.SendTransactionalEmailAsync(email);

        Console.WriteLine($"Messages accepted: {response.Messages.Length}");
    }
}

Client and call configuration

API versioning

The Mailjet API spans three versions:

VersionScope
v3Email API
v3.1Send API v3.1 (latest send version)
v4SMS API, contact delete API

You do not need to configure this. Since 2.0.0 the client derives the required version from the resource you call.

Base URL

The default base domain is https://api.mailjet.com. Override it with the BaseAdress property:

var client = new MailjetClient(
    Environment.GetEnvironmentVariable("MJ_APIKEY_PUBLIC"),
    Environment.GetEnvironmentVariable("MJ_APIKEY_PRIVATE"))
{
    BaseAdress = "https://api.us.mailjet.com",
};

Accounts on Mailjet's US architecture must set https://api.us.mailjet.com.

Dependency injection

MailjetClient supports IHttpClientFactory and can be registered as a typed client:

services.AddHttpClient<IMailjetClient, MailjetClient>(client =>
{
    // sets BaseAddress, MediaType and UserAgent
    client.SetDefaultSettings();

    client.UseBasicAuthentication("apiKey", "apiSecret");
    // or, for the SMS API:
    // client.UseBearerAuthentication("access_token");
});

Then inject IMailjetClient where you need it:

public class EmailService : IEmailService
{
    private readonly IMailjetClient _mailjetClient;

    public EmailService(IMailjetClient mailjetClient)
    {
        _mailjetClient = mailjetClient;
    }
}

Because sending lives on the client itself (rather than on extension methods), IMailjetClient can be mocked in unit tests.

Proxy

Pass a configured HttpClientHandler to the constructor:

var proxy = new WebProxy
{
    // even for an HTTPS proxy the address starts with http
    Address = new Uri("http://51.79.0.0:8080"),
    UseDefaultCredentials = false,
    // Credentials = new NetworkCredential("user", "password"),
};

var handler = new HttpClientHandler { Proxy = proxy };

var client = new MailjetClient(
    Environment.GetEnvironmentVariable("MJ_APIKEY_PUBLIC"),
    Environment.GetEnvironmentVariable("MJ_APIKEY_PRIVATE"),
    handler);

Request examples

Every request is a MailjetRequest carrying a Resource, an optional ResourceId, properties and filters. The full list of resources lives in /Mailjet.Client/Resources.

POST — create an object

var request = new MailjetRequest
{
    Resource = Contact.Resource,
}
    .Property(Contact.Email, "passenger@example.com")
    .Property(Contact.IsExcludedFromCampaigns, "false")
    .Property(Contact.Name, "New Contact");

MailjetResponse response = await client.PostAsync(request);

if (response.IsSuccessStatusCode)
{
    Console.WriteLine($"Total: {response.GetTotal()}, Count: {response.GetCount()}");
    Console.WriteLine(response.GetData());
}
else
{
    Console.WriteLine($"StatusCode: {response.StatusCode}");
    Console.WriteLine($"ErrorInfo: {response.GetErrorInfo()}");
    Console.WriteLine($"ErrorMessage: {response.GetErrorMessage()}");
}

POST — endpoints with an action

Action endpoints have their own resource object. /contact/{id}/managecontactslists maps to ContactManagecontactslists:

var request = new MailjetRequest
{
    Resource = ContactManagecontactslists.Resource,
    ResourceId = ResourceId.Numeric(contactId)
}
    .Property(ContactManagecontactslists.ContactsLists, new JArray {
        new JObject {
            { "ListID", listId1 },
            { "Action", "addnoforce" }
        },
        new JObject {
            { "ListID", listId2 },
            { "Action", "addforce" }
        }
    });

MailjetResponse response = await client.PostAsync(request);

GET — all objects

var request = new MailjetRequest
{
    Resource = Contact.Resource,
};

MailjetResponse response = await client.GetAsync(request);

GET — with filters

var request = new MailjetRequest
{
    Resource = Contact.Resource,
}
    .Filter(Contact.IsExcludedFromCampaigns, "false");

MailjetResponse response = await client.GetAsync(request);

GET — a single object

Set ResourceId to target one object. Numeric IDs use ResourceId.Numeric, and resources that accept an email address (such as contact) use ResourceId.Alphanumeric:

var byId = new MailjetRequest
{
    Resource = Contact.Resource,
    ResourceId = ResourceId.Numeric(contactId)
};

var byEmail = new MailjetRequest
{
    Resource = Contact.Resource,
    ResourceId = ResourceId.Alphanumeric("passenger@example.com")
};

PUT — update an object

A PUT in the Mailjet API behaves like a PATCH: only the properties you send are updated, everything else is left untouched, and non-mandatory properties can be omitted.

var request = new MailjetRequest
{
    Resource = Contactdata.Resource,
    ResourceId = ResourceId.Numeric(contactId)
}
    .Property(Contactdata.Data, new JArray {
        new JObject {
            { "first_name", "John" },
            { "last_name", "Smith" }
        }
    });

MailjetResponse response = await client.PutAsync(request);

DELETE — remove an object

A successful DELETE returns 204 No Content with no response body.

var request = new MailjetRequest
{
    Resource = Template.Resource,
    ResourceId = ResourceId.Numeric(templateId)
};

MailjetResponse response = await client.DeleteAsync(request);

Response object

GetAsync, PostAsync, PutAsync and DeleteAsync all return a MailjetResponse:

MemberReturns
IsSuccessStatusCodewhether the call succeeded
StatusCodeHTTP status code (200, 400, …)
GetData()the Data property of the JSON payload, or the full payload if there is none
GetTotal()total number of matching objects
GetCount()number of objects returned in this response
GetErrorInfo()HTTP reason phrase ("OK", "Bad Request", …)
GetErrorMessage()error reason from the API response payload

SMS API

SMS endpoints authenticate with a bearer token generated in the SMS section of your account. Pass the token as the only constructor argument:

using Mailjet.Client;
using Mailjet.Client.Resources.SMS;

var client = new MailjetClient(Environment.GetEnvironmentVariable("MJ_API_TOKEN"));

var request = new MailjetRequest
{
    Resource = Send.Resource,
}
    .Property(Send.From, "MJPilot")
    .Property(Send.To, "+33600000000")
    .Property(Send.Text, "Have a nice SMS flight with Mailjet!");

MailjetResponse response = await client.PostAsync(request);

Release notes

VersionChanges
4.0.1Fixes MissingMethodException on PostAsync/PutAsync with Newtonsoft.Json 13.0.0–13.0.3 loaded at runtime
4.0.0Breaking: target framework moved to .NET Standard 2.0
3.0.1Renames TemplateErrorDelivery to TemplateErrorDeliver; fixes TransactionalEmailBuilder validation; handles a null Messages property
3.0.0Breaking: removes extension methods such as SendTransactionalEmailAsync from the extension class
2.1.0Bumps Newtonsoft.Json; drops the .NET Framework target; moves SendTransactionalEmailAsync onto the client so it can be mocked
2.0.0Adds TransactionalEmailBuilder and typed models, the GDPR contact delete API, automatic version resolution, and a strong-named assembly

More examples

Contribute

The wrapper is open source. Fork the repository, branch, implement your fix or feature, document it, and open a pull request at mailjet/mailjet-apiv3-dotnet. Documentation improvements belong in the API documentation repo.