# .NET
> Use this guide to migrate to the new Dropbox Sign Dotnet SDK, which is powered by our OpenAPI specification. Contains concepts and examples to help you migrate successfully.
# Dotnet Migration Guide
## Migrating the Dotnet SDK from `HelloSign` to `Dropbox.Sign`
## Architecture and Tooling
## Core Concepts and Patterns
This section contains the core concepts and patterns of the new SDK and highlights differences from the legacy SDK.
### Installation
There are two methods for installing the new OpenAPI Dotnet SDK:
-
Install using this NuGet package: Dropbox.Sign:
dotnet add package Dropbox.Sign --version 1.0.0
-
Clone the Dotnet SDK repo:
git clone [https://github.com/hellosign/dropbox-sign-dotnet.git](https://github.com/hellosign/dropbox-sign-dotnet.git)
-
Ensure Docker is installed and running
-
cd into
dropbox-sign-dotnet
-
Run:
dotnet pack
-
This should generate a .nupkg with the path:
src/Dropbox.Sign/bin/Debug/Dropbox.Sign.1.0.0-*.nupkg
-
Note: the version will be different depending on when you have cloned the repo
-
Create a local
NuGet.Config
file at the root level of the existing project
-
Add the following code to your
NuGet.Config file:
```
<configuration>
<packageSources>
<add key="local" value="/absolute/path/to/Dropbox.Sign.1.0.0-*.nupkg" />
</packageSources>
</configuration>
```
-
Reference the package within the
.csproj file:
```
<ItemGroup>
<PackageReference Include="Dropbox.Sign" Version="1.0.0*" />
</ItemGroup>
```
-
Add code to your project
-
Run:
dotnet run
### Importing the SDK
-
Pulled in everything from a single namespace.
-
Requires 3 separate namespaces
```csharp Legacy SDK - Namespaces
using HelloSign;
```
```csharp New SDK - Namespaces
using Dropbox.Sign.Api;
using Dropbox.Sign.Client;
using Dropbox.Sign.Model;
```
The New Dotnet SDK organizes methods and classes across multiple namespaces; each with a specific purpose.
| Namespace | Purpose |
| --------------------- | ---------------------------------------------------------------------------------- |
| `Dropbox.Sign.Api` | A collection of functions to interact with the API endpoints |
| `Dropbox.Sign.Client` | A collection of classes that focus mainly on set-up, configuration, and exceptions |
| `Dropbox.Sign.Model` | A collection of models for all endpoint classes and sub classes |
### Authentication
To set-up your configuration and set the HTTP basic authenticator:
-
Option 1: Instantiate a new
Client
class with your API key.
-
Option 2: Instantiate a new
Client
class and pass OAuth Access Token in the
.UseOAuth2Authentication()
method.
-
Option 1: Instantiate a new
Configuration
class and set your API Key as the
Username
.
-
Option 2: Instantiate a new
Configuration
class and set bearer authorization: oauth 2 token as the
AccessToken
.
```csharp Legacy SDK - Config
var client = new Client(apiKey);
// Include OAuth token if using OAuth
// client.UseOAuth2Authentication("OAUTH ACCESS TOKEN HERE");
// Use one the Client class methods to execute a call to an endpoint
var account = client.GetAccount("ACCOUNT_CLIENT_ID);
Console.Writeline(account.AccountId)
```
```csharp New SDK - Config
var config = new Configuration();
config.Username = "YOUR_API_KEY";
// or, configure Bearer authorization: oauth2
// config.AccessToken = "YOUR_BEARER_TOKEN";
// Instantiate one of the new classes and pass your configuration in as an arguement
var accountApi = new AccountApi(config);
```
### Endpoints Grouped into Classes
The new SDK divides endpoints across unique Classes:
| Class Name and Reference | API Reference |
| ------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- |
| [AccountApi](https://github.com/hellosign/dropbox-sign-dotnet/blob/main/docs/AccountApi.md) | [/account/\* Endpoints](/api/account) |
| [ApiAppApi](https://github.com/hellosign/dropbox-sign-dotnet/blob/main/docs/ApiAppApi.md) | [/api\_app/\* Endpoints](/api/api-app) |
| [BulkSendJobApi](https://github.com/hellosign/dropbox-sign-dotnet/blob/main/docs/BulkSendJobApi.md) | [/bulk\_send\_job/\* Endpoints](/api/bulk-send-job) |
| [EmbeddedApi](https://github.com/hellosign/dropbox-sign-dotnet/blob/main/docs/EmbeddedApi.md) | [/embedded/\* Endpoints](/api/embedded) |
| [OAuthApi](https://github.com/hellosign/dropbox-sign-dotnet/blob/main/docs/OAuthApi.md) | [/oauth/\* Endpoints](/docs/guides/o-auth/overview) |
| [ReportApi](https://github.com/hellosign/dropbox-sign-dotnet/blob/main/docs/ReportApi.md) | [/report/\* Endpoints](/api/report) |
| [SignatureRequestApi](https://github.com/hellosign/dropbox-sign-dotnet/blob/main/docs/SignatureRequestApi.md) | [/signature\_request/\* Endpoints](/api/signature-request) |
| [TeamApi](https://github.com/hellosign/dropbox-sign-dotnet/blob/main/docs/TeamApi.md) | [/team/\* Endpoints](/api/team) |
| [TemplateApi](https://github.com/hellosign/dropbox-sign-dotnet/blob/main/docs/TemplateApi.md) | [/template/\* Endpoints](/api/template) |
| [UnclaimedDraftApi](https://github.com/hellosign/dropbox-sign-dotnet/blob/main/docs/UnclaimedDraftApi.md) | [/unclaimed\_draft/\* Endpoints](/api/unclaimed-draft) |
### Using Models to Pass Parameters
[Models](https://github.com/hellosign/dropbox-sign-dotnet/blob/main/README.md#documentation-for-models) are used to define the structure and value of the parameters being passed. The fully assembled model is passed to the API endpoint method.
**New SDK Using Models to Pass Parameters**
```csharp
using Dropbox.Sign.Api;
using Dropbox.Sign.Client;
using Dropbox.Sign.Model;
public class Example
{
public static void Main()
{
var config = new Configuration();
config.Username = "YOUR_API_KEY";
var apiAppApi = new ApiAppApi(config);
var oauth = new SubOAuth(
callbackUrl: "https://example.com/oauth",
scopes: new List() {
SubOAuth.ScopesEnum.BasicAccountInfo,
SubOAuth.ScopesEnum.RequestSignature
}
);
var whiteLabelingOptions = new SubWhiteLabelingOptions(
primaryButtonColor: "#00b3e6",
primaryButtonTextColor: "#ffffff"
);
var customLogoFile = new FileStream(
"CustomLogoFile.png",
FileMode.Open
);
var data = new ApiAppCreateRequest(
name: "My Production App",
domains: new List(){"example.com"},
oauth: oauth,
whiteLabelingOptions: whiteLabelingOptions,
customLogoFile: customLogoFile
);
try
{
var result = apiAppApi.ApiAppCreate(data);
Console.WriteLine(result);
}
catch (ApiException e)
{
Console.WriteLine("Exception when calling Dropbox Sign API: " + e.Message);
Console.WriteLine("Status Code: " + e.ErrorCode);
Console.WriteLine(e.StackTrace);
}
}
}
```
### Path and Query Parameters
In the legacy SDK you would pass Path and Query parameters alongside any POST data to the API endpoint:
**Legacy SDK - Path and Query Parameters**
```csharp
var client = new Client(apiKey);
var emailAddress = "john@example.com";
var signatureRequestId = "2f9781e1a8e2045224d808c153c2e1d3df6f8f2f";
client.RemindSignatureRequest(signatureRequestId, emailAddress);
```
The new SDK now requires POST data be an object when calling any API endpoint. Path and Query parameters must be passed individually to these methods.
**New SDK - Path and Query Parameters**
```csharp
using Dropbox.Sign.Api;
using Dropbox.Sign.Client;
using Dropbox.Sign.Model;
public class Example
{
public static void Main()
{
var config = new Configuration();
// Configure HTTP basic authorization: api_key
config.Username = "YOUR_API_KEY";
// or, configure Bearer authorization: oauth2
// config.AccessToken = "YOUR_BEARER_TOKEN";
var signatureRequestApi = new SignatureRequestApi(config);
var data = new SignatureRequestRemindRequest(
emailAddress: "john@example.com"
);
var signatureRequestId = "2f9781e1a8e2045224d808c153c2e1d3df6f8f2f";
try
{
var result = signatureRequestApi.SignatureRequestRemind(signatureRequestId, data);
Console.WriteLine(result);
}
catch (ApiException e)
{
Console.WriteLine("Exception when calling Dropbox Sign API: " + e.Message);
Console.WriteLine("Status Code: " + e.ErrorCode);
Console.WriteLine(e.StackTrace);
}
}
}
```
### Error Handling and Warnings
The New SDK handles errors and warnings differently. See the table below for a breakdown of the changes:
| Type | Legacy SDK | New SDK |
| -------- | ------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- |
| Errors | Uses `ErrorException` class
Provides:
| Uses `ApiException` class
Provides:
- Error Code
- Error Message
- Headers
|
| Warnings | Uses `Client` class list of warnings objects (`Client.Warnings`)
- Logged based on user preference
| Uses `WarningResponse` class - Passed in response object and and can be looped through and logged when warnings are present
|
#### Error Handling
Errors are an instance of [Dropbox.Sign.Client.ApiException](https://github.com/hellosign/dropbox-sign-dotnet/blob/main/src/Dropbox.Sign/Client/ApiException.cs) with its `ErrorContent` getter returning an instance of [Dropbox.Sign.Model.ErrorResponse](https://github.com/hellosign/dropbox-sign-dotnet/blob/main/src/Dropbox.Sign/Model/ErrorResponse.cs) class and should be handled using Try/Catch blocks.
```csharp Legacy SDK - Error Handling
var client = new Client(apiKey);
// Set invalid email address to cause error
string emailAddress = "dropbox.com";
try
{
var account = client.VerifyAccount(emailAddress);
Console.WriteLine(account);
}
// Use the ErrorException class to display error name and message
catch(HelloSign.ErrorException e)
{
Console.WriteLine("Status Code: " + e.ErrorName);
Console.WriteLine("Exception when calling Dropbox Sign API: " + e.Message);
}
```
```csharp New SDK - Error Handling
using Dropbox.Sign.Api;
using Dropbox.Sign.Client;
public class Example
{
public static void Main()
{
var config = new Configuration();
// Configure HTTP basic authorization: api_key
config.Username = "YOUR_API_KEY";
// or, configure Bearer authorization: oauth2
// config.AccessToken = "YOUR_BEARER_TOKEN";
var accountApi = new AccountApi(config);
try
{
var result = accountApi.AccountGet(null, "jack@example.com");
Console.WriteLine(result);
}
catch (ApiException e)
{
Console.WriteLine("Exception when calling Dropbox Sign API: " + e.Message);
Console.WriteLine("Status Code: " + e.ErrorCode);
Console.WriteLine(e.StackTrace);
}
}
}
```
#### Warnings
Warnings are a list of [Dropbox.Sign.Model.WarningResponse](https://github.com/hellosign/dropbox-sign-dotnet/blob/main/src/Dropbox.Sign/Model/WarningResponse.cs).
```csharp Legacy SDK - Warnings
// Client setup
var client = new Client(apiKey);
var request = new SignatureRequest();
request.Subject = "The NDA we talked about";
request.Message = "Please sign this NDA and then we can discuss more. Let me know if you have any questions.";
request.Title = "NDA with Acme Co.";
request.AddSigner("jack@dropboxsign.com", "Jack");
request.AddSigner("jill@dropboxsign.com", "Jill");
request.AddFile("c:\users\me\My Documents\nda.txt");
// Adjusted parameters so that form field is out of bounds of the document to cause warning
FormField formField1 = new FormField("uniqueIeHere_1", "signature", 1, 45, 985, 270, 40, true, 0, null, null, null);
request.AddFormField(formField1);
FormField formField2 = new FormField("uniqueIdHere_2", "signature", 1, 16, 100, 112, 40, true, 1, null, null, null);
request.AddFormField(formField2);
request.TestMode = true;
// Send request
var response = client.SendSignatureRequest(request, clientId);
Console.WriteLine("New Embedded Signature Request ID: " + response.SignatureRequestId);
requestId = response.SignatureRequestId;
int num = 1;
// Loop through warnings in the Client instance
foreach (var warning in client.Warnings)
{
Console.WriteLine($"{num}: {warning.WarningName} - {warning.WarningMsg}");
num++;
}
```
```csharp New SDK - Warnings
using Dropbox.Sign.Api;
using Dropbox.Sign.Client;
using Dropbox.Sign.Model;
public class Example
{
public static void Main()
{
var config = new Configuration();
// Configure HTTP basic authorization: api_key
config.Username = "YOUR_API_KEY";
// or, configure Bearer authorization: oauth2
// config.AccessToken = "YOUR_BEARER_TOKEN";
var signatureRequestApi = new SignatureRequestApi(config);
var signer1 = new SubSignatureRequestSigner(
emailAddress: "jack@dropboxsign.com",
name: "Jack",
order: 0
);
var signer2 = new SubSignatureRequestSigner(
emailAddress: "jill@dropboxsign.com",
name: "Jill",
order: 1
);
var formField1 = new SubFormFieldsPerDocumentText(
placeholder: null,
autoFillType: null,
linkId: null,
masked: false,
validationType: null,
validationCustomRegex: null,
validationCustomRegexFormatLabel: null,
documentIndex: 0,
apiId: "uniqueIdHere_1",
height: 16,
name: "text_field_1",
page: 1,
required: true,
signer: "0",
width: 100,
x: 112,
// This is outside the bounds of the document and should prompt a warning
y: 928
);
var data = new SignatureRequestSendRequest(
title: "NDA with Acme Co.",
subject: "The NDA we talked about",
message: "Please sign this NDA and then we can discuss more. Let me know if you have any questions.",
signers: new List() { signer1, signer2 },
fileUrls: new List() { "https://app.hellosign.com/docs/example_signature_request.pdf" },
formFieldsPerDocument: new List { formField1 },
testMode: true
);
try
{
var result = signatureRequestApi.SignatureRequestSend(data);
Console.WriteLine(result);
// Warnings are returned with the response object of each new model specific class and can be looped through to be displayed
foreach (var warning in result.Warnings)
{
Console.WriteLine(warning);
}
}
catch (ApiException e)
{
Console.WriteLine("Exception when calling Dropbox Sign API: " + e.Message);
Console.WriteLine("Status Code: " + e.ErrorCode);
Console.WriteLine(e.StackTrace);
}
}
}
```
### Instantiating Objects From Data
There are three ways to instantiate an object.
* You can instantiate a class directly and use constructor arguments
* You can use setter methods
* You can use the `Init()` static method
```csharp New SDK - Using Constructor Arguments
var signer1 = new SubSignatureRequestSigner(
emailAddress: "jack@example.com",
name: "Jack",
order: 0
);
var attachment1 = new SubAttachment(
name: "Attachment 1",
instructions: "Please download this file",
signerIndex: 0
);
attachment1.Required = true;
```
```csharp New SDK - Using setter methods
var signer1 = new SubSignatureRequestSigner();
signer1.EmailAddress = "jack@example.com";
signer1.Name = "Jack";
signer1.Order = 0;
var attachment1 = new SubAttachment();
attachment1.Name = "Attachment 1";
attachment1.Instructions = "Please download this file";
attachment1.SignerIndex = 0;
attachment1.Required = true;
```
```csharp New SDK - Using Init() Static Method
var signer1_json = new JObject(
new JProperty("name", "Signer 1"),
new JProperty("email_address", "s1@example.com")
);
var signer1 = SubSignatureRequestSigner.Init(signer1_json.ToString());
var attachment1_json = new JObject(
new JProperty("name", "Attachment 1"),
new JProperty("instructions", "Please download this file"),
new JProperty("signer_index", 0),
new JProperty("required", true)
);
var attachment1 = SubAttachment.Init(attachment1_json.ToString());
```
`Init()` creates a full object using all the data you pass, including nested data to instantiate nested objects. Any parameters that you do not pass data for will be set to their default value (including `null`).
### Event Callback Helper
A callback helper class is included in the [New SDK repo](https://github.com/hellosign/dropbox-sign-dotnet/tree/main/src/Dropbox.Sign/EventCallbackHelper.cs) to assist in verifying callbacks. The helper simplifies:
1. Checking event authenticity with built in event hash check
2. Displaying event types (account callback vs. app callback)
3. Displaying event messages
The `EventCallbackHelper` and `EventCallbackRequest` classes facilitate parsing of event data and assist in validating that a callback originated from Dropbox Sign.
We will send event callback payloads to you as a `multipart/form-data` request with a single `json` formfield that contains your event callback as a JSON string.
**Example Event Callback Request From US to YOU**
```bash
curl -X POST 'https://example.com/YOUR_EVENT_CALLBACK_URL' \
-F 'json={"event":{"event_type":"account_confirmed","event_time":"1669926463","event_hash":"ff8b03439122f9160500c3fb855bdee5a9ccba5fff27d3b258745d8f3074832f","event_metadata":{"related_signature_id":null,"reported_for_account_id":"6421d70b9bd45059fa207d03ab8d1b96515b472c","reported_for_app_id":null,"event_message":null}}}'
```
**Example JSON Payload**
```json
{
"event": {
"event_type": "account_confirmed",
"event_time": "1669926463",
"event_hash": "ff8b03439122f9160500c3fb855bdee5a9ccba5fff27d3b258745d8f3074832f",
"event_metadata": {
"related_signature_id": null,
"reported_for_account_id": "6421d70b9bd45059fa207d03ab8d1b96515b472c",
"reported_for_app_id": null,
"event_message": null
}
}
}
```
**How to use the EventCallbackHelper**
```csharp
using Newtonsoft.Json;
using Dropbox.Sign.Model;
using Dropbox.Sign;
public class Example
{
public static void Main()
{
// use your API key
var apiKey = "324e3b0840f065eb51f3fd63231d0d33daa35d4ed10d27718839e81737065782";
// callbackData represents data we send to you
var callbackData = Request.Form["json"];;
var callbackEvent = EventCallbackRequest.Init(callbackData);
// verify that a callback came from HelloSign.com
if (EventCallbackHelper.IsValid(apiKey, callbackEvent))
{
// one of "account_callback" or "api_app_callback"
var callbackType = EventCallbackHelper.GetCallbackType(callbackEvent);
// do your magic below!
}
}
}
```
## Differences from Legacy SDK
This section highlights larger changes to be aware of when migrating to the new SDK.
### Form Fields per Document
The Form Fields per Document parameter has changed from a two dimensional array, to a one dimensional array—allowing you to designate which file you to add the field to using `document_index`. You can learn more about this change here: [Form Fields per Document](/docs/sd-ks/open-api/form-fields-per-document).
```csharp Legacy SDK - Form Fields Per Document
var request = new SignatureRequest();
request.Title = "NDA with Acme Co.";
request.Subject = "The NDA we talked about";
request.Message = "Please sign this NDA and then we can discuss more. Let me know if you have any questions.";
request.AddSigner("jack@example.com", "Jack");
request.AddSigner("jill@example.com", "Jill");
request.AddFile("https://app.hellosign.com/docs/example_signature_request.pdf").WithFields(
// id type page x y w h req signer
new FormField("sig1", FormField.TypeSignature, 1, 140, 72, 225, 52, true, 0),
new FormField("sig2", FormField.TypeSignature, 1, 140, 144, 225, 52, true, 1)
);
request.TestMode = true;
var response = client.CreateEmbeddedSignatureRequest(request, clientId);
```
```csharp New SDK - Form Fields per Document
using System;
using Dropbox.Sign.Api;
using Dropbox.Sign.Client;
using Dropbox.Sign.Model;
public class Example
{
public static void Main()
{
var config = new Configuration();
config.Username = "YOUR_API_KEY";
var signatureRequestApi = new SignatureRequestApi(config);
var signer1 = new SubSignatureRequestSigner(
emailAddress: "example+1@dropbox.com",
name: "Jack",
order: 0
);
var formField1 = new SubFormFieldsPerDocumentText(
documentIndex: 0,
apiId: "134asdf",
required: true,
signer: 0,
width: 100,
height: 16,
x: 112,
y: 700,
page: 1,
placeholder: "Full Name",
validationType: "letters_only"
);
var formField2 = new SubFormFieldsPerDocumentTextMerge(
documentIndex: 0,
apiId: "5678yuio",
name: "Address",
required: true,
signer: 0,
width: 100,
height: 16,
x: 222,
y: 700,
page: 1
);
var formField3 = new SubFormFieldsPerDocumentSignature(
documentIndex: 0,
apiId: "zxcvuip",
required: true,
signer: 1,
width: 150,
height: 30,
x: 400,
y: 715,
page: 2
);
var data = new SignatureRequestSendRequest(
title: "NDA with Acme Co.",
subject: "The NDA we talked about",
message: "Please sign this NDA and then we can discuss more. Let me know if you have any questions.",
signers: new List() { signer1 },
fileUrls: new List() { "https://app.hellosign.com/docs/example_signature_request.pdf" },
formFieldsPerDocument: new List { formField1, formField2, formField3 },
testMode: true
);
try
{
var result = signatureRequestApi.SignatureRequestSend(data);
Console.WriteLine(result);
}
catch (ApiException e)
{
Console.WriteLine("Exception when calling Dropbox Sign API: " + e.Message);
Console.WriteLine("Status Code: " + e.ErrorCode);
Console.WriteLine(e.StackTrace);
}
}
}
```
#### Instantiating the Correct Field Class
There are several different types of form fields you can define, identified by the value of the `type` field and a few ways to instantiate the correct object when making an API request.
The different classes for each type are:
| Field Type | Class |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| checkbox | [SubFormFieldsPerDocumentCheckbox](https://github.com/hellosign/dropbox-sign-dotnet/blob/main/src/Dropbox.Sign/Model/SubFormFieldsPerDocumentCheckbox.cs) |
| checkbox-merge | [SubFormFieldsPerDocumentCheckboxMerge](https://github.com/hellosign/dropbox-sign-dotnet/blob/main/src/Dropbox.Sign/Model/SubFormFieldsPerDocumentCheckboxMerge.cs) |
| date\_signed | [SubFormFieldsPerDocumentDateSigned](https://github.com/hellosign/dropbox-sign-dotnet/blob/main/src/Dropbox.Sign/Model/SubFormFieldsPerDocumentDateSigned.cs) |
| dropdown | [SubFormFieldsPerDocumentDropdown](https://github.com/hellosign/dropbox-sign-dotnet/blob/main/src/Dropbox.Sign/Model/SubFormFieldsPerDocumentDropdown.cs) |
| hyperlink | [SubFormFieldsPerDocumentHyperlink](https://github.com/hellosign/dropbox-sign-dotnet/blob/main/src/Dropbox.Sign/Model/SubFormFieldsPerDocumentHyperlink.cs) |
| initials | [SubFormFieldsPerDocumentInitials](https://github.com/hellosign/dropbox-sign-dotnet/blob/main/src/Dropbox.Sign/Model/SubFormFieldsPerDocumentInitials.cs) |
| radio | [SubFormFieldsPerDocumentRadio](https://github.com/hellosign/dropbox-sign-dotnet/blob/main/src/Dropbox.Sign/Model/SubFormFieldsPerDocumentRadio.cs) |
| signature | [SubFormFieldsPerDocumentSignature](https://github.com/hellosign/dropbox-sign-dotnet/blob/main/src/Dropbox.Sign/Model/SubFormFieldsPerDocumentSignature.cs) |
| text | [SubFormFieldsPerDocumentText](https://github.com/hellosign/dropbox-sign-dotnet/blob/main/src/Dropbox.Sign/Model/SubFormFieldsPerDocumentText.cs) |
| text-merge | [SubFormFieldsPerDocumentTextMerge](https://github.com/hellosign/dropbox-sign-dotnet/blob/main/src/Dropbox.Sign/Model/SubFormFieldsPerDocumentTextMerge.cs) |
**You can use `::init()` on the base request class**
```csharp
var dataDict = new Dictionary()
{
["signers"] = new List>() {
new Dictionary()
{
["email_address"] = "example+1@dropbox.com",
["name"] = "Jack",
["order"] = 0,
},
},
["form_fields_per_document"] = new List>() {
new Dictionary()
{
["type"] = "signature",
["document_index"] = 0,
["api_id"] = "4688957689",
["name"] = "signature1",
["x"] = 5,
["y"] = 7,
["width"] = 60,
["height"] = 30,
["required"] = true,
["signer"] = 0,
["page"] = 1,
}
},
};
var data = SignatureRequestSendRequest.Init(JsonConvert.SerializeObject(dataDict));
```
**You can use `::init()` on the field class**
```csharp
var formField1Dict = new Dictionary()
{
["type"] = "signature",
["document_index"] = 0,
["api_id"] = "4688957689",
["name"] = "signature1",
["x"] = 5,
["y"] = 7,
["width"] = 60,
["height"] = 30,
["required"] = true,
["signer"] = 0,
["page"] = 1,
};
var formField1 = SubFormFieldsPerDocumentSignature.Init(
JsonConvert.SerializeObject(formField1Dict)
);
```
**You can instantiate the class directly**
```csharp
var formField1 = new SubFormFieldsPerDocumentSignature(
documentIndex: 0,
apiId: "4688957689",
name: "signature1",
x: 5,
y: 7,
width: 60,
height: 30,
required: true,
signer: 0,
page: 1
);
```
**Form Fields per Document Examples using the new SDK:**
```csharp Signature
var formField1Dict = new Dictionary()
{
["document_index"] = 0,
["api_id"] = "4688957689",
["name"] = "signature1",
["x"] = 5,
["y"] = 7,
["width"] = 60,
["height"] = 30,
["required"] = true,
["signer"] = 0,
["page"] = 1,
};
var formField1 = SubFormFieldsPerDocumentSignature.Init(
JsonConvert.SerializeObject(formField1Dict)
);
```
```csharp Initials
var formField1Dict = new Dictionary()
{
["document_index"] = 0,
["api_id"] = "4688957689",
["name"] = "initials1",
["x"] = 5,
["y"] = 7,
["width"] = 60,
["height"] = 30,
["required"] = true,
["signer"] = 0,
["page"] = 1,
};
var formField1 = SubFormFieldsPerDocumentInitials.Init(
JsonConvert.SerializeObject(formField1Dict)
);
```
```csharp Date Signed
var formField1Dict = new Dictionary()
{
["document_index"] = 0,
["api_id"] = "4688957689",
["name"] = "date_signed1",
["x"] = 5,
["y"] = 7,
["width"] = 60,
["height"] = 30,
["required"] = true,
["signer"] = 0,
["page"] = 1,
};
var formField1 = SubFormFieldsPerDocumentDateSigned.Init(
JsonConvert.SerializeObject(formField1Dict)
);
```
```csharp Text
var formField1Dict = new Dictionary()
{
["document_index"] = 0,
["api_id"] = "4688957689",
["name"] = "text1",
["x"] = 5,
["y"] = 7,
["width"] = 60,
["height"] = 30,
["required"] = true,
["signer"] = 0,
["page"] = 1,
};
var formField1 = SubFormFieldsPerDocumentText.Init(
JsonConvert.SerializeObject(formField1Dict)
);
```
```csharp Text Merge
var firstNameDict = new Dictionary()
{
["name"] = "first_name",
["value"] = "John"
};
var customField1 = SubCustomField.Init(
JsonConvert.SerializeObject(firstNameDict)
);
var formField1Dict = new Dictionary()
{
["document_index"] = 0,
["api_id"] = "4688957689",
["name"] = "first_name",
["x"] = 5,
["y"] = 7,
["width"] = 60,
["height"] = 30,
["required"] = true,
["signer"] = 0,
["page"] = 1,
};
var formField1 = SubFormFieldsPerDocumentTextMerge.Init(
JsonConvert.SerializeObject(formField1Dict)
);
```
```csharp Checkbox
var formField1Dict = new Dictionary()
{
["document_index"] = 0,
["api_id"] = "4688957689",
["name"] = "checkbox1",
["x"] = 5,
["y"] = 7,
["width"] = 60,
["height"] = 30,
["required"] = true,
["signer"] = 0,
["page"] = 1,
};
var formField1 = SubFormFieldsPerDocumentCheckbox.Init(
JsonConvert.SerializeObject(formField1Dict)
);
```
```csharp Checkbox Merge
var customField1 = SubCustomField.Init(
JsonConvert.SerializeObject(isRegisteredDict)
);
var formField1Dict = new Dictionary()
{
["document_index"] = 0,
["api_id"] = "4688957689",
["name"] = "is_registered",
["x"] = 5,
["y"] = 7,
["width"] = 60,
["height"] = 30,
["required"] = true,
["signer"] = 0,
["page"] = 1,
};
var formField1 = SubFormFieldsPerDocumentCheckboxMerge.Init(
JsonConvert.SerializeObject(formField1Dict)
);
```
```csharp Dropdown
var formField1Dict = new Dictionary()
{
["document_index"] = 0,
["api_id"] = "4688957689",
["name"] = "dropdown1",
["x"] = 5,
["y"] = 7,
["width"] = 60,
["height"] = 30,
["required"] = true,
["signer"] = 0,
["page"] = 1,
["options"] = new List(){ "Option 1","Option 2" },
["content"] = "Option 2",
};
var formField1 = SubFormFieldsPerDocumentDropdown.Init(
JsonConvert.SerializeObject(formField1Dict)
);
```
```csharp Hyperlink
var formField1Dict = new Dictionary()
{
["document_index"] = 0,
["api_id"] = "4688957689",
["name"] = "hyperlink1",
["x"] = 5,
["y"] = 7,
["width"] = 60,
["height"] = 30,
["required"] = true,
["signer"] = "me_now",
["page"] = 1,
["content"] = "Click me!",
["content_url"] = "http://example.com",
};
var formField1 = SubFormFieldsPerDocumentHyperlink.Init(
JsonConvert.SerializeObject(formField1Dict)
);
```
```csharp Radio
var formField1Dict = new Dictionary()
{
["document_index"] = 0,
["api_id"] = "4688957689",
["name"] = "radio1",
["x"] = 5,
["y"] = 7,
["width"] = 60,
["height"] = 30,
["required"] = true,
["signer"] = 0,
["page"] = 1,
["group"] = "RadioItemGroup1",
["is_checked"] = true,
};
var formField1 = SubFormFieldsPerDocumentRadio.Init(
JsonConvert.SerializeObject(formField1Dict)
);
var formField2Dict = new Dictionary()
{
["document_index"] = 0,
["api_id"] = "46876587",
["name"] = "radio2",
["x"] = 5,
["y"] = 50,
["width"] = 60,
["height"] = 30,
["required"] = true,
["signer"] = 0,
["page"] = 1,
["group"] = "RadioItemGroup1",
["is_checked"] = false,
};
var formField2 = SubFormFieldsPerDocumentRadio.Init(
JsonConvert.SerializeObject(formField1Dict)
);
var formFieldGroupDict = new Dictionary()
{
["group_id"] = "RadioItemGroup1",
["group_label"] = "Radio Item Group 1",
["requirement"] = "require_0-1",
};
var formFieldGroup = SubFormFieldGroup.Init(
JsonConvert.SerializeObject(formFieldGroupDict)
);
```
### "role" Value in `signers` Object
In the Legacy SDK when making a Signature Request using a Template the `signers` property was an object with the role name as the key. In the new SDK the role value has been moved into the signer object itself.
For example for the [/signature\_request/send\_with\_template](/api/signature-request/send-with-template) endpoint the `signers` property could be represented as:
```json Legacy SDK - signers with Roles
{
"signers": {
"Client": {
"name": "George",
"email_address": "george@example.com"
},
"Manager": {
"name": "Bob",
"email_address": "bob@example.com"
}
}
}
```
```json New SDK - signers with Roles
{
"signers": [
{
"role": "Client",
"name": "George",
"email_address": "george@example.com"
},
{
"role": "Manager",
"name": "Bob",
"email_address": "bob@example.com"
}
]
}
```
Using the new SDK you would now send this data as follows:
```csharp New SDK - signers with Roles Example #1
using Dropbox.Sign.Api;
using Dropbox.Sign.Client;
using Dropbox.Sign.Model;
using Newtonsoft.Json;
public class Example
{
public static void Main()
{
var config = new Configuration();
config.Username = "YOUR_API_KEY";
var signatureRequestApi = new SignatureRequestApi(config);
var signer1Dict = new Dictionary()
{
["role"] = "Client",
["name"] = "George",
["email_address"] = "george@example.com",
};
var signer1 = SubSignatureRequestTemplateSigner.Init(
JsonConvert.SerializeObject(signer1Dict)
);
var signer2Dict = new Dictionary()
{
["role"] = "Manager",
["name"] = "Bob",
["email_address"] = "bob@example.com",
};
var signer2 = SubSignatureRequestTemplateSigner.Init(
JsonConvert.SerializeObject(signer2Dict)
);
var data = new SignatureRequestSendWithTemplateRequest(
templateIds: new List(){"c26b8a16784a872da37ea946b9ddec7c1e11dff6"},
subject: "Purchase Order",
message: "Glad we could come to an agreement.",
signers: new List(){signer1, signer2}
);
try
{
var result = signatureRequestApi.SignatureRequestSendWithTemplate(data);
Console.WriteLine(result);
}
catch (ApiException e)
{
Console.WriteLine("Exception when calling Dropbox Sign API: " + e.Message);
Console.WriteLine("Status Code: " + e.ErrorCode);
Console.WriteLine(e.StackTrace);
}
}
}
```
```csharp New SDK - signers with Roles Example #2
using Dropbox.Sign.Api;
using Dropbox.Sign.Client;
using Dropbox.Sign.Model;
public class Example
{
public static void Main()
{
var config = new Configuration();
config.Username = "YOUR_API_KEY";
var signatureRequestApi = new SignatureRequestApi(config);
var signer1 = new SubSignatureRequestTemplateSigner(
role: "Client",
name: "George",
emailAddress: "george@example.com"
);
var signer2 = new SubSignatureRequestTemplateSigner(
role: "Manager",
name: "Bob",
emailAddress: "bob@example.com"
);
var data = new SignatureRequestSendWithTemplateRequest(
templateIds: new List(){"c26b8a16784a872da37ea946b9ddec7c1e11dff6"},
subject: "Purchase Order",
message: "Glad we could come to an agreement.",
signers: new List(){signer1, signer2}
);
try
{
var result = signatureRequestApi.SignatureRequestSendWithTemplate(data);
Console.WriteLine(result);
}
catch (ApiException e)
{
Console.WriteLine("Exception when calling Dropbox Sign API: " + e.Message);
Console.WriteLine("Status Code: " + e.ErrorCode);
Console.WriteLine(e.StackTrace);
}
}
}
```
### "role" Value in `ccs` Property
In the Legacy SDK when making a Signature Request using a Template the `ccs` property was an object with the role name as the key. In the new SDK the role value has been moved into the cc object itself, alongside a new `email_address` property.
For example for the [/signature\_request/send\_with\_template](/api/signature-request/send-with-template) endpoint the `ccs` property could be represented as:
```json Legacy SDK - ccs
{
"ccs": {
"Client": "george@example.com",
"Manager": "bob@example.com"
}
}
```
```json New SDK - ccs
{
"ccs": [
{
"role": "Client",
"email_address": "george@example.com"
},
{
"role": "Manager",
"email_address": "bob@example.com"
}
]
}
```
Using the new SDK you would now send this data as follows:
```csharp New SDK - ccs Example #1
using Dropbox.Sign.Api;
using Dropbox.Sign.Client;
using Dropbox.Sign.Model;
using Newtonsoft.Json;
public class Example
{
public static void Main()
{
var config = new Configuration();
config.Username = "YOUR_API_KEY";
var signatureRequestApi = new SignatureRequestApi(config);
var signer1Dict = new Dictionary()
{
["role"] = "Client",
["name"] = "George",
["email_address"] = "george@example.com",
};
var signer1 = SubSignatureRequestTemplateSigner.Init(
JsonConvert.SerializeObject(signer1Dict)
);
var signer2Dict = new Dictionary()
{
["role"] = "Manager",
["name"] = "Bob",
["email_address"] = "bob@example.com",
};
var signer2 = SubSignatureRequestTemplateSigner.Init(
JsonConvert.SerializeObject(signer2Dict)
);
var cc1Dict = new Dictionary()
{
["role"] = "Client",
["email_address"] = "george@example.com",
};
var cc1 = SubCC.Init(
JsonConvert.SerializeObject(cc1Dict)
);
var cc2Dict = new Dictionary()
{
["role"] = "Manager",
["email_address"] = "bob@example.com",
};
var cc2 = SubCC.Init(
JsonConvert.SerializeObject(cc2Dict)
);
var data = new SignatureRequestSendWithTemplateRequest(
templateIds: new List(){"c26b8a16784a872da37ea946b9ddec7c1e11dff6"},
subject: "Purchase Order",
message: "Glad we could come to an agreement.",
signers: new List(){signer1, signer2},
ccs: new List(){cc1, cc2}
);
try
{
var result = signatureRequestApi.SignatureRequestSendWithTemplate(data);
Console.WriteLine(result);
}
catch (ApiException e)
{
Console.WriteLine("Exception when calling Dropbox Sign API: " + e.Message);
Console.WriteLine("Status Code: " + e.ErrorCode);
Console.WriteLine(e.StackTrace);
}
}
}
```
```csharp New SDK - ccs Example #2
using Dropbox.Sign.Api;
using Dropbox.Sign.Client;
using Dropbox.Sign.Model;
public class Example
{
public static void Main()
{
var config = new Configuration();
config.Username = "YOUR_API_KEY";
var signatureRequestApi = new SignatureRequestApi(config);
var signer1 = new SubSignatureRequestTemplateSigner(
role: "Client",
name: "George",
emailAddress: "george@example.com"
);
var signer2 = new SubSignatureRequestTemplateSigner(
role: "Manager",
name: "Bob",
emailAddress: "bob@example.com"
);
var cc1 = new SubCC(
role: "Client",
emailAddress: "george@example.com"
);
var cc2 = new SubCC(
role: "Manager",
emailAddress: "bob@example.com"
);
var data = new SignatureRequestSendWithTemplateRequest(
templateIds: new List(){"c26b8a16784a872da37ea946b9ddec7c1e11dff6"},
subject: "Purchase Order",
message: "Glad we could come to an agreement.",
signers: new List(){signer1, signer2},
ccs: new List(){cc1, cc2}
);
try
{
var result = signatureRequestApi.SignatureRequestSendWithTemplate(data);
Console.WriteLine(result);
}
catch (ApiException e)
{
Console.WriteLine("Exception when calling Dropbox Sign API: " + e.Message);
Console.WriteLine("Status Code: " + e.ErrorCode);
Console.WriteLine(e.StackTrace);
}
}
}
```
### "name" Value in `custom_fields` Property
In the Legacy SDK when making a Signature Request with the `custom_fields` property it was an object with the name as the key. In the new SDK the name value has been moved into the custom\_field object itself.
For example for the [/signature\_request/send\_with\_template](/api/signature-request/send-with-template) endpoint the `custom_fields` property could be represented as:
```json Legacy SDK - custom_fields
{
"custom_fields": {
"company": {
"value": "ABC Corp",
"required": true
}
}
}
```
```json New SDK - custom_fields
{
"custom_fields": [
{
"name": "company",
"value": "ABC Corp",
"required": true
}
]
}
```
Using the new SDK you would now send this data as follows:
```csharp New SDK - custom_fields Example #1
using Dropbox.Sign.Api;
using Dropbox.Sign.Client;
using Dropbox.Sign.Model;
using Newtonsoft.Json;
public class Example
{
public static void Main()
{
var config = new Configuration();
config.Username = "YOUR_API_KEY";
var signatureRequestApi = new SignatureRequestApi(config);
var signer1Dict = new Dictionary()
{
["role"] = "Client",
["name"] = "George",
["email_address"] = "george@example.com",
};
var signer1 = SubSignatureRequestTemplateSigner.Init(
JsonConvert.SerializeObject(signer1Dict)
);
var signer2Dict = new Dictionary()
{
["role"] = "Manager",
["name"] = "Bob",
["email_address"] = "bob@example.com",
};
var signer2 = SubSignatureRequestTemplateSigner.Init(
JsonConvert.SerializeObject(signer2Dict)
);
var customField1Dict = new Dictionary()
{
["name"] = "company",
["value"] = "ABC Corp",
["required"] = true,
};
var customField1 = SubCustomField.Init(
JsonConvert.SerializeObject(customField1Dict)
);
var data = new SignatureRequestSendWithTemplateRequest(
templateIds: new List(){"c26b8a16784a872da37ea946b9ddec7c1e11dff6"},
subject: "Purchase Order",
message: "Glad we could come to an agreement.",
signers: new List(){signer1, signer2},
customFields: new List(){customField1}
);
try
{
var result = signatureRequestApi.SignatureRequestSendWithTemplate(data);
Console.WriteLine(result);
}
catch (ApiException e)
{
Console.WriteLine("Exception when calling Dropbox Sign API: " + e.Message);
Console.WriteLine("Status Code: " + e.ErrorCode);
Console.WriteLine(e.StackTrace);
}
}
}
```
```csharp New SDK - custom_fields Example #2
using Dropbox.Sign.Api;
using Dropbox.Sign.Client;
using Dropbox.Sign.Model;
public class Example
{
public static void Main()
{
var config = new Configuration();
config.Username = "YOUR_API_KEY";
var signatureRequestApi = new SignatureRequestApi(config);
var signer1 = new SubSignatureRequestTemplateSigner(
role: "Client",
name: "George",
emailAddress: "george@example.com"
);
var signer2 = new SubSignatureRequestTemplateSigner(
role: "Manager",
name: "Bob",
emailAddress: "bob@example.com"
);
var customField1 = new SubCustomField(
name: "company",
value: "ABC Corp",
required: true
);
var data = new SignatureRequestSendWithTemplateRequest(
templateIds: new List(){"c26b8a16784a872da37ea946b9ddec7c1e11dff6"},
subject: "Purchase Order",
message: "Glad we could come to an agreement.",
signers: new List(){signer1, signer2},
customFields: new List(){customField1}
);
try
{
var result = signatureRequestApi.SignatureRequestSendWithTemplate(data);
Console.WriteLine(result);
}
catch (ApiException e)
{
Console.WriteLine("Exception when calling Dropbox Sign API: " + e.Message);
Console.WriteLine("Status Code: " + e.ErrorCode);
Console.WriteLine(e.StackTrace);
}
}
}
```
### `template_id` to `template_ids`
The `template_id` parameter has been removed. You must now use `template_ids`.
| Legacy SDK version | New SDK Version |
| --------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| Template ID (`template_id`) is passed as a singular string:
template\_id : "1234567890"
| Template ID is passed as an array of strings (`template_ids`):
template\_ids:\["1234567890"]
|
### `file` to `files`
The `file` parameter has been renamed to `files`. Usage remains the same.
Use `.Files([...])`;
### `file_url` to `file_urls`
The `file_url` parameter has been renamed to `file_urls`. Usage remains the same.
Use `.FileUrls([...])`;
### Interacting with Files
The new SDK version introduces some new patterns around uploading and downloading files. You can read about them more in depth here: [Interacting with Files](/docs/sd-ks/open-api/interacting-with-files).
#### Uploading Files
The file upload process changed with the newly-adopted OpenAPI-specification — it is no longer possible to pass file paths into file upload methods. You can learn more about this update here: [New Patterns: Interacting with Files](/docs/sd-ks/open-api/interacting-with-files).
The New Dotnet SDK only accepts files passed as binary. For more information, see Interacting with Files.
| Behavior | Legacy SDK | New SDK |
| ----------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------- |
| File Upload | - Pass file path with `file` parameter
| - `file` parameter does not accept file path
- Requires a binary (List of `System.IO.Stream`)
|
Please see the comments in the New Dotnet SDK code sample below for detailed description of passing the file as binary.
```csharp Legacy SDK - File Upload
var request = new SignatureRequest();
request.Title = "NDA with Acme Co.";
request.Subject = "The NDA we talked about";
request.Message = "Please sign this NDA and then we can discuss more. Let me know if you have any questions.";
request.AddSigner("jack@example.com", "Jack");
request.AddFile("c:\users\me\My Documents\nda.pdf");
request.TestMode = true;
var response = client.SendSignatureRequest(request);
Console.WriteLine("New Signature Request ID: " + response.SignatureRequestId);
```
```csharp New SDK - File Upload
var config = new Configuration();
config.Username = "YOUR_API_KEY";
var sigReqApi = new SignatureRequestApi(config);
var signer1 = new SubSignatureRequestSigner(
emailAddress: "jack@dropboxsign.com",
name: "Jack",
order: 0
);
// Create a file stream by opening and reading the specified file
var file = new FileStream(
@"c:\users\me\My Documents\nda.pdf",
FileMode.Open,
FileAccess.Read,
FileShare.Read
);
// Not all code shown for this signature request
// Pass stream into the file parameter as a new System.IO.Stream list
var data = new SignatureRequestSendRequest(
title: "NDA with Acme Co.",
subject: "The NDA we talked about",
message: "Please sign this NDA and then we can discuss more. Let me know if you have any questions.",
signers: new List() { signer1 },
files: new List() { file },
testMode: true
);
// Send signature request
try
{
var result = sigReqApi.SignatureRequestSend(data);
var signatureRequestId = result.SignatureRequest.SignatureRequestId;
Console.WriteLine(signatureRequestId);
Console.WriteLine(result);
Console.ReadLine();
}
catch (ApiException e)
{
Console.WriteLine("Exception when calling Dropbox Sign API: " + e.Message);
Console.WriteLine("Status Code: " + e.ErrorCode);
Console.WriteLine(e.StackTrace);
}
```
#### Downloading Files
The New Dotnet SDK downloads files differently. You can learn more about why this change was made here: Interacting with Files.
Switch between file format using parameters sent to a single endpoint for either downloading files or downloading templates.
Switch between file formats by calling an endpoint specific to that format. You can see how those are split up in the table below.
| Original Endpoint | New Endpoints |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Download Files | - [Download Files](/api/signature-request/files)
- [Download Files as Data Uri](/api/signature-request/files-as-data-uri)
- [Download Files as File Url](/api/signature-request/files-as-file-url)
|
| Get Template Files | - [Get Template Files](/api/template/files)
- [Get Template Files as Data Uri](/api/template/files-as-data-uri)
- [Get Template Files as File Url](/api/template/files-as-file-url)
|
```csharp Legacy SDK - Download
// 1. Download a merged PDF
var bytes = client.DownloadSignatureRequestFiles("SIGNATURE REQUEST ID HERE");
// 2. Download a ZIP containing individual unmerged PDFs
var bytes = client.DownloadSignatureRequestFiles(
"SIGNATURE REQUEST ID HERE",
SignatureRequest.FileType.ZIP
);
```
```csharp New SDK - Download
// 1. Download file as a merged PDF
// Set a variable to a new SignatureRequestApi instance
var sigReqApi = new SignatureRequestApi(config);
// Set your signature request ID for the request you would like to download files from
var signatureRequestId = "fa5c8a0b0f492d768749333ad6fcc214c111e967";
// Send request (returns System.IO.MemoryStream of PDF)
try
{
var result = sigReqApi.SignatureRequestFiles(signatureRequestId);
Console.WriteLine(result);
}
catch (ApiException e)
{
Console.WriteLine("Exception when calling Dropbox Sign API: " + e.Message);
Console.WriteLine("Status Code: " + e.ErrorCode);
Console.WriteLine(e.StackTrace);
}
```
```csharp New SDK - Data URI
// 2. Download a PDF as a Data URI
// Set a variable to a new SignatureRequestApi instance
var sigReqApi = new SignatureRequestApi(config);
// Set your signature request ID for the request you would like to download files from
var signatureRequestId = "fa5c8a0b0f492d768749333ad6fcc214c111e967";
// Send request (returns PDF as a json of the data URI representing the base64 encoded file)
try
{
var result = sigReqApi.SignatureRequestFilesAsDataUri(signatureRequestId);
Console.WriteLine(result);
}
catch (ApiException e)
{
Console.WriteLine("Exception when calling Dropbox Sign API: " + e.Message);
Console.WriteLine("Status Code: " + e.ErrorCode);
Console.WriteLine(e.StackTrace);
}
```
```csharp New SDK - Data URL
// 3. Download a PDF as a Data URL
// Set a variable to a new SignatureRequestApi instance
var sigReqApi = new SignatureRequestApi(config);
// Set your signature request ID for the request you would like to download files from
var signatureRequestId = "fa5c8a0b0f492d768749333ad6fcc214c111e967";
// Send request (returns a URL to download the PDF)
try
{
var result = sigReqApi.SignatureRequestFilesAsFileUrl(signatureRequestId);
Console.WriteLine(result);
}
catch (ApiException e)
{
Console.WriteLine("Exception when calling Dropbox Sign API: " + e.Message);
Console.WriteLine("Status Code: " + e.ErrorCode);
Console.WriteLine(e.StackTrace);
}
```
**Downloading Templates**
```csharp Legacy SDK - Download
// 1. Download a merged PDF
var bytes = client.DownloadTemplateFiles("TEMPLATE ID HERE");
// 2. Download a ZIP containing individual unmerged PDFs
var bytes = client.DownloadTemplateFiles(
"TEMPLATE ID HERE",
SignatureRequest.FileType.ZIP
);
```
```csharp New SDK - Download Template Files
using System;
using System.Collections.Generic;
using Dropbox.Sign.Api;
using Dropbox.Sign.Client;
using Dropbox.Sign.Model;
public class Example
{
public static void Main()
{
var config = new Configuration();
// Configure HTTP basic authorization: api_key
config.Username = "YOUR_API_KEY";
// or, configure Bearer authorization: oauth2
// config.AccessToken = "YOUR_BEARER_TOKEN";
var templateApi = new TemplateApi(config);
var templateId = "f57db65d3f933b5316d398057a36176831451a35";
try
{
var result = templateApi.TemplateFiles(templateId, "pdf");
var fileStream = File.Create("file_response.pdf");
result.Seek(0, SeekOrigin.Begin);
result.CopyTo(fileStream);
fileStream.Close();
}
catch (ApiException e)
{
Console.WriteLine("Exception when calling Dropbox Sign API: " + e.Message);
Console.WriteLine("Status Code: " + e.ErrorCode);
Console.WriteLine(e.StackTrace);
}
}
}
```
```csharp New SDK - Template File as Data Uri
using System;
using System.Collections.Generic;
using Dropbox.Sign.Api;
using Dropbox.Sign.Client;
using Dropbox.Sign.Model;
public class Example
{
public static void Main()
{
var config = new Configuration();
// Configure HTTP basic authorization: api_key
config.Username = "YOUR_API_KEY";
// or, configure Bearer authorization: oauth2
// config.AccessToken = "YOUR_BEARER_TOKEN";
var templateApi = new TemplateApi(config);
var templateId = "f57db65d3f933b5316d398057a36176831451a35";
try
{
var result = templateApi.TemplateFilesAsDataUri(templateId, "pdf", false, false);
Console.WriteLine(result);
}
catch (ApiException e)
{
Console.WriteLine("Exception when calling Dropbox Sign API: " + e.Message);
Console.WriteLine("Status Code: " + e.ErrorCode);
Console.WriteLine(e.StackTrace);
}
}
}
```
```csharp New SDK - Template File as File Url
using System;
using System.Collections.Generic;
using Dropbox.Sign.Api;
using Dropbox.Sign.Client;
using Dropbox.Sign.Model;
public class Example
{
public static void Main()
{
var config = new Configuration();
// Configure HTTP basic authorization: api_key
config.Username = "YOUR_API_KEY";
// or, configure Bearer authorization: oauth2
// config.AccessToken = "YOUR_BEARER_TOKEN";
var templateApi = new TemplateApi(config);
var templateId = "f57db65d3f933b5316d398057a36176831451a35";
try
{
var result = templateApi.TemplateFilesAsFileUrl(templateId, "pdf", false, false);
Console.WriteLine(result);
}
catch (ApiException e)
{
Console.WriteLine("Exception when calling Dropbox Sign API: " + e.Message);
Console.WriteLine("Status Code: " + e.ErrorCode);
Console.WriteLine(e.StackTrace);
}
}
}
```
## Endpoint Mapping
Get a head start migrating or planning your migration using the code examples in this section. We created examples for our most-used endpoints. [Reach out](https://faq.hellosign.com/hc/en-us/requests/new) if you think we're missing an important one.
* [Update API App](#update-api-app)
* [Send Signature Request with Custom Fields](#send-signature-request-with-custom-fields)
* [Send Signature Request with Form Fields Per Document](#send-signature-request-with-form-fields-per-document)
* [List Signature Requests with query parameter](#list-signature-requests-with-query-parameter)
* [Create Embedded Template Draft with Merge Fields](#create-embedded-template-draft-with-merge-fields)
* [Create Embedded Signature Request](#create-embedded-signature-request)
* [Get Embedded Sign URL](#get-embedded-sign-url)
* [Create Embedded Unclaimed Draft with file](#create-embedded-unclaimed-draft-with-file)
### Update API App
```csharp Legacy SDK - Create API App
// The Legacy SDK did not support the Update API App endpoint, but here is an example of how oauth and white labeling options were passed in the Create Api App endpoint
// Inject white_labeling_options into AdditionalParameters
client.AdditionalParameters.Add("white_labeling_options", "{ \"header_background_color\":\"#1A1A1A\", \"page_background_color\": \"#F7F8F9\", \"legal_version\":\"terms2\"}");
// Create an instance of Oauth and set the new Oauth callback URL and scopes
var oauth = new Oauth()
{
CallbackUrl = "https://example.com/oauth",
Scopes = new List()
{
"basic_account_info",
"request_signature"
}
};
// Create new instance of ApiApp
var apiAppApi = new ApiApp();
apiAppApi.Name = "Test App 1";
apiAppApi.Domain = "test1.com";
apiAppApi.Oauth = oauth;
apiAppApi.CallbackUrl = "https://example.com/";
// Send request
var response = client.CreateApiApp(apiAppApi);
Console.WriteLine(response.ClientId);
```
```csharp New SDK - Update API App
var config = new Configuration();
config.Username = "YOUR_API_KEY";
// Create instance of ApiAppApi
var apiAppApi = new ApiAppApi(config);
// Use sub class SubOath to change OAuth properties
var oauth = new SubOAuth(
callbackUrl: "https://example.com/oauth",
scopes: new List() {
SubOAuth.ScopesEnum.BasicAccountInfo,
SubOAuth.ScopesEnum.RequestSignature
}
);
// Use sub class SubWhiteLabelingOptions to update white labeling options
var whiteLabelingOptions = new SubWhiteLabelingOptions(
headerBackgroundColor: "#1A1A1A",
pageBackgroundColor: "#F7F8F9",
legalVersion: SubWhiteLabelingOptions.LegalVersionEnum.Terms2
);
// Build request parameters
var data = new ApiAppUpdateRequest(
name: "Test App 3",
callbackUrl: "https://example.com/",
oauth: oauth,
whiteLabelingOptions: whiteLabelingOptions
);
// Use client ID of API App that you would like to update
var clientId = "c9f2940c399a8089890b2c52c838014f";
// Send request
try
{
var result = apiAppApi.ApiAppUpdate(clientId, data);
Console.WriteLine(result);
}
catch (ApiException e)
{
Console.WriteLine("Exception when calling Dropbox Sign API: " + e.Message);
Console.WriteLine("Status Code: " + e.ErrorCode);
Console.WriteLine(e.StackTrace);
}
```
### Send Signature Request with Custom Fields
```csharp Legacy SDK - Send Signature Request
// Create new instance of TemplateSignatureRequest
var request = new TemplateSignatureRequest();
request.AddTemplate("1cba0c693fe6fc2bdd3b9967f704740e7631696c");
request.Title = "Rental Agreement";
request.Subject = "Contract for new apartment";
request.Message = "Please sign this Rental Agreement.";
request.AddSigner("Client 1", "jack@dropboxsign.com", "Jack");
// Add custom field
request.AddCustomField("Address", "123 Dropbox Drive", "Client 1", true);
request.TestMode = true;
// Send request
var response = client.SendSignatureRequest(request);
Console.WriteLine("New Signature Request ID: " + response.SignatureRequestId);
```
```csharp New SDK - Send Signature Request
var config = new Configuration();
config.Username = "YOUR_API_KEY";
// Create new instance of SignatureRequestApi
var sigReqApi = new SignatureRequestApi(config);
var signer1 = new SubSignatureRequestTemplateSigner(
emailAddress: "jack@dropboxsign.com",
name: "Jack",
role: "Client 1"
);
var signerList1CustomFields = new SubBulkSignerListCustomField(
name: "Address",
value: "123 Dropbox Drive"
);
var data = new SignatureRequestSendWithTemplateRequest(
templateIds: new List() { "1cba0c693fe6fc2bdd3b9967f704740e7631696c" },
title: "Rental Agreement",
subject: "Contract for new apartment",
message: "Please sign this Rental Agreement.",
signers: new List() { signer1 },
testMode: true
);
// Send request
try
{
var result = sigReqApi.SignatureRequestSendWithTemplate(data);
Console.WriteLine(result);
}
catch (ApiException e)
{
Console.WriteLine("Exception when calling Dropbox Sign API: " + e.Message);
Console.WriteLine("Status Code: " + e.ErrorCode);
Console.WriteLine(e.StackTrace);
}
```
### Send Signature Request with Form Fields Per Document
```csharp Legacy SDK - Signature Request with Form Fields
var request = new SignatureRequest();
request.Title = "NDA with Acme Co.";
request.Subject = "The NDA we talked about";
request.Message = "Please sign this NDA and then we can discuss more. Let me know if you have any questions.";
request.AddSigner("jack@example.com", "Jack");
request.AddSigner("jill@example.com", "Jill");
request.AddFile("https://app.hellosign.com/docs/example_signature_request.pdf").WithFields(
// id type page x y w h req signer
new FormField("sig1", FormField.TypeSignature, 1, 140, 72, 225, 52, true, 0),
new FormField("sig2", FormField.TypeSignature, 1, 140, 144, 225, 52, true, 1)
);
request.TestMode = true;
var response = client.CreateEmbeddedSignatureRequest(request, clientId);
```
```csharp New SDK - Signature Request with Form Fields
var config = new Configuration();
config.Username = "YOUR_API_KEY";
// Create new instance of SignatureRequestApi class
var signatureRequestApi = new SignatureRequestApi(config);
// Build parameters of the request using the subclasses
var signer1 = new SubSignatureRequestSigner(
emailAddress: "example+1@dropbox.com",
name: "Jack",
order: 0
);
var signer2 = new SubSignatureRequestSigner(
emailAddress: "example+2@dropbox.com",
name: "Jill",
order: 1
);
var signingOptions = new SubSigningOptions(
draw: true,
type: true,
upload: true,
phone: true,
defaultType: SubSigningOptions.DefaultTypeEnum.Draw
);
var subFieldOptions = new SubFieldOptions(
dateFormat: SubFieldOptions.DateFormatEnum.DDMMYYYY
);
var metadata = new Dictionary()
{
["custom_id"] = 1234,
["custom_text"] = "NDA #9"
};
var formField1 = new SubFormFieldsPerDocumentText(
placeholder: null,
autoFillType: null,
linkId: null,
masked: false,
validationType: null,
validationCustomRegex: null,
validationCustomRegexFormatLabel: null,
documentIndex: 0,
apiId: "uniqueIdHere_1",
height: 16,
name: "text_field_1",
page: 1,
required: true,
signer: "0",
width: 100,
x: 112,
y: 328
);
var formField2 = new SubFormFieldsPerDocumentSignature(
type: "signature",
documentIndex: 0,
apiId: "uniqueIdHere_2",
height: 16,
name: "text_field_1",
page: 1,
required: true,
signer: "1",
width: 100,
x: 112,
y: 150
);
var data = new SignatureRequestSendRequest(
title: "NDA with Acme Co.",
subject: "The NDA we talked about",
message: "Please sign this NDA and then we can discuss more. Let me know if you have any questions.",
signers: new List() { signer1, signer2 },
fileUrls: new List() { "https://app.hellosign.com/docs/example_signature_request.pdf" },
metadata: metadata,
signingOptions: signingOptions,
fieldOptions: subFieldOptions,
formFieldsPerDocument: new List { formField1, formField2 },
testMode: true
);
// Send signature request
try
{
var result = signatureRequestApi.SignatureRequestSend(data);
Console.WriteLine(result);
}
catch (ApiException e)
{
Console.WriteLine("Exception when calling Dropbox Sign API: " + e.Message);
Console.WriteLine("Status Code: " + e.ErrorCode);
Console.WriteLine(e.StackTrace);
}
```
### List Signature Requests with query parameter
```csharp Legacy SDK - List Sig Req
var client = new Client(apiKey);
// Inject additional parameters for account_id and query
client.AdditionalParameters.Add("account_id", "all");
client.AdditionalParameters.Add("query", "complete:true");
var queryList = client.ListSignatureRequests(0, 100);
// Remove injected parameters before next request
client.AdditionalParameters.Remove("account_id");
client.AdditionalParameters.Remove("query");
Console.WriteLine("Found this many signature requests: " + allRequests.NumResults);
foreach (var result in queryList)
{
Console.WriteLine("Signature request: " + result.SignatureRequestId);
if (result.IsComplete) == true) { Console.WriteLine("Signature request is complete.");}
else { Console.WriteLine("Signature request is not complete");}
}
```
```csharp New SDK - List Sig Req
var config = new Configuration();
config.Username = "YOUR_API_KEY";
var signatureRequestApi = new SignatureRequestApi(config);
// Include variables for optional parameters -- please note: query is passed as a string for completed documents
var accountId = "all";
var page = 1;
var pageSize = 10;
var query = "complete:true";
// Send request
try
{
var response = signatureRequestApi.SignatureRequestList(accountId, page, pageSize, query);
Console.WriteLine(response);
}
catch (ApiException e)
{
Console.WriteLine("Exception when calling SignatureRequestApi.SignatureRequestList: " + e.Message);
Console.WriteLine("Status Code: " + e.ErrorCode);
Console.WriteLine(e.StackTrace);
}
```
### Create Embedded Template Draft with Merge Fields
```csharp Legacy SDK - Create Embedded Template Draft
var draft = new EmbeddedTemplateDraft();
draft.TestMode = true;
draft.AddFile(file1, "NDA.txt");
draft.Title = "Test Template";
draft.Subject = "Please sign this document";
draft.Message = "For your approval.";
draft.AddSignerRole("Client", 0);
draft.AddSignerRole("Witness", 1);
draft.AddCcRole("Manager");
draft.AddMergeField("Full Name", MergeField.FieldType.Text);
draft.AddMergeField("Is Registered?", MergeField.FieldType.Checkbox);
var response = client.CreateEmbeddedTemplateDraft(draft, "CLIENT ID HERE");
```
```csharp New SDK - Create Embedded Template Draft
var config = new Configuration();
config.Username = "YOUR_API_KEY";
// Create an instance of TemplateApi
var templateApi = new TemplateApi(config);
// Complete sub classes for parameters that have multiple properties
var role1 = new SubTemplateRole(
name: "Client",
order: 0
);
var role2 = new SubTemplateRole(
name: "Witness",
order: 1
);
var mergeField1 = new SubMergeField(
name: "Full Name",
type: SubMergeField.TypeEnum.Text
);
var mergeField2 = new SubMergeField(
name: "Is Registered?",
type: SubMergeField.TypeEnum.Checkbox
);
var subFieldOptions = new SubFieldOptions(
dateFormat: SubFieldOptions.DateFormatEnum.DDMMYYYY
);
// Build the request
var data = new TemplateCreateEmbeddedDraftRequest(
clientId: "ec64a202072370a737edf4a0eb7f4437",
fileUrls: new List() { "https://app.hellosign.com/docs/example_signature_request.pdf" },
title: "Test Template",
subject: "Please sign this document",
message: "For your approval",
signerRoles: new List() { role1, role2 },
ccRoles: new List() { "Manager" },
mergeFields: new List() { mergeField1, mergeField2 },
fieldOptions: subFieldOptions,
testMode: true
);
// Send the request
try
{
var result = templateApi.TemplateCreateEmbeddedDraft(data);
Console.WriteLine(result);
}
catch (ApiException e)
{
Console.WriteLine("Exception when calling Dropbox Sign API: " + e.Message);
Console.WriteLine("Status Code: " + e.ErrorCode);
Console.WriteLine(e.StackTrace);
}
```
### Create Embedded Signature Request
```csharp Legacy SDK - Create Embedded Req
var request = new SignatureRequest();
request.Title = "NDA with Acme Co.";
request.Subject = "The NDA we talked about";
request.Message = "Please sign this NDA and then we can discuss more. Let me know if you have any questions.";
request.AddSigner("jack@example.com", "Jack");
request.AddSigner("jill@example.com", "Jill");
request.AddFile("c:\users\me\My Documents\example_signature_request.pdf");;
request.Metadata.Add("custom_id", "1234");
request.Metadata.Add("custom_text", "NDA #9");
request.TestMode = true;
var response = client.CreateEmbeddedSignatureRequest(request, "CLIENT ID HERE");
Console.WriteLine("New Embedded Signature Request ID: " + response.SignatureRequestId);
```
```csharp New SDK - Create Embedded Req
var config = new Configuration();
config.Username = "YOUR_API_KEY";
var signatureRequestApi = new SignatureRequestApi(config);
// Use sub classes to build parameters for signature request
var signer1 = new SubSignatureRequestSigner(
emailAddress: "jack@example.com",
name: "Jack",
order: 0
);
var signer2 = new SubSignatureRequestSigner(
emailAddress: "jill@example.com",
name: "Jill",
order: 1
);
var clientId = "YOUR_CLIENT_ID";
// Create embedded request with parameters
var data = new SignatureRequestCreateEmbeddedRequest(
clientId: clientId,
title: "NDA with Acme Co.",
subject: "The NDA we talked about",
message: "Please sign this NDA and then we can discuss more. Let me know if you have any questions.",
signers: new List() { signer1, signer2 },
fileUrls: new List() { "https://app.hellosign.com/docs/example_signature_request.pdf" },
testMode: true
);
// Send request
try
{
var result = signatureRequestApi.SignatureRequestCreateEmbedded(data);
Console.WriteLine(result);
}
catch (ApiException e)
{
Console.WriteLine("Exception when calling Dropbox Sign API: " + e.Message);
Console.WriteLine("Status Code: " + e.ErrorCode);
Console.WriteLine(e.StackTrace);
}
```
### Get Embedded Sign URL
```csharp Legacy SDK - Get Embedded Sign URL
var response = client.GetSignUrl("SIGNATURE ID HERE");
Console.WriteLine("Signature URL for HelloSign.open(): " + response.SignUrl);
```
```csharp New SDK - Get Embedded Sign URL
var config = new Configuration();
config.Username = "YOUR_API_KEY";
var embeddedApi = new EmbeddedApi(config);
// Set the signatureId for the specific signer in your request
var signatureId = "47c7084089602b9ea45e4c1cd24d71aa";
// Send request
try
{
var result = embeddedApi.EmbeddedSignUrl(signatureId);
Console.WriteLine(result);
}
catch (ApiException e)
{
Console.WriteLine("Exception when calling Dropbox Sign API: " + e.Message);
Console.WriteLine("Status Code: " + e.ErrorCode);
Console.WriteLine(e.StackTrace);
}
```
### Create Embedded Unclaimed Draft with file
```csharp Legacy SDK - Create Embedded Unclaimed Draft
var draft = new SignatureRequest();
draft.AddFile("DOCUMENT A.pdf");
draft.RequesterEmailAddress = "EMAIL HERE";
draft.TestMode = true;
var response = client.CreateUnclaimedDraft(draft, myClientId);
Console.WriteLine("Embedded Unclaimed Draft Signature Request ID: " + response.SignatureRequestId);
Console.WriteLine("Claim URL: " + response.ClaimUrl);
```
```csharp New SDK - Create Embedded Unclaimed Draft
var config = new Configuration();
config.Username = "YOUR_API_KEY";
var unclaimedDraftApi = new UnclaimedDraftApi(config);
// Build signature request
var data = new UnclaimedDraftCreateEmbeddedRequest(
clientId: "ec64a202072370a737edf4a0eb7f4437",
fileUrls: new List() { "https://app.hellosign.com/docs/example_signature_request.pdf" },
requesterEmailAddress: "jack@dropboxsign.com",
testMode: true
);
// Send request
try
{
var result = unclaimedDraftApi.UnclaimedDraftCreateEmbedded(data);
Console.WriteLine(result);
}
catch (ApiException e)
{
Console.WriteLine("Exception when calling Dropbox Sign API: " + e.Message);
Console.WriteLine("Status Code: " + e.ErrorCode);
Console.WriteLine(e.StackTrace);
}
```
## Supporting Legacy SDKs
## Feedback and Assistance