---
title: "Install"
description: "One NuGet package for .NET 8 and later and for .NET Standard 2.0, with no dependencies on .NET 8."
url: "https://openemail.uk/docs/csharp/install"
area: "C#"
category: "Getting started"
---

# Install

One NuGet package for .NET 8 and later and for .NET Standard 2.0, with no dependencies on .NET 8.

## Install

> The current release is `0.0.1`. It has a method for every method of the TypeScript SDK, and the parity check of the package fails the build when one goes missing or sends a different request.

**Install**

_.NET CLI_

```bash
dotnet add package OpenEmail
```

**Program.cs**

```
using OpenEmail;

var client = new OpenEmailClient();

var sent = await client.Emails.SendAsync(new Body
{
    ["from"] = "Acme Billing <billing@acme.com>",
    ["to"] = "ada@example.com",
    ["subject"] = "Your September invoice",
    ["html"] = "<p>Invoice attached.</p>",
});

Console.WriteLine($"{sent["id"]} {sent["status"]}");
```

`new OpenEmailClient()` reads the key from `OPENEMAIL_API_KEY`, so the code holds no credential. Pass `new OpenEmailOptions { ApiKey = ... }` when your configuration lives somewhere else. A missing or malformed key throws `ArgumentException` when the client is built, before anything is sent.

A request body is a `Body`, or any `IReadOnlyDictionary<string, object?>`, whose keys keep the names of the API, so `scheduledAt` is written the same way here as in the API reference. A response is a `JsonObject` from `System.Text.Json.Nodes`, read with `sent["id"]`.

> `SendAsync` returning does not mean the message has gone. A scheduled or cancellable send comes back `queued` or `scheduled` and settles later. Read `status`, not the fact that the call returned.

## Try it in one file

On .NET 10 one file runs without a project. The `#:package` line fetches the package, and `dotnet run send.cs` sends the message.

**send.cs**

```
#:package OpenEmail@*

using OpenEmail;

var client = new OpenEmailClient();

var sent = await client.Emails.SendAsync(new Body
{
    ["from"] = "billing@acme.com",
    ["to"] = "ada@example.com",
    ["subject"] = "Sent from one file",
    ["text"] = "No project was needed.",
});

Console.WriteLine(sent["id"]);
```

## Where it runs

The package targets `net8.0` and `netstandard2.0`. On .NET 8 and later it has no dependencies, and it is safe to trim and to compile ahead of time. On .NET Standard 2.0 it brings `System.Text.Json` and `Microsoft.Bcl.AsyncInterfaces`. A client is safe to use from many threads at once: build one when the program starts and share it.

> The client carries a workspace API key that can send mail and read the mailbox, so it belongs on a server, in a job or in a tool that runs on your own machine. Keep the key in an environment variable or your framework’s secrets, never in code.
