NAV

eSignTools API v2.1.0

Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.

This document describes how to send a document for signature to eSignTools. Based on REST principles, our Web API return data in JSON .

See an example of a Java implementation.

A document which will be signed is also called "agreement".

The classic workflow is :

The document is now sent for signature to the recipients.

eSignTools will call the callback each time an event occurs.

Example, if the callback is set to https://mysite.com/event :

Version 2.1.0

Version 2.1.0 adds embedded signing for client portals and in-person workflows, with temporary sessions, an iframe/modal integration script and browser events. The API endpoint paths retain their /v1 prefixes.

Downloads: Swagger 2.0 contract, Postman collection, iframe/modal integration script.

About signature fields

There are currently 3 ways to manage signature fields. You can either put it yourself in the PDF before uploading it to eSignTools, or you can add them dynamically at the upload.

Postman Collection detailing the 3 methods to create an agreement

Method 1 : Upload a PDF already containing signature fields :

These fields shall have a name like SignatorySignature_X_Y, where X is the recipent position (set in CreateRecipientDTO) and Y the fields number.
Examples :

Example Document

Method 2 : Using tags

Your PDF can have no signature field, but just text tags. Add anywhere in your document a text #signatureX# to add a signature field linked to the recipient with position=X.

Example :

The signature fields will have a default size. You can customize the size in the API.

Example Document

Method 3 : Upload a PDF without signature fields

If your PDF does not contain any signature fields, you must define them in the call to the API. For each recipient, you must have at least one signature field. See CreateSignatureZoneDTO

A signature field is defined by :

Example Document

About document types

Instead of uploading a PDF file, you can upload any file with one of the following extension : .rtf, .doc, .docx, .xls, .xlsx, .odt, .ods The document will be converted by eSignTools into a PDF.

Base URLs:

Embedded signing (v2.1.0)

Embed the signing journey in a client portal, an iframe or a modal. The same documents, recipients, signature fields and optional SMS checks are used as for email signing. Signers do not need an EST account or third-party cookies.

Create the document and session

Create the agreement with the existing multipart endpoint. To disable invitation emails, pass "autoSendMailsEnabled": "false" in CreateAgreementDTO (a JSON string, not a boolean). Email signing remains enabled by default. Existing confirmation emails and business callbacks retain their behavior.

Use the recipient id returned in AgreementDTO.recipients; an email address cannot replace it. The host application's server must check that its authenticated user is allowed to access this agreement and sign for this recipient. For a client portal, derive the recipient from the authenticated client session. signatureScalePercent is an optional integer from 1 to 100 (default: 100, including null). A value of 70 scales both dimensions of the complete signature block (name, date and handwriting) to 70%, centered within its field in the final PDF. It applies only to this session, in either mode. Values other than 100 require the BLOCKCHAIN provider; DOCAPOST returns HTTP 400.

For in-person signing, check the operator's assignment to the case. Keep EST credentials and JWT tokens on your server.

Open a session from your server:

curl --request POST \
  'https://secure.esign-tools.fr/api/signing/v1/agreements/123/embedded-sessions' \
  --header 'Authorization: Bearer <JWT_EST>' \
  --header 'Content-Type: application/json' \
  --data '{"recipientId":456,"parentOrigin":"https://app.example.com","mode":"CLIENT_SPACE","signatureScalePercent":70}'

For in-person signing, use "mode": "IN_PERSON" and include "operatorReference": "technician-789". This identifies the authenticated professional; recipientId still identifies the customer who signs. EST stores these references with the calling EST user and the session expiration.

parentOrigin must match the host application's exact origin, including its port if applicable, without a path or trailing slash. HTTPS is required; HTTP is accepted for localhost and 127.0.0.1 during development.

201 Created — Cache-Control: no-store

{
  "signingUrl": "https://secure.esign-tools.fr/fr/signature/embedded-00000000-0000-4000-8000-000000000000",
  "expiresAt": "2026-10-16T15:30:00+02:00",
  "agreementId": 123,
  "recipientId": 456
}

Always use the returned signingUrl; its language prefix depends on the EST deployment. Treat it as confidential access to the document. Forward the response to the signer's browser without exposing your EST JWT.

The session lasts up to 30 minutes and never exceeds the agreement's expiration. The agreement must be accessible to the API caller, OPEN, and the recipient must be WAITING at the current signing step. An incompatible state or expired agreement returns 409 Conflict when creating a session. An unknown agreement or recipient returns 404 Not Found. Invalid input returns 400 Bad Request. When using a session, an expired access returns 410 Gone, and an unknown access returns 404 Not Found. Request a new session from your server to resume after expiration.

Display an iframe or modal

Download the ESTSigning integration script and host it with your application, or load /assets/est-embedded.js from your EST client deployment (including its language prefix when needed). The signer needs network access to both the EST client and API.

