> ## Documentation Index
> Fetch the complete documentation index at: https://docs.formabledocs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# .NET

> Install and use Formable, the official .NET SDK for the Formable API.

[`Formable`](https://www.nuget.org/packages/Formable) is the official .NET SDK for the Formable API (v1). It covers templates, signature requests, redlining, and billing.

* Typed request and response models
* Async methods with `CancellationToken` support
* Zero runtime dependencies on .NET 8+

Source code is on [GitHub](https://github.com/FormableDocs/formable-dotnet).

## Installation

```bash theme={null}
dotnet add package Formable
```

## Initialize the client

Pass your API key from [Settings](https://app.formabledocs.com/settings). It's sent as a bearer token on every request.

```csharp theme={null}
using Formable;

using var formable = new FormableClient(Environment.GetEnvironmentVariable("FORMABLE_API_KEY"));
```

## Templates

Upload a document to create a reusable template, then mint edit URLs to place fields in the embedded editor. See the [embedded templates walkthrough](/walkthroughs/embedded-templates).

```csharp theme={null}
var created = await formable.Templates.CreateAsync(
    "nda.docx",
    [
        new TemplateSignerRole("Client", 0),
        new TemplateSignerRole("Witness", 1),
    ]);

string templateId = created.TemplateId;

// Mint a fresh edit URL later (expires after 1 day)
var edit = await formable.Templates.CreateEditUrlAsync(templateId);
```

## Signature requests

Send a template for signing by email, or embed the signing experience in your product. See the [embedded signing walkthrough](/walkthroughs/embedded-signing).

```csharp theme={null}
// Formable emails each signer a signing link
var request = await formable.SignatureRequests.CreateAsync(
    new CreateSignatureRequest(
        templateId,
        [
            new Signer("jane@example.com", "Jane Doe", "Client"),
            new Signer("bob@example.com", "Bob Smith", "Witness"),
        ]));

// Embedded flow: mint signing URLs to embed in an iframe yourself
var embedded = await formable.SignatureRequests.CreateEmbeddedAsync(
    new CreateSignatureRequest(
        templateId,
        [new Signer("jane@example.com", "Jane Doe", "Client")],
        TestMode: true));

var signer = embedded.Signers[0];
var signing = await formable.SignatureRequests.CreateSigningUrlAsync(signer.RecipientSignatureId);

// Track progress
var current = await formable.SignatureRequests.GetAsync(embedded.SignatureRequestId);
var all = await formable.SignatureRequests.ListAsync(DateTimeOffset.Parse("2026-01-01T00:00:00Z"));
var events = await formable.SignatureRequests.GetEventsAsync(embedded.SignatureRequestId);

// Download the signed document once completed
var envelope = await formable.SignatureRequests.GetSignedEnvelopeAsync(embedded.SignatureRequestId);
```

<Note>
  `GetSignedEnvelopeAsync` throws a `409` until the document is complete. Wait for the [`document_completed`](/webhooks/events#document_completed) webhook, or poll `GetAsync` until `Status` is `Completed`.
</Note>

## Redline requests

Run turn-based contract negotiation before signing. See the [redlining walkthrough](/walkthroughs/redlining).

```csharp theme={null}
var created = await formable.RedlineRequests.CreateAsync(
    new CreateRedlineRequest(
        templateId,
        [
            new RedlineMember("us@example.com", "John Doe", RedlineMemberRole.DisclosingParty),
            new RedlineMember("them@example.com", "Jane Smith", RedlineMemberRole.ReceivingParty),
        ],
        Metadata: new RedlineRequestMetadata("Mutual NDA")));

string redlineRequestId = created.RedlineRequestId;

// Mint a redline URL for a member (embed in an iframe)
var url = await formable.RedlineRequests.CreateUrlAsync(redlineRequestId, "them@example.com");

// Manage members and track progress
await formable.RedlineRequests.UpdateMembersAsync(
    redlineRequestId,
    [new RedlineMember("counsel@example.com", "Counsel", RedlineMemberRole.ReceivingCounsel)]);
var redline = await formable.RedlineRequests.GetAsync(redlineRequestId);
var events = await formable.RedlineRequests.GetEventsAsync(redlineRequestId);
```

## Billing and health

```csharp theme={null}
var billing = await formable.BillingAsync();
var health = await formable.HealthAsync();
```

## Error handling

All non-2xx responses throw a `FormableException` with the server's error message, HTTP status, and parsed response body.

```csharp theme={null}
try
{
    await formable.SignatureRequests.GetAsync("missing-id");
}
catch (FormableException error)
{
    Console.Error.WriteLine($"{error.Status} {error.Message}");
}
```

## Configuration

`FormableOptions` takes an API key, then optional `BaseUrl`, `Timeout`, and `HttpClient` values.

```csharp theme={null}
using Formable;

using var formable = new FormableClient(
    new FormableOptions
    {
        ApiKey = Environment.GetEnvironmentVariable("FORMABLE_API_KEY"),
        BaseUrl = "https://api.formabledocs.com/v1",
        Timeout = TimeSpan.FromSeconds(60),
        HttpClient = httpClient,
    });
```

| Option       | Description                                               | Default                           |
| ------------ | --------------------------------------------------------- | --------------------------------- |
| `ApiKey`     | Your Formable API key (sent as a bearer token). Required. | -                                 |
| `BaseUrl`    | Override the API base URL.                                | `https://api.formabledocs.com/v1` |
| `Timeout`    | Per-request timeout.                                      | 60 seconds                        |
| `HttpClient` | Custom `HttpClient`. Not disposed by the SDK.             | Built-in client with 60s timeout  |

Pass an `HttpClient` from `IHttpClientFactory` in ASP.NET Core so the factory owns the handler lifetime.

## Next steps

<CardGroup cols={2}>
  <Card title="Quickstart" icon="rocket" href="/quickstart">
    Go from a plain document to a signed PDF in 4 calls.
  </Card>

  <Card title="API reference" icon="code" href="/api-reference/introduction">
    Every endpoint the SDK wraps, with a live playground.
  </Card>
</CardGroup>
