Formable 0.1.0
dotnet add package Formable --version 0.1.0
NuGet\Install-Package Formable -Version 0.1.0
<PackageReference Include="Formable" Version="0.1.0" />
<PackageVersion Include="Formable" Version="0.1.0" />
<PackageReference Include="Formable" />
paket add Formable --version 0.1.0
#r "nuget: Formable, 0.1.0"
#:package Formable@0.1.0
#addin nuget:?package=Formable&version=0.1.0
#tool nuget:?package=Formable&version=0.1.0
formable-dotnet
Official .NET SDK for the Formable API (v1). Covers templates, signature requests, redlining, and billing.
- Typed request and response models (
System.Text.Json) - Async methods with
CancellationTokensupport - Zero runtime dependencies on .NET 8+
- Injectable
HttpClientforIHttpClientFactory
Installation
dotnet add package Formable
Usage
using Formable;
using var formable = new FormableClient(Environment.GetEnvironmentVariable("FORMABLE_API_KEY")!);
Templates
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
// 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);
Redline requests
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
var billing = await formable.BillingAsync();
int sessions = billing.NumberOfRedliningSessions;
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.
try
{
await formable.SignatureRequests.GetAsync("missing-id");
}
catch (FormableException error)
{
Console.Error.WriteLine($"{error.Status} {error.Message}");
}
Configuration
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.
Development
dotnet test
Publishing
Releases use NuGet Trusted Publishing. GitHub Actions exchanges an OIDC token for a short-lived nuget.org key. There is no long-lived API key to store.
One-time setup
Create a nuget.org account (Formable org, not a personal account).
On GitHub, create an Environment named
nugeton FormableDocs/formable-dotnet. Add a secretNUGET_USERset to your nuget.org profile name (not your email).On nuget.org, open your avatar → Trusted Publishing → add a policy:
Field Value Repository owner FormableDocsRepository formable-dotnetWorkflow file publish.ymlEnvironment nugetEnter the workflow file name only. Owner, repo, workflow, and environment must match this repo exactly (case-insensitive).
Publish a version
The published version is the git tag with the leading v stripped (v0.1.0 → 0.1.0).
git tag v0.1.0
git push origin v0.1.0
That runs .github/workflows/publish.yml: test, pack, OIDC login, dotnet nuget push. The package is at nuget.org/packages/Formable after indexing (usually a few minutes).
Do not use a reusable workflow for this job. NuGet binds the OIDC identity to publish.yml in this repository.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.1.0 | 42 | 8/27/2026 |