Developer Guide · C# / .NET

How to add e-signatures
in C# (.NET)

Add legally binding e-signatures to a .NET app in four steps using HttpClient and MultipartFormDataContent: get a token, create an envelope, send the signing link, and handle the completion webhook in ASP.NET Core. No NuGet package required.

Get free API keys →
1

Get a bearer token

Exchange your OAuth2 client credentials for a short-lived access token using .NET's built-in HttpClient — no NuGet package needed.

csharp
using System.Net.Http;
using System.Text.Json;

var http = new HttpClient();

var tokenResp = await http.PostAsync(
    "https://api.getsigned.app/oauth/token",
    new FormUrlEncodedContent(new Dictionary<string, string> {
        ["grant_type"]    = "client_credentials",
        ["client_id"]     = Environment.GetEnvironmentVariable("GETSIGNED_CLIENT_ID")!,
        ["client_secret"] = Environment.GetEnvironmentVariable("GETSIGNED_CLIENT_SECRET")!,
    })
);

var tokenDoc = JsonDocument.Parse(await tokenResp.Content.ReadAsStringAsync());
var token    = tokenDoc.RootElement.GetProperty("access_token").GetString()!;
2

Create an envelope

Upload the PDF and declare signers and fields with MultipartFormDataContent — the .NET equivalent of a multipart/form-data request.

csharp
var pdfBytes = await File.ReadAllBytesAsync("nda.pdf");

var signers = JsonSerializer.Serialize(new[] {
    new { name = "Jamie", email = "jamie@client.io" }
});
var fields = JsonSerializer.Serialize(new[] {
    new { type = "signature", page = 1, x = 420, y = 580 }
});

using var form = new MultipartFormDataContent();
form.Add(new ByteArrayContent(pdfBytes)
    { Headers = { ContentType = new("application/pdf") } },
    "document", "nda.pdf");
form.Add(new StringContent(signers), "signers");
form.Add(new StringContent(fields),  "fields");

http.DefaultRequestHeaders.Authorization =
    new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);

var envResp = await http.PostAsync(
    "https://api.getsigned.app/v1/envelopes", form);
var envDoc  = JsonDocument.Parse(await envResp.Content.ReadAsStringAsync());
var envId   = envDoc.RootElement.GetProperty("id").GetString()!;
3

Send for signing

Sending generates a tokenized, single-use link per signer and emails it. Signers verify identity with email/SMS OTP.

csharp
await http.PostAsync(
    $"https://api.getsigned.app/v1/envelopes/{envId}/send",
    null
);
4

Handle the completion webhook

When the last signer finishes, GetSigned POSTs envelope.completed to your ASP.NET Core endpoint. Verify the HMAC-SHA256 signature before trusting the payload.

csharp
// Program.cs — minimal API
app.MapPost("/webhooks/getsigned", async (HttpRequest req) =>
{
    using var reader = new StreamReader(req.Body);
    var raw = await reader.ReadToEndAsync();   // raw body, before parsing
    var sig = req.Headers["X-GetSigned-Signature"].ToString();

    var secret = Environment.GetEnvironmentVariable("GETSIGNED_WEBHOOK_SECRET")!;
    using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret));
    var expected = Convert.ToHexString(
        hmac.ComputeHash(Encoding.UTF8.GetBytes(raw))).ToLowerInvariant();
    // FixedTimeEquals is constant-time
    if (!CryptographicOperations.FixedTimeEquals(
            Encoding.UTF8.GetBytes(expected), Encoding.UTF8.GetBytes(sig)))
        return Results.Unauthorized();

    using var doc = JsonDocument.Parse(raw);
    var root = doc.RootElement;

    if (root.TryGetProperty("event", out var evProp)
        && evProp.GetString() == "envelope.completed")
    {
        var envelopeId = root.GetProperty("envelope_id").GetString();
        // GET /v1/envelopes/{envelopeId}/document -> sealed PDF
        // Persist, notify parties, update your database, etc.
    }

    return Results.Ok();
});

Frequently asked questions

How do I add e-signatures in C# (.NET)?

Use .NET's built-in HttpClient and MultipartFormDataContent to call the GetSigned REST API: POST client credentials to /oauth/token for a bearer token, create an envelope by uploading a PDF with signers and fields as a multipart request, send it to generate signing links, then handle the envelope.completed webhook in ASP.NET Core (minimal API or controller). No NuGet package is required.

Do I need a NuGet package for multipart file uploads in .NET?

No. .NET's built-in MultipartFormDataContent (System.Net.Http) handles multipart/form-data natively. Add ByteArrayContent for the PDF file and StringContent for JSON-encoded signers and fields. No Refit, RestSharp, or other HTTP library is needed for a three-endpoint integration.

How do I register HttpClient in ASP.NET Core dependency injection?

Register it in Program.cs: builder.Services.AddHttpClient<GetSignedService>() where GetSignedService is a typed client that encapsulates the token, envelope creation, and send calls. This gives you lifetime management, connection pooling, and easy testability via IHttpClientFactory. For a simple integration, a singleton HttpClient is also acceptable.

How do I skip CSRF validation for the webhook endpoint in ASP.NET Core?

For minimal API endpoints (MapPost), CSRF protection is not applied by default. For controller endpoints, add [IgnoreAntiforgeryToken] to the action or controller. Always verify the HMAC-SHA256 signature in the X-GetSigned-Signature header as the authentication mechanism instead.

Is there a free tier to build against?

Yes. The free Starter plan includes full REST API access, PKCS#7 sealing, OTP verification, and webhooks, with 5 envelopes per month — enough to build and test a complete .NET integration.

Other stacks: Java · Node.js · Python · Go · Language-agnostic guide

Ship signing in your .NET app today

Get free API keys →