The following native HTML modal receives session from your own server:

<dialog id="signature-dialog" aria-label="Sign document"
  style="width:96vw;max-width:1100px;height:92vh;height:92dvh;padding:0;border:0">
  <div id="signature-container" style="width:100%;height:100%"></div>
</dialog>
<script src="/assets/est-embedded.js"></script>
<script>
  function openSignature(session) {
    const dialog = document.getElementById('signature-dialog');
    const container = document.getElementById('signature-container');
    let integration;
    function close() {
      if (integration) integration.destroy();
      dialog.close();
      dialog.removeEventListener('cancel', cancel);
    }
    function cancel(event) {
      event.preventDefault();
      close();
    }
    dialog.addEventListener('cancel', cancel);
    integration = ESTSigning.mount({
      ...session,
      container,
      onEvent(message) {
        if (message.event === 'signed' || message.event === 'refused') {
          // Refresh the status through your server / the EST business callback.
          close();
        } else if (message.event === 'cancelled') {
          close();
        } else if (message.event === 'error') {
          // Show an error and offer a new session through your server.
          console.error('Signing unavailable', message.code);
          close();
        }
      }
    });
    dialog.showModal();
  }
</script>

For an iframe within a page, call ESTSigning.mount with a container of a defined height, for example height: 85vh. Call destroy() when closing or unmounting the host component. It removes the iframe, message listener and readiness timer.

If your proxy adds a Content Security Policy, allow the host origin in EST's frame-ancestors and the EST origin in the host application's frame-src. X-Frame-Options: DENY or SAMEORIGIN on the EST client prevents embedding across origins.

Browser events

EST sends postMessage events only to parentOrigin. The integration script checks the EST origin, iframe window, message version, agreement and recipient before invoking onEvent.

interface ESTSigningMessage {
  source: 'est-signing';
  version: 1;
  event: 'ready' | 'signed' | 'refused' | 'error' | 'cancelled';
  agreementId: number;
  recipientId: number;
  code?: string;
}
Event / code Meaning
ready The document and recipient have loaded.
signed This recipient has signed; other recipients may still be pending.
refused This recipient has refused the document.
cancelled Close the display; this does not refuse the document.
error / session_unavailable No valid event arrived within 30 seconds: access may have expired, the network may be unavailable, or loading may be blocked. Customize the timeout with readyTimeout in milliseconds.
error / signature_failed The signing action failed; EST retains its existing error handling.

Browser notifications update the interface. Your server's agreement status and the existing EST callback remain the business reference; do not use a browser event alone as proof that an agreement is fully signed.

Authentication

Authentication

Authenticate

POST /v1/authenticate

Authenticate with eSignTools API and returns a JWT Token. This token must be sent to every other request in the Authorization bearer header. Example : "Authorization: Bearer XXX" where XXX is the token returned by this method.

Body parameter

{
  "password": "string",
  "rememberMe": true,
  "username": "string"
}

Parameters

Name In Type Required Description
body body Credentials true eSignTools Credentials

Example responses

200 Response

{
  "authorities": [
    "string"
  ],
  "id_token": "string"
}

Responses

Status Meaning Description Schema
200 OK OK JWTToken
201 Created Created None
401 Unauthorized Unauthorized None
403 Forbidden Forbidden None
404 Not Found Not Found None

Agreement Resource

Basic interactions necessarry to handle the agreement through it's lifetime

Create a new agreement

POST /signing/v1/agreements

Body is a FormData composed of a document (sent in binary) and a CreateAgreementDTO object (serialized as a JSON) to create an agreement.
For examples, see the Postman collection in the introduction.

Body : composed of two multipart/form-data fields

pdf: binary data
agreement: JSON format data

Parameters

Name In Type Required Description
body body object true Body with the format multipart/form-data
» pdf body binary true The source document
» agreement body string true String containing a CreateAgreementDTO in json format

Example responses

200 Response

Responses

Status Meaning Description Schema
200 OK OK AgreementDTO
201 Created Created None
401 Unauthorized Unauthorized None
403 Forbidden Forbidden None
404 Not Found Not Found None

Open an embedded signing session

POST /signing/v1/agreements/{id}/embedded-sessions

Call from your application's server using Authorization: Bearer <JWT_EST>. See Embedded signing for the full integration workflow.

Body parameter

{"recipientId":456,"parentOrigin":"https://app.example.com","mode":"CLIENT_SPACE","signatureScalePercent":70}
Name In Type Required Description
id path integer(int64) true Agreement ID
body body CreateEmbeddedSigningSessionDTO true Session settings

201 Created

