SignNow.NET 1.3.0

dotnet add package SignNow.NET --version 1.3.0                
NuGet\Install-Package SignNow.NET -Version 1.3.0                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SignNow.NET" Version="1.3.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add SignNow.NET --version 1.3.0                
#r "nuget: SignNow.NET, 1.3.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install SignNow.NET as a Cake Addin
#addin nuget:?package=SignNow.NET&version=1.3.0

// Install SignNow.NET as a Cake Tool
#tool nuget:?package=SignNow.NET&version=1.3.0                

signNow.NET

Build status Codecov NuGet Version NuGet Downloads License

About signNow

signNow.Net is the official .NET 4.5+ and .NET Standard class library for the signNow API. signNow allows you to embed legally-binding e-signatures into your app, CRM or cloud storage. Send documents for signature directly from your website. Invite multiple signers to finalize contracts. Track status of your requests and download signed copies automatically.

Get your account at https://www.signnow.com/developers

Table of Contents

  1. Get started
  2. Platform dependencies
  3. Installation
  4. Documentation
  5. Features
  6. Contribution guidelines
  7. License

Get started

To start using the API you will need an API key. You can get one here https://www.signnow.com/api. For a full list of accepted parameters, refer to the signNow REST Endpoints API guide: signNow API Reference.

API and Application
Resources Sandbox Production
API: api-eval.signnow.com:443 api.signnow.com:443
Application: https://app-eval.signnow.com https://app.signnow.com
Entry page: https://eval.signnow.com

Platform Dependencies

Windows
  • .Net Framework 4.5 or newer version should be installed in your system, or
  • .Net Core 3.0 and newer
MacOS and Linux
  • .Net Core 3.0 and newer

Installation

Install .Net package

dotnet add package SignNow.Net --version <package-version>

Install using Package manager

Install-Package SignNow.Net -Version <package-version>

Documentation

Read about the available signNow features in signNow API Docs.

Features

Authorization

Request Access Token

Get your access token via OAuth 2.0 service.

public static class AuthenticationExamples
{
    /// <summary>
    /// An example of obtaining an access token via OAuth 2.0 service.
    /// </summary>
    /// <param name="apiBase">signNow API base URL. Sandbox: "https://api-eval.signnow.com", Production: "https://api.signnow.com"</param>
    /// <param name="clientInfo"><see cref="CredentialModel"/> with Application Client ID and Client Secret</param>
    /// <param name="userCredentials"><see cref="CredentialModel"/> with User email and User password</param>
    public static async Task<Token> RequestAccessToken(Uri apiBase, CredentialModel clientInfo, CredentialModel userCredentials)
    {
        Uri apiBaseUrl = apiBase;

        string clientId = clientInfo.Login;
        string clientSecret = clientInfo.Password;

        string userLogin = userCredentials.Login;
        string userPassword = userCredentials.Password;

        var oauth = new OAuth2Service(apiBaseUrl, clientId, clientSecret);

        return await oauth.GetTokenAsync(userLogin, userPassword, Scope.All)
            .ConfigureAwait(false);
    }
}

More examples: Request Access token, Verify Access Token, Refresh Access Token

User

Creates an account for a user

By default verification email is not sent to newly created User. To send it - use IUserService.SendVerificationEmailAsync(string email)

public static partial class UserExamples
{
    /// <summary>
    /// Creates an account for a user example
    /// </summary>
    /// <param name="firstname">User firstname</param>
    /// <param name="lastname">User lastname</param>
    /// <param name="email">User email</param>
    /// <param name="password">User password</param>
    /// <param name="token">Access token</param>
    /// <returns>
    /// Response with: User identity, email
    /// </returns>
    public static async Task<UserCreateResponse> CreateSignNowUser(string firstname, string lastname, string email, string password, Token token)
    {
        var signNowContext = new SignNowContext(token);

        var userRequest = new CreateUserOptions
        {
            Email = email,
            FirstName = firstname,
            LastName = lastname,
            Password = password
        };

        return await signNowContext.Users
            .CreateUserAsync(userRequest)
            .ConfigureAwait(false);
    }
}

