Pular para o conteúdo principal

Create documents

Creating a document in Signer involves two steps: uploading the file and creating the document by defining the participant flow. From there, Signer automatically notifies the participants in the defined order.

Step by step​

Each step shows the REST call and the same call through the client libraries for C#, Java, Node.js and PHP. The code comes from the SignerSamples scenarios, trimmed to the call. Create the client once, with the URL of your Signer instance and the API key:

using Lacuna.Signer.Client;

// Sandbox URL; in production, https://www.dropsigner.com or your on-premises instance
var signerClient = new SignerClient("https://signer-lac.azurewebsites.net", "your-application|0000000000000000000000000000000000000000000000000000000000000000");

The Node.js client is generated from the API: it has one class per API group (UploadApi, DocumentsApi) and one method per endpoint, named after the route, such as apiDocumentsPost for POST /api/documents. Every method returns the axios response, with the body in data.

1. Upload the file​

Upload the file that will be signed. There are two upload APIs:

Both return an upload ID that identifies that file:

{
...
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}

With a client library, uploadFile in Java and PHP sends the file to POST /api/uploads (multipart); in Node.js, apiUploadsBytesPost sends it to POST /api/uploads/bytes (Base64). The C#, Java and PHP methods return an upload model that the next step passes on whole; in Node.js, keep data.id.

var file = File.ReadAllBytes("Contract.pdf");
var uploadModel = await signerClient.UploadFileAsync("Contract.pdf", file, "application/pdf");

2. Create the document​

Create a document from the uploaded file using the Document Creation API. In this call, you assemble the document flow, that is, define the participants and in what order they should take their actions:

POST /api/documents

{
"files": [
{
"displayName": "Integration Contract", //Name that will be given to the created document
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", //File's upload ID
"name": "Contract.pdf", //Name of the original file
"contentType": "application/pdf" //Original file mime type
}
],
"flowActions": [
{
"type": "Signer", //Type of participant, in this scenario, signer
"step": 1, //Signing order
"user": {
"name": "John Wick", //Participant's name
"identifier": "81976153069", //Participant's identifier number
"email": "john.wick@mailinator.com", //Participant's email
},
"allowElectronicSignature": true //Allows electronic signature
}
]
}

The response returns the ID of the created document associated with the upload ID, so you know exactly which document matches which upload:

[
{
"uploadId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"documentId": "b12cb1b2-5d6e-40b2-a050-097d068c4c11"
}
]

The same request with a client library. The create call returns the list of uploadId and documentId pairs; with one file, take the first.

using Lacuna.Signer.Api;
using Lacuna.Signer.Api.Documents;
using Lacuna.Signer.Api.FlowActions;
using Lacuna.Signer.Api.Users;

// The name the document will have in Signer
var fileUploadModel = new FileUploadModel(uploadModel) { DisplayName = "Integration Contract" };

// One FlowActionCreateModel per action (signature or approval) of the flow
var flowAction = new FlowActionCreateModel()
{
Type = FlowActionType.Signer,
Step = 1,
User = new ParticipantUserModel()
{
Name = "John Wick",
Identifier = "81976153069",
Email = "john.wick@mailinator.com"
},
AllowElectronicSignature = true
};

var documentRequest = new CreateDocumentRequest()
{
Files = new List<FileUploadModel>() { fileUploadModel },
FlowActions = new List<FlowActionCreateModel>() { flowAction }
};
var result = (await signerClient.CreateDocumentAsync(documentRequest)).First();
// result.DocumentId, result.UploadId
tip

You can create more than one document in the same call, adding as many files as needed. In this case, all documents will share the same flow.

When the document is created, Signer automatically notifies the participants in the specified order. Each participant receives an email with a link that lets them sign or approve the document without having to authenticate.

The request also accepts options that apply to all its documents, such as the timestamp and access validation. See Document options.

The flow (flowActions)​

Each flowActions item represents a participant's action. The main fields are:

FieldDescription
typeAction type (see the table below)
stepOrder of the action in the flow. Actions with the same step happen in parallel; different steps run in sequence
userParticipant data (name, identifier, email). See The participant (user)
allowElectronicSignatureAllows the participant to sign electronically (without a digital certificate)

The available action types (type) are:

typeDescription
SignerParticipant who signs the document
ApproverParticipant who approves the document (without signing)
SignRuleSigning rule: a group in which any member can sign
ApproverRuleApproval rule: a group in which any member can approve

In the client libraries these values are the FlowActionType enum. The FlowActionType of the .NET client (in Lacuna.Signer.Api 1.67.0, which Lacuna.Signer.Client 1.24.0 installs) and of the PHP client 1.4.10 has no ApproverRule; the Java and Node.js ones have all four.

Examples on GitHub, by scenario:

