1. Overview — what this article covers

You will learn, step-by-step, how to implement DocuSign eSignature in a .NET (ASP.NET Core) app:

I’ll include working C# snippets and notes you can drop into an ASP.NET Core project.

2. Quick background: DocuSign building blocks

3. Prerequisites

  1. DocuSign developer account ( https://developers.docusign.com ) — use Demo (sandbox).

  2. Integration Key (app) created in DocuSign Admin with the redirect URI (if using Auth Code) or configured for JWT.

  3. RSA keypair (private key) generated and uploaded to your DocuSign app (for JWT flow).

  4. .NET 6 / .NET 7+ SDK and an ASP.NET Core Web API or MVC project.

  5. NuGet packages: DocuSign.eSign (official C# SDK).

Install the SDK

  
    dotnet add package DocuSign.eSign
  

4. Authentication: choose the right flow

JWT Grant (service integrations): no user interaction; server exchanges signed JWT for access token. Best for backend services that act on behalf of users or a system account. Requires consent once (admin or user).

Authorization Code Grant (user interactive): redirect user to DocuSign login page, user consents and returns code. Best for user-driven flows where the signer must authenticate with DocuSign.

Recommendation: Use JWT for server flows (creating envelopes programmatically, embedded signing server prepares envelope); use Authorization Code when the user must sign in to DocuSign itself.

5. Getting an access token (JWT) — minimal example

  1. Upload your RSA private key to the DocuSign app (Admin → Apps and Keys).

  2. Grant consent to your Integration Key for the impersonated user (admin consent or via browser link).

Below is a minimal JWT token flow using the DocuSign SDK helper. The SDK exposes helper classes; you can also form JWT by hand.

  
    using DocuSign.eSign.Client;
using System.Security.Cryptography;
using System.IO;

public class DocuSignAuthService
{
    private readonly string _integrationKey = "<INTEGRATION_KEY>";
    private readonly string _userId = "<IMPERSONATED_USER_ID_GUID>";
    private readonly string _authBasePath = "account-d.docusign.com"; // demo
    private readonly string _privateKeyPath = "docusign_private_key.pem"; // RSA private key (PKCS8)

    public ApiClient CreateApiClient()
    {
        var apiClient = new ApiClient($"https://{_authBasePath}");
        return apiClient;
    }

    public string GetAccessToken()
    {
        var apiClient = CreateApiClient();
        // Read private key
        var privateKey = File.ReadAllText(_privateKeyPath);
        // Requests JWT token. SDK provides a helper method.
        var oauthToken = apiClient.RequestJWTUserToken(
            _integrationKey,
            _userId,
            new List<string> { "signature", "impersonation" },
            System.Text.Encoding.UTF8.GetBytes(privateKey),
            3600);
        return oauthToken.access_token;
    }
}
  

Notes

6. Create and send an envelope (server side)

This example creates an envelope with a single PDF and a single signer.

  
    using DocuSign.eSign.Api;
using DocuSign.eSign.Model;
using DocuSign.eSign.Client;
using System.Collections.Generic;

public class DocuSignService
{
    private readonly string _accountId;
    private readonly ApiClient _apiClient;

    public DocuSignService(string accessToken, string accountId, string basePath = "https://demo.docusign.net/restapi")
    {
        _apiClient = new ApiClient(basePath);
        _apiClient.Configuration.DefaultHeader.Add("Authorization", "Bearer " + accessToken);
        _accountId = accountId;
    }

    public EnvelopeSummary SendEnvelope(byte[] pdfBytes, string signerEmail, string signerName, string signerClientUserId = null)
    {
        var envelopesApi = new EnvelopesApi(_apiClient.Configuration);

        // Document
        var doc = new Document
        {
            DocumentBase64 = Convert.ToBase64String(pdfBytes),
            Name = "Sample Document",
            FileExtension = "pdf",
            DocumentId = "1"
        };

        // Signer
        var signer = new Signer
        {
            Email = signerEmail,
            Name = signerName,
            RecipientId = "1",
            RoutingOrder = "1"
        };

        // Example: add a signHere tab at absolute position
        signer.Tabs = new Tabs
        {
            SignHereTabs = new List<SignHere> {
                new SignHere { DocumentId = "1", PageNumber = "1", XPosition = "100", YPosition = "150" }
            }
        };

        var envDef = new EnvelopeDefinition
        {
            EmailSubject = "Please sign this document",
            Documents = new List<Document> { doc },
            Recipients = new Recipients { Signers = new List<Signer> { signer } },
            Status = "sent" // "sent" to send immediately, "created" to save as draft
        };

        var result = envelopesApi.CreateEnvelope(_accountId, envDef);
        return result;
    }
}
  

This SendEnvelope returns an EnvelopeSummary with the envelopeId you can store and track.

7. Embedded Signing (In-app signing / Recipient View)

For in-app signing (so the signer stays in your app), create a recipient view (signing URL). This requires the signer to be a embedded recipient — set clientUserId on the signer object.

  
    public string CreateRecipientView(string envelopeId, string signerEmail, string signerName, string returnUrl)
{
    var viewRequest = new RecipientViewRequest
    {
        ReturnUrl = returnUrl, // user returns here after signing
        ClientUserId = "123",  // must match Signer.clientUserId
        AuthenticationMethod = "none",
        UserName = signerName,
        Email = signerEmail
    };

    var envelopesApi = new EnvelopesApi(_apiClient.Configuration);
    var result = envelopesApi.CreateRecipientView(_accountId, envelopeId, viewRequest);
    return result.Url; // redirect user to this URL (or open in iframe if allowed)
}
  

Notes and security

8. DocuSign Connect (Webhook) — implement listener in ASP.NET Core

DocuSign Connect delivers envelope events to your public webhook endpoint. Implement a listener to receive JSON/XML notifications and verify them.

Simple controller endpoint

  
    [ApiController]
[Route("api/docusign")]
public class DocuSignController : ControllerBase
{
    [HttpPost("connect")]
    public async Task<IActionResult> Connect()
    {
        // DocuSign may send XML or JSON based on configuration
        string body;
        using (var reader = new StreamReader(Request.Body))
        {
            body = await reader.ReadToEndAsync();
        }

        // Optionally log the raw payload (ensure PII rules)
        // Validate using HMAC or OAuth method (recommended)
        // Process payload: parse envelope status, recipient events etc.

        // Respond with 200 OK quickly
        return Ok();
    }
}
  

Validation options (recommended):

Example: validating HMAC

  
    public bool ValidateHmac(string requestBody, string hmacHeader, string secret)
{
    var keyBytes = Encoding.UTF8.GetBytes(secret);
    using var hmac = new HMACSHA256(keyBytes);
    var computed = hmac.ComputeHash(Encoding.UTF8.GetBytes(requestBody));
    var computedBase64 = Convert.ToBase64String(computed);
    return string.Equals(computedBase64, hmacHeader, StringComparison.InvariantCulture);
}
  

Configure DocuSign Admin for Connect to include your HMAC key, and check the header (DocuSign sends it in X-DocuSign-Signature or similar; check current header name in the docs).

9. Processing webhook events — idempotency & state transitions

10. Local testing with DocuSign Demo & ngrok

Example with ngrok

  
    ngrok http 5000
# Use the generated https URL in DocuSign Connect settings
  

Set the Connect listener to POST to https://<your-ngrok-id>.ngrok.io/api/docusign/connect .

11. Error handling, retries, and monitoring

12. Example: End-to-end flow (step diagram)

  
    Developer / System
   └─> Create Envelope (server) --> DocuSign eSignature API (Create Envelope)
         └─> DocuSign sends email to recipient (if remote) OR
         └─> Server requests Recipient View URL (embedded signing) and returns URL to client

User (if embedded) visits signing URL -> signs -> DocuSign updates envelope status

DocuSign Connect (webhook) --> Your webhook endpoint (/api/docusign/connect)
   └─> You validate (HMAC / OAuth) --> enqueue processing (update DB, send notifications)
  

13. Deployment & CI/CD tips

14. Security & compliance recommendations

15. Testing & QA checklist

16. Useful DocuSign resources (official)

(These five references are the most load-bearing sources for setup, auth, SDK, and webhook guidance.)

17. Common pitfalls and how to avoid them

18. Advanced topics (next steps)

19. Example repository & samples

DocuSign maintains sample repos and quickstarts (C# examples) to help you start quickly — the official GitHub repo and Developer Center have ready examples you can clone and run.

20. Summary — practical checklist before go-live