More examples: Create User, Retrieve User information, Sends verification email to a user, Change User details, Sends password reset link via email, Get modified documents, Get user documents

Document

Upload a document to signNow

All the features in signNow require a document_id. Once you upload a document to signNow, you get the document_id from a successful response.

public static class DocumentExamples
{
    /// <summary>
    /// Uploads a PDF document to signNow and returns SignNowDocument object.
    /// </summary>
    /// <param name="pdfFilePath">Full qualified path to your PDF file.</param>
    /// <param name="token">Access token</param>
    public static async Task<SignNowDocument> UploadDocument(string pdfFilePath, Token token)
    {
        // using token from the Authorization step
        var signNowContext = new SignNowContext(token);
        var pdfFileName = "document-example.pdf";
        
        await using var fileStream = File.OpenRead(pdfFilePath);
        
        // Upload the document
        var uploadResponse = signNowContext.Documents
            .UploadDocumentAsync(fileStream, pdfFileName).Result;

        // Gets document ID from successful response
        var documentId = uploadResponse.Id;

        return await signNowContext.Documents.GetDocumentAsync(documentId);
    }
}

More examples: Upload document, Upload document with field extract, Upload document with complex tags

Download a document from signNow

Choose the type of download for your document:

  • PdfOriginal - download a document in a state it's been when uploaded to signNow, before any changes
  • PdfCollapsed - download a document in PDF file format
  • ZipCollapsed - download a document in ZIP archive
  • PdfWithHistory - download a document with its history, a full log of changes on a separate page.
public static class DocumentExamples
{
    /// <summary>
    /// Downloads signed document.
    /// <see cref="DownloadDocumentResponse"/> contains: file name, file length, Stream content
    /// </summary>
    /// <param name="documentId">ID of signed document</param>
    /// <param name="token">Access token</param>
    public static async Task<DownloadDocumentResponse> DownloadDocument(string documentId, Token token)
    {
        // using token from the Authorization step
        var signNowContext = new SignNowContext(token);
        
        // using `documentId` from the Upload document step
        return await signNowContext.Documents
                        .DownloadDocumentAsync(documentId, DownloadType.PdfCollapsed)
                        .ConfigureAwait(false);
    }
}

More examples: Download signed document

Merge two or more signNow documents into one

Merges two or more signNow documents into one single PDF file.

Steps:

  • Upload documents or Get document IDs of the documents you’d like to merge
  • Merge the documents

Merged document will be saved in PDF file format.

public static partial class DocumentExamples
{
    /// <summary>
    /// Merge two documents into one final document
    /// </summary>
    /// <param name="documentName">New Document name with extension</param>
    /// <param name="documentsList">List of the documents to be merged</param>
    /// <param name="token">Access token</param>
    /// <returns>
    /// <see cref="DownloadDocumentResponse"/> contains: file name, file length, Stream content
    /// </returns>
    public static async Task<DownloadDocumentResponse>
        MergeTwoDocuments(string documentName, IEnumerable<SignNowDocument> documentsList, Token token)
    {
        // using token from the Authorization step
        var signNowContext = new SignNowContext(token);

        return await signNowContext.Documents
            .MergeDocumentsAsync(documentName, documentsList)
            .ConfigureAwait(false);
    }
}

More examples: Merge document

Signing link - a single-use link to a document that requires a signature. When the document is signed (or the signer declines to sign it), the link is no longer valid. Having followed the link, signers can click anywhere on the document to sign it.

Steps:

  • Upload a document or Get the ID of the document you’d like to have signed
  • Send a signing link
public static partial class DocumentExamples
{
    /// <summary>
    /// Create a signing link to the document for signature.
    /// </summary>
    /// <param name="documentId">Identity of the document you’d like to have signed</param>
    /// <param name="token">Access token</param>
    /// <returns>
    /// Response with:
    /// <para> <see cref="SigningLinkResponse.Url"/>
    /// to sign the document via web browser using signNow credentials. </para>
    /// <para> <see cref="SigningLinkResponse.AnonymousUrl"/>
    /// to sign the document via web browser without signNow credentials. </para>
    /// </returns>
    public static async Task<SigningLinkResponse>
        CreateSigningLinkToTheDocument(string documentId, Token token)
    {
        // using token from the Authorization step
        var signNowContext = new SignNowContext(token);

        // using `documentId` from the Upload document step
        return await signNowContext.Documents
            .CreateSigningLinkAsync(documentId).ConfigureAwait(false);
    }
}