{"signingUrl":"https://secure.esign-tools.fr/fr/signature/embedded-00000000-0000-4000-8000-000000000000","expiresAt":"2026-10-16T15:30:00+02:00","agreementId":123,"recipientId":456}
Status Description Schema
201 Session created; Cache-Control: no-store EmbeddedSigningSessionDTO
400 Invalid input or origin; missing operatorReference for IN_PERSON None
401 Missing or invalid JWT None
403 Access forbidden None
404 Agreement or recipient not found None
409 Agreement not open or expired; recipient not waiting at current step None

This operation requires JWT authentication. An expired session returns 410 Gone when used; an unknown session returns 404 Not Found.

Re-send the mail to the recipient

GET /signing/v1/agreements/{agreementId}/send-mails

Parameters

Name In Type Required Description
agreementId path integer(int64) true ID of the document

Example responses

200 Response

Responses

Status Meaning Description Schema
200 OK OK boolean
401 Unauthorized Unauthorized None
403 Forbidden Forbidden None
404 Not Found Not Found None

Agreements settings

GET /signing/v1/agreements/{id}

Get information about the agreement in JSON format.

Parameters

Name In Type Required Description
id path integer(int64) true ID of the eSignTools agreement to get the settings.

Example responses

200 Response

Responses

Status Meaning Description Schema
200 OK OK AgreementDTO
401 Unauthorized Unauthorized None
403 Forbidden Forbidden None
404 Not Found Not Found None

Delete an agreement

DELETE /signing/v1/agreements/{id}

The agreement must not be signed. It will be deleted and the recipient(s) will not be able to sign it.

Parameters

Name In Type Required Description
id path integer(int64) true ID of the eSignTools agreement to delete.

Example responses

200 Response

Responses

Status Meaning Description Schema
200 OK OK string
204 No Content No Content None
401 Unauthorized Unauthorized None
403 Forbidden Forbidden None

Download the document

GET /signing/v1/agreements/{id}/current-file

The document can be downloaded at any point of the process. (Unsigned, Partially Signed, Signed)

Parameters

Name In Type Required Description
id path integer(int64) true ID of the eSignTools document

Example responses

200 Response

Responses

Status Meaning Description Schema
200 OK OK byte
401 Unauthorized Unauthorized None
403 Forbidden Forbidden None
404 Not Found Not Found None

Downloads the proof PDF

GET /signing/v1/agreements/{id}/proof

Parameters

Name In Type Required Description
id path integer(int64) true ID of the eSignTools document

Example responses

200 Response

Responses

Status Meaning Description Schema
200 OK OK byte
401 Unauthorized Unauthorized None
403 Forbidden Forbidden None
404 Not Found Not Found None

Schemas

Credentials

{
  "password": "string",
  "rememberMe": true,
  "username": "string"
}

Credentials

Properties

Name Type Required Restrictions Description
password string true none Password of the API user
rememberMe boolean false none none
username string true none Username of the API user

JWTToken

{
  "authorities": [
    "string"
  ],
  "id_token": "string"
}

JWTToken

Properties

Name Type Required Restrictions Description
authorities [string] false none none
id_token string false none JWT Token to pass to next API calls.

CreateAgreementDTO

{
  "autoSendMailsEnabled": "false",
  "durationUntilExpirationSeconds": 3600,
  "callbackUrl": "https://mysite.com/event",
  "defaultFieldHeight": 0,
  "defaultFieldWidth": 0,
  "name": "Contract123",
  "recipients": [
    {
      "canRenew": true,
      "email": "string",
      "fields": [
        {
          "height": 0,
          "page": 0,
          "width": 0,
          "x": 0,
          "y": 0
        }
      ],
      "firstname": "string",
      "lastname": "string",
      "phone": "string",
      "position": 0,
      "step": 0
    }
  ],
  "reminderDelay": "86 400",
  "textTemplateName": "default"
}

CreateAgreementDTO

Properties

Name Type Required Restrictions Description
autoSendMailsEnabled string false none Set the string "false" to disable invitation emails for embedded signing. Defaults to "true".
durationUntilExpirationSeconds integer(int64) false minimum: 600 Agreement lifetime in seconds; account default if omitted.
callbackUrl string false none URL which will be called when an event occurs. See the Introduction to know how callback events works.
defaultFieldHeight integer(int32) false none Set the default height of signature fields when using tags.
defaultFieldWidth integer(int32) false none Set the default width of signature fields when using tags.
name string true none Name of the agreement
recipients [CreateRecipientDTO] true none none
reminderDelay integer(int32) false none Set the delay of reminders in minutes. A reminder is sent when a recipient has not signed the document. If this parameter is not set, no reminder will be sent.
textTemplateName string false none Template to use when a mail is sent to the recipient. If this parameter is not set, the default template is used.

CreateRecipientDTO

