Pular para o conteúdo principal

Integration Guide

Signer is a web portal of documents that enables digital and electronic signatures as well as the creation of complex document flows. This guide presents the integration options so that your application can make the most of Signer's potential.

New here?

If this is your first integration, start with Getting started, which takes you from zero to your first signed document in about 15 minutes. This guide serves as a reference for the use cases.

Authentication​

All API calls demand one API Key in order to communicate with Signer. This key must be placed in the header of all requests:

X-Api-Key: your-application|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Every API Key is associated with an Organization previously registered in Signer. Therefore, the scope of this key is restricted to that organization, that key will only allow you to access/create documents from that same organization.

note

To get an API key: if you have permission to create applications in the organization, create an application under Applications and generate the key with its Keys button, as shown in Getting started. Otherwise, ask your instance administrator for one.

Client libraries​

Lacuna publishes a client library of the API for .NET, Java, Node.js and PHP. You create the client with the URL of your Signer instance and the API key, and call the APIs through its methods. You can also call the REST API directly from any language, as Getting started does with curl.

LanguagePackageVersionInstall
.NET (.NET Framework 4.5 or later, .NET Standard 2.0)Lacuna.Signer.Client1.24.0dotnet add package Lacuna.Signer.Client
Javacom.lacunasoftware.signer:signer-client2.14.0Gradle: implementation 'com.lacunasoftware.signer:signer-client:2.14.0'
Node.jssigner-node-client1.1.0npm install signer-node-client
PHPlacuna/signer-client1.4.10composer require lacuna/signer-client

The samples on GitHub use these libraries, with one scenario per use case of this guide. To embed the signing screen in your web page, use the lacuna-signer-widget JavaScript library: see Embedded signature.

Features newer than the client libraries​

The client libraries were released before Signer 3.x, so they lack some of its calls and fields. A method or field missing from a library does not mean that Signer lacks it: check the API reference.

Feature.NETJavaNode.jsPHP
Pause and resume, and the Paused statusNoNoNoNo
DocumentPaused and DocumentResumed webhook eventsNoNoNoNo
DocumentDeleted webhook eventWith Lacuna.Signer.Api 2.1.0YesYesNo
disableRefusalNoNoNoNo
notificationLanguage of a participantNoYesYesNo
notifiedEmailsData, timestampEnabledNoNoNoNo
signerPositioningEnabled, automaticSignaturePositioningNoNoNoNo
convertToPdfA, pdfAProfileNoYesNoNo

Lacuna.Signer.Client 1.24.0 installs Lacuna.Signer.Api 1.67.0. To get the newer models, add Lacuna.Signer.Api 2.1.0 to your project as well, as the .NET samples do. Even then, no library's DocumentStatus has Paused, and the .NET GetDocumentDetailsAsync fails on a paused document: read it with a direct call.

For these features, call the REST API directly with the same URL and API key. The samples add a small helper to their base class: it sends JSON with the X-Api-Key header and throws on an answer other than 2xx, with the body, which for a 422 holds Signer's error code. Upload the file with the library as usual, and use the helper for the call the library lacks. For example, to pause and resume a document:

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

private static readonly HttpClient HttpClient = new HttpClient();

// signerEndpoint and apiKey: the same values you give to the SignerClient
private async Task<JToken> CallSignerApiAsync(HttpMethod method, string path, object body = null)
{
using (var request = new HttpRequestMessage(method, signerEndpoint.TrimEnd('/') + path))
{
request.Headers.TryAddWithoutValidation("X-Api-Key", apiKey);
if (body != null)
{
request.Content = new StringContent(JsonConvert.SerializeObject(body), Encoding.UTF8, "application/json");
}
using (var response = await HttpClient.SendAsync(request))
{
var content = await response.Content.ReadAsStringAsync();
if (!response.IsSuccessStatusCode)
{
throw new HttpRequestException($"{method} {path} answered {(int)response.StatusCode}: {content}");
}
return string.IsNullOrEmpty(content) ? null : JToken.Parse(content);
}
}
}

// Pause: the reason is optional
await CallSignerApiAsync(HttpMethod.Post, $"/api/documents/{documentId}/pause", new { reason = "Waiting for the contract review" });
var document = await CallSignerApiAsync(HttpMethod.Get, $"/api/documents/{documentId}");
// document["status"] is "Paused"

// Resume: no body
await CallSignerApiAsync(HttpMethod.Post, $"/api/documents/{documentId}/resume");

To create a document with a new field, send the whole POST /api/documents body through the helper, with the id, name and contentType of the upload in files. The samples linked from each feature's page do that.

An older Signer ignores new fields

A Signer instance older than a feature does not reject its field: it creates the document without it. Read the document back (GET /api/documents/{id}) and check that the field is there, as the samples do.

How the flow works​

In practice, an integration with Signer follows four stages. Each stage has a dedicated page in this guide:

  1. Create documents: upload the file, assemble the participant flow and (optionally) sign inside your own application.
  2. Track documents: check the status, send reminders and receive webhook notifications.
  3. Download and list: get the document versions and list documents by different criteria.
  4. Validate signatures: validate signatures using a validation key or the signed file.

And throughout the document's life you may need lifecycle operations: cancel, refuse, pause and resume, submit a new version, delete or restore.

Use cases​

Use caseWhat you do
Create documentsUpload, flow creation, embedded signature, pre-positioning signatures and envelopes (multiple files)
Document field referenceLook up the participant fields, the identifier types and the participant and document options
Track documentsCheck document and participant status, send reminders and set up webhooks
Download and listDownload the different document versions and list documents
Validate signaturesValidate signatures by key or by signed file
Document lifecycleCancel, refuse, pause and resume, submit a new version, delete and restore
Contacts and identifiersManage the organization's contacts and a user's identifiers

Error responses​

The APIs answer with these HTTP status codes:

CodeMeaning
200 (OK)Request processed. The response body depends on the API: see its entry in the API reference.
400 (Bad Request)Syntax error, for instance a required field that was not sent.
401 (Unauthorized)The API key was not sent or is invalid.
403 (Forbidden)The API key is valid, but its application does not have permission for the requested operation.
422 (Unprocessable Entity)API error, for instance an entity ID that is not found. The body is an ErrorModel.

An ErrorModel has three fields:

FieldTypeContent
codestringThe error code. Test this field in your code, not the message.
messagestringA description of the error.
detailsobject, with string valuesAdditional information about the error. It may be null.
{
"code": "DocumentNotFound",
"message": "...",
"details": null
}

The API reference lists the main codes of a 422 response: CertificateNotFound, DocumentNotFound, FolderNotFound, CpfMismatch, CpfNotExpected, InvalidFlowAction and DocumentInvalidKey. The list is not comprehensive, and new codes may be added at any time without notice, so handle codes you do not know. Other pages describe the codes of their operations, such as DocumentHasNoSignatures when downloading a version.

View as Markdown