More examples: Create signing link, Check signing status

Create a freeform invite to the document for signature

Freeform invite - an invitation to sign a document which doesn't contain any fillable fields.

Simply upload a document and send it for signature right away. No need for adding fields and configuring roles. Just add the signer's email address and customize the message in your email. The document will be available for signing via a button in the email. Clicking the button opens a document in signNow editor. Signers can click anywhere on a document to add their signature.

Remember: if your document contains even one fillable field, you have to create a role-based invite to get it signed.

public static partial class InviteExamples
{
    /// <summary>
    /// Create a freeform invite to the document for signature.
    /// </summary>
    /// <param name="document">signNow document you’d like to have signed</param>
    /// <param name="email">The email of the invitee.</param>
    /// <param name="token">Access token</param>
    /// <returns>
    /// <see cref="InviteResponse"/> which contains an Identity of invite request.
    /// </returns>
    public static async Task<InviteResponse>
        CreateFreeformInviteToSignTheDocument(SignNowDocument document, string email, Token token)
    {
        // using token from the Authorization step
        var signNowContext = new SignNowContext(token);

        // Create freeform invite
        var invite = new FreeFormSignInvite(email)
        {
            Message = $"{email} invited you to sign the document {document.Name}",
            Subject = "The subject of the Email"
        };

        // Creating Invite request
        return await signNowContext.Invites.CreateInviteAsync(document.Id, invite).ConfigureAwait(false);
    }
}

More examples: Create freeform invite

Create a role-based invite to the document for signature

Role-based invite - an invitation to sign a document which contains at least one fillable field assigned to one role.

Role-based invites allow you to build e-signature workflows. The document can be signed by multiple signers: each with individual access settings, all arranged in a specific order.

Upload a document or create one from a template.

The document will be available for signing via a button in the email. You can customize email messages for every signer. Clicking the button opens a document in signNow editor. Signers can sign only the fields designated for their role.

You can add more roles either in signNow web app while editing the fields, or with ISignInvite interface from SDK while specifying parameters of the SignerOptions object.

public static partial class InviteExamples
{
    /// <summary>
    /// Create a role-based invite to the document for signature.
    /// </summary>
    /// <param name="document">signNow document with fields you’d like to have signed</param>
    /// <param name="email">The email of the invitee.</param>
    /// <param name="token">Access token</param>
    /// <returns><see cref="InviteResponse"/> without any Identity of invite request.</returns>
    public static async Task<InviteResponse>
        CreateRoleBasedInviteToSignTheDocument(SignNowDocument document, string email, Token token)
    {
        // using token from the Authorization step
        var signNowContext = new SignNowContext(token);

        // Create role-based invite
        var invite = new RoleBasedInvite(document)
        {
            Message = $"{email} invited you to sign the document {document.Name}",
            Subject = "The subject of the Email"
        };

        // Creates options for signers
        var signer = new SignerOptions(email, invite.DocumentRoles().First())
            {
                ExpirationDays = 15,
                RemindAfterDays = 7,
            }
            .SetAuthenticationByPassword("***PASSWORD_TO_OPEN_THE_DOCUMENT***");

        // Attach signer to existing roles in the document
        invite.AddRoleBasedInvite(signer);

        // Creating Invite request
        return await signNowContext.Invites.CreateInviteAsync(document.Id, invite).ConfigureAwait(false);
    }
}

More examples: Create role-based invite

Create embedded signing invite to the document for signature

public static partial class InviteExamples
{
    /// <summary>
    /// Create an embedded signing invite to the document for signature.
    /// </summary>
    /// <param name="document">signNow document you’d like to have signed</param>
    /// <param name="email">The email of the invitee.</param>
    /// <param name="token">Access token</param>
    /// <returns>
    /// <see cref="EmbeddedInviteResponse"/> which contains an invite data.
    /// </returns>
    public static async Task<EmbeddedInviteResponse>
        CreateEmbeddedSigningInviteToSignTheDocument(SignNowDocument document, string email, Token token)
    {
        // using token from the Authorization step
        var signNowContext = new SignNowContext(token);

        // create embedded signing invite
        var invite = new EmbeddedSigningInvite(document);
        invite.AddEmbeddedSigningInvite(
            new EmbeddedInvite
            {
                Email = email,
                RoleId = document.Roles[0].Id,
                SigningOrder = 1
            });

        return await signNowContext.Invites.CreateInviteAsync(document.Id, invite)
            .ConfigureAwait(false);
    }
}

More examples: Generate embedded signing link, Cancel embedded signing invite

public static partial class DocumentExamples
{
    /// <summary>
    /// Create a one-time use URL for anyone to download the document as a PDF.
    /// </summary>
    /// <param name="documentId">Identity of the document</param>
    /// <param name="token">Access token</param>
    /// <returns><see cref="DownloadLinkResponse"/></returns>
    public static async Task<DownloadLinkResponse>
        CreateOneTimeLinkToDownloadTheDocument(string documentId, Token token)
    {
        // using token from the Authorization step
        var signNowContext = new SignNowContext(token);

        return await signNowContext.Documents
            .CreateOneTimeDownloadLinkAsync(documentId)
            .ConfigureAwait(false);
    }
}

More examples: Create a One-time Use Download URL

Get the history of a document

public static partial class DocumentExamples
{
    /// <summary>
    /// Retrieve the history of a document.
    /// </summary>
    /// <param name="documentId">Identity of the document</param>
    /// <param name="token">Access token</param>
    /// <returns><see cref="DocumentHistoryResponse"/></returns>
    public static async Task<IReadOnlyList<DocumentHistoryResponse>>
        GetTheDocumentHistory(string documentId, Token token)
    {
        // using token from the Authorization step
        var signNowContext = new SignNowContext(token);

        return await signNowContext.Documents
            .GetDocumentHistoryAsync(documentId)
            .ConfigureAwait(false);
    }
}

More examples: Get document history

Template

Create Template by flattening the existing Document

Set required templateName and documentId parameters to create the signNow Template.

public static class DocumentExamples
{
    /// <summary>
    /// Creates a template by flattening an existing document.
    /// </summary>
    /// <param name="documentId">Identity of the document which is the source of a template</param>
    /// <param name="templateName">The new template name</param>
    /// <param name="token">Access token</param>
    /// <returns><see cref="CreateTemplateFromDocumentResponse"/>Returns a new template ID</returns>
    public static async Task<CreateTemplateFromDocumentResponse>
        CreateTemplateFromTheDocument(string documentId, string templateName, Token token)
    {
        // using token from the Authorization step
        var signNowContext = new SignNowContext(token);
    
        return await signNowContext.Documents
            .CreateTemplateFromDocumentAsync(documentId, templateName)
            .ConfigureAwait(false);    
    }
}

More examples: Create a template by flattening an existing document, Create document from the template

Document Group

Create document group

Creates a document group from a list of document ids

All documents:

  • Must be owned by the person creating the document group.
  • Cannot be templates.
  • Cannot already be a part of another document group (delete document group first to add them).
  • At least one of the documents must have fields.
public async Task<DocumentGroupInfoResponse> CreateDocumentGroupAsync()
{
     // using token from the Authorization step
    var signNowContext = new SignNowContext(token);
    
    // Upload test documents
    await using var fileStream = File.OpenRead("./PdfWithSignatureField.pdf");

    var documents = new List<SignNowDocument>();

    for (int i = 0; i < 2; i++)
    {
        var upload = await signNowContext.Documents
            .UploadDocumentAsync(fileStream, $"ForDocumentGroupFile-{i}.pdf");
        var doc = await signNowContext.Documents.GetDocumentAsync(upload.Id).ConfigureAwait(false);
        documents.Add(doc);
    }

    // Create document group from uploaded documents
    var documentGroup = await signNowContext.DocumentGroup
        .CreateDocumentGroupAsync("CreateDocumentGroupExample", documents)
        .ConfigureAwait(false);

    // Get document group by id
    return await signNowContext.DocumentGroup
        .GetDocumentGroupInfoAsync(documentGroup.Id)
        .ConfigureAwait(false);
}

More examples: Document group operations

Folders

Get all folders

public static class FolderExamples
{
    /// <summary>
    /// Get all folders of a user.
    /// </summary>
    /// <param name="token">Access token</param>
    /// <returns>Returns all information about user's folders.</returns>
    public static async Task<SignNowFolders> GetAllFolders(Token token)
    {
        var signNowContext = new SignNowContext(token);

        return await signNowContext.Folders
            .GetAllFoldersAsync()
            .ConfigureAwait(false);
    }
}

More examples: Get all folders, Get folder, Create folder

Contribution guidelines

XML doc generation

For XML documentation generation, install InheritDocTool:

dotnet tool install -g InheritDocTool

More about the InheritDoc here

Important notes

Thanks to all contributors who got interested in this project. We're excited to hear from you. Here are some tips to make our collaboration meaningful and bring its best results to life:

  • We accept pull requests from the community. Please, send your pull requests to the DEVELOP branch which is the consolidated work-in-progress branch. We don't accept requests to the Master branch.
  • Please, check in with the documentation first before you open a new Issue.
  • When suggesting new functionality, give as many details as possible. Add a test or code example if you can.
  • When reporting a bug, please, provide full system information. If possible, add a test that helps us reproduce the bug. It will speed up the fix significantly.

License

This SDK is distributed under the MIT License, see LICENSE for more information.

API Contact Information

If you have questions about the signNow API, please visit signNow API Reference or email api@signnow.com.

Support: To contact signNow support, please email support@signnow.com or api@signnow.com.

Sales: For pricing information, please call (800) 831-2050, email sales@signnow.com or visit https://www.signnow.com/contact.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  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. 
.NET Core netcoreapp1.0 was computed.  netcoreapp1.1 was computed.  netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard1.2 is compatible.  netstandard1.3 was computed.  netstandard1.4 was computed.  netstandard1.5 was computed.  netstandard1.6 was computed.  netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net45 is compatible.  net451 was computed.  net452 was computed.  net46 was computed.  net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen30 was computed.  tizen40 was computed.  tizen60 was computed. 
Universal Windows Platform uap was computed.  uap10.0 was computed. 
Windows Phone wpa81 was computed. 
Windows Store netcore451 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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
1.3.0 123 12/18/2024
1.2.3 11,805 10/15/2023
1.2.2 785 8/27/2023
1.2.1 2,654 7/13/2023
1.2.0 959 7/3/2023
1.1.1 3,769 5/2/2023
1.1.0 11,430 1/23/2023
1.0.0 9,250 1/26/2022
0.9.0 2,928 7/7/2021
0.8.0 1,239 4/26/2021
0.7.0 2,636 3/28/2021
0.6.0-beta 920 11/17/2020
0.5.2-beta 1,106 5/22/2020
0.5.1-beta 18,261 4/18/2020
0.5.0-beta 1,018 3/6/2020
0.4.0-beta 915 2/19/2020
0.3.0-beta 848 1/24/2020
0.2.0-beta 916 12/18/2019
0.1.0-beta 826 11/18/2019
0.0.0-beta 900 10/30/2019
0.0.0-alpha 834 9/2/2019

### Added
- Resend Invite feature [#153](https://github.com/signnow/SignNow.NET/issues/153)
- Options for Embedded invite [#160](https://github.com/signnow/SignNow.NET/issues/160)
- DocumentGroup feature [#161](https://github.com/signnow/SignNow.NET/issues/161)

### Changed
- `DownloadDocumentResponse` model extended with `MediaType` property

### Fixed
- Fixed force logout after user details update