{
  "canRenew": true,
  "email": "string",
  "fields": [
    {
      "height": 0,
      "page": 0,
      "width": 0,
      "x": 0,
      "y": 0
    }
  ],
  "firstname": "string",
  "lastname": "string",
  "phone": "string",
  "position": 0,
  "step": 0
}

CreateRecipientDTO

Properties

Name Type Required Restrictions Description
canRenew boolean false none none
email string true none none
fields [CreateSignatureZoneDTO] false none List of the signature fields to add for this recipient. This list is mandatory if the PDF does not contain any signature fields.
firstname string true none none
lastname string true none none
phone string false none Phone number of the recipient. If this propery is set, a SMS with a code will be sent to the recipient to validate its signature.
position integer(int32) false none Position of the concerned Signature Form in the PDF. Example : if the position is 1, every Signature Form with the name SignatorySignature_1_x will be bound to this recipient. This property is optional if you set the signature fields via the API. Default is 1
step integer(int32) false none Step of this recipient in the signature workflow. If every recipient has step=1, the document will be sent for signature simultaneously to every recipient. If step=1 for recipient A and step=2 for recipient B, eSignTools will wait A to sign before sending it to B. Default is 1

CreateSignatureZoneDTO

{
  "height": 0,
  "page": 0,
  "width": 0,
  "x": 0,
  "y": 0
}

CreateSignatureZoneDTO

Properties

Name Type Required Restrictions Description
height integer(int32) false none Height of the field in points
page integer(int32) false none Number of the page which will contain the field (starts with 1)
width integer(int32) false none Width of the field in points
x integer(int32) false none Horizontal position of the field, from the left of the page, in points
y integer(int32) false none Vertical position of the field, from the bottom of the page, in points

AgreementDTO

{
  "currentStep": 0,
  "estClientUrlAccess": "string",
  "id": 0,
  "name": "string",
  "pages": 0,
  "recipients": [
    {
      "canRenew": true,
      "email": "string",
      "firstname": "string",
      "id": 0,
      "lastname": "string",
      "status": "WAITING",
      "step": 0
    }
  ],
  "renewedDate": "2019-08-24T14:15:22Z",
  "status": "OPEN"
}

AgreementDTO

Properties

Name Type Required Restrictions Description
currentStep integer(int32) false none Current step of the document. See CreateAgreementDTO::step
estClientUrlAccess string false none none
id integer(int64) false none Agreement ID generated by eSignTools
name string false none Name of the agreement (ex : "Contract")
pages integer(int32) false none Number of pages of the document
recipients [RecipientStatusDTO] false none [Information about the recipient and its status in the signature workflow.]
renewedDate string(date-time) false none none
status string false none Current status of the agreement.
- OPEN : the document has not been signed by all recipients
- CLOSED : the document is signed by every recipient and is archived
- ABORTED : the document has been rejected by a recipient
- DELETED : the document has been deleted with a DELETE API call
- ABANDONED : the document is expired

Enumerated Values

Property Value
status OPEN
status CLOSED
status ABORTED
status DELETED
status ABANDONED

RecipientStatusDTO

{
  "canRenew": true,
  "email": "string",
  "firstname": "string",
  "id": 0,
  "lastname": "string",
  "status": "WAITING",
  "step": 0
}

RecipientStatusDTO

Properties

Name Type Required Restrictions Description
canRenew boolean false none none
email string false none none
firstname string false none none
id integer(int64) false none ID of the recipient, generated by eSignTools
lastname string false none none
status string false none none
step integer(int32) false none See CreateRecipientDTO:step for more details.

Enumerated Values

Property Value
status WAITING
status SIGNED
status REFUSED

CreateEmbeddedSigningSessionDTO

Properties

Name Type Required Restrictions Description
recipientId integer(int64) true none Recipient ID from AgreementDTO.recipients; must be WAITING at the current signing step.
parentOrigin string true maxLength: 255 Exact HTTPS origin of the host application, without path or trailing slash. HTTP allowed only for localhost and 127.0.0.1.
mode string true CLIENT_SPACE, IN_PERSON Client portal or in-person signing. IN_PERSON requires operatorReference.
operatorReference string false maxLength: 255 Required and non-blank for IN_PERSON. Reference of the authenticated professional, not the signer.
signatureScalePercent integer(int32) false 1–100, default: 100 Proportional scale of the complete signature block in the final PDF, centered in its field. Values other than 100 require BLOCKCHAIN.

EmbeddedSigningSessionDTO

Properties

Name Type Required Restrictions Description
signingUrl string(uri) false none Confidential temporary signing URL. Use the returned URL, including its deployment-specific language prefix.
expiresAt string(date-time) false none Up to 30 minutes from creation, capped at the agreement expiration.
agreementId integer(int64) false none none
recipientId integer(int64) false none none