ScenarioExamples
One signerC# · Java · PHP · Node.js
Two or more signers, with orderC# · Java · PHP · Node.js
Two or more signers, without orderC# · Java · PHP · Node.js
With approverC# · Java · PHP · Node.js
With attachmentC# · Java · PHP · Node.js
With descriptionC# · Java · PHP · Node.js

For the participant fields and the identifier types, see The participant (user). For the other options of each flowActions item, such as initials and the electronic signature checks, see Participant options.

Signing in your own application​

If you want to sign the document inside your own application, use the Embedded Signature option.

Follow the same steps from the previous section, but, when sending the document, it is recommended to add the parameter disablePendingActionNotifications set to true. This way, notifications will not be sent to participants.

After the creation of the document, use the document ID to get the signing URL using the Action URL API:

POST /api/documents/b12cb1b2-5d6e-40b2-a050-097d068c4c11/action-url

{
//the information must be sent to identify the participant
"identifier": "81976153069",
"emailAddress": "john.wick@mailinator.com"
}

If the signer has allowed electronic signature (parameter allowElectronicSignature = true), it is possible to require an e-mail confirmation through a code asked during signing. To do so, set requireEmailAuthentication to true:

POST /api/documents/b12cb1b2-5d6e-40b2-a050-097d068c4c11/action-url

{
//the information must be sent to identify the participant
"identifier": "81976153069",
"emailAddress": "john.wick@mailinator.com",
//if the action is an electronic signature and this parameter is set to true, requires e-mail authentication with code in order to complete the signature
"requireEmailAuthentication": true
}

The response presents two URLs:

{
//URL to redirect the user to the Signer signing page
"url": "https://...",
//URL to use the signing Widget
"embedUrl": "https://..."
}

Use the embedUrl with the Signing Widget to display Signer's signing page inside your application. The section Embedded signature describes how to use the Widget.

With a client library, set disablePendingActionNotifications on the request of step 2 and, once the document is created, ask for the participant's URLs:

// Before CreateDocumentAsync: don't e-mail the participants
documentRequest.DisablePendingActionNotifications = true;
var result = (await signerClient.CreateDocumentAsync(documentRequest)).First();

var actionUrlRequest = new ActionUrlRequest()
{
Identifier = "81976153069",
EmailAddress = "john.wick@mailinator.com"
};
var actionUrlResponse = await signerClient.GetActionUrlAsync(result.DocumentId, actionUrlRequest);
// actionUrlResponse.Url: redirect the user to Signer
// actionUrlResponse.EmbedUrl: pass it to the widget

To require the e-mail code, also set RequireEmailAuthentication = true (C#), setRequireEmailAuthentication(true) (Java and PHP) or requireEmailAuthentication: true (Node.js) on the action URL request.

Examples on GitHub: C# · Java · PHP · Node.js

Pre-positioning a signature on the document​

During the creation of a document, it is possible to place each participant's signature in a specific place in the document. All definitions are done during the creation of the flowAction: there are options to define the page and the location of the signature within it.

Examples on GitHub: C# · Java · PHP · Node.js

Signer positioning of the signature​

Available from version 3.0.0. Two fields control where the signature's visual representation (the signature image on the PDF) goes:

FieldDescription
signerPositioningEnabledIf false, the signer cannot position their own signature. If they send a position, the API responds with the SignerPositioningNotAllowed error.
automaticSignaturePositioningWhat the Signer does with a signature nobody positioned: Disabled (leaves it off the PDF), Footnote (places it on the document footer) or SignatureSheet (places it on a signature sheet at the end of the PDF).

Send the fields when you create the document. A null or missing field uses the organization's current setting. The document keeps the value: a later change in the organization does not change the document. You cannot combine signerPositioningEnabled set to false with Disabled: the API responds with the SignerPositioningIncompatibleWithAutomaticPositioningDisabled error.

To change both fields after creation, send a PUT. It requires the same permission as editing the flow:

PUT /api/documents/b12cb1b2-5d6e-40b2-a050-097d068c4c11/signer-positioning

{
"signerPositioningEnabled": false,
"automaticSignaturePositioning": "SignatureSheet"
}

You can make this change only before a participant signs or approves. After that, the API responds with the SignerPositioningLockedAfterSignature error. The change also fails on canceled, expired, refused or paused documents.

When you edit the flow of an already signed document (POST /api/documents/{id}/flow), the signature sheet may have no room for a new participant. In that case, the API responds with the SignatureSheetFull error. To accept the edit anyway, send ?acceptFootnoteVisualRepresentation=true. The Signer places the signatures that do not fit on the page footer and leaves out those participants' optional initials.

Merge multiple files into a single document (envelope)​

It is possible to upload multiple files and merge them all into a single document (envelope). To do so, add the isEnvelope=true parameter and an envelope name in EnvelopeName.

caution

Merging only works if all uploaded files are PDFs.

Examples on GitHub: C# · Java · PHP · Node.js

Next steps​

With the document created, see how to track its status and send reminders.

View as Markdown