Digital Signing API

The Digital Signing API creates signing orders from your own system and follows them until the documents are signed. For the application, read Digital Signing.

Every call needs a bearer token, see Authentication, and a company that has the signing licence. The orders belong to your own company.

https://api.digitalsigning.metaforce.net/DigitalSigningOrders

Property names in requests and responses are written in camel case, for example packageName.

Check before you create

GET /DigitalSigningOrders/GetCreateOrderInitialData/{langCode} returns what you need to prepare an order. langCode is optional and picks the language of the default texts. The response has:

FieldWhat it is
isCreateNewOrderAvailableWhether your company can create an order now.
orderAvailabilityMessageWhy not, when it cannot.
emailSigningSubject, emailSigningMessageThe default email text.
providerSigningSubject, providerSigningMessageThe default text shown when signing.
providerType, archiveTypeThe signing provider and the archive in use.
availableFoldersThe Archive folders you can use for archiveFolderId.
languagesThe languages you can pick.

Create an order

POST /DigitalSigningOrders takes a JSON body.

FieldWhat it is
signatoriesThe people who sign. At least one. See below.
signingOrderFilesThe PDF files to sign, one to ten, each with a name and the file as a base64 fileContent.
packageNameThe name of the order. Required.
languageThe language of the notifications and the signing page. Required. One of cs, da, de, el, en, es, et, fi, fr, hu, is, it, lt, lv, nb, nl, pl, pt or sv.
emailNotificationSubject, emailNotificationMessageThe subject (up to 256 characters) and text (up to 8000 characters) of the email to each signatory. Required.
signingNotificationTitle, signingNotificationMessageThe title (up to 256 characters) and text (up to 8000 characters) shown when signing. Required.
useSignatureOrderSign in a fixed order. Use it together with signingSequence on each signatory.
signNowViaUrlGive each signatory a link to sign at once.
completedWebhookUrl, cancelledWebhookUrlURLs Doc Gen calls when the order is completed or cancelled. See Webhooks.
distributeSignedDocumentToAllSignatoriesSend the signed document to every signatory.
archiveFolderIdThe Archive folder to store the signed documents in.

Each signatory has:

FieldWhat it is
idOptional. Your own identifier for the signatory, up to 64 characters of letters, digits, - and _.
emailAddressWhere to send the request. Required.
firstName, lastNameThe name. Some signing providers require them.
personalNumberThe personal number, for providers that check it. A number the provider rejects is reported as invalid_personal_number.
signViaUrlGive this signatory a link to sign at once.
signingSequenceInitial, DependsOnInitial or NoOrder.
signUrlSend an empty string. Doc Gen fills it in, but the request is rejected with 400 if the field is missing.
{
    "packageName": "Employment contract, Ingrid Berg",
    "language": "en",
    "emailNotificationSubject": "Please sign your employment contract",
    "emailNotificationMessage": "Hi Ingrid, your employment contract is ready to sign.",
    "signingNotificationTitle": "Employment contract",
    "signingNotificationMessage": "Read the contract and sign it.",
    "signatories": [
        {
            "emailAddress": "ingrid.berg@example.com",
            "firstName": "Ingrid",
            "lastName": "Berg",
            "signingSequence": "Initial",
            "signUrl": ""
        }
    ],
    "signingOrderFiles": [
        { "name": "contract.pdf", "fileContent": "JVBERi0xLjQK..." }
    ],
    "completedWebhookUrl": "https://example.com/signing/completed"
}

A request that misses a required field is answered with 400. The call answers 200 when the request is valid, so read the body. It has data, type and message. type is 0 when the order was created, 1 when it could not be created and 2 when the licence stopped it. On success, data holds the order and its id.

These messages can come back:

typemessageMeaning
1invalid_personal_numberThe signing provider rejected a personal number.
1something_went_wrong_with_external_providerThe signing provider could not create the order.
1something_went_wrong_internalA signatory has no firstName or lastName while your signing provider shows names, or the order could not be saved. With such a provider, send both names for every signatory.
2licence_order_will_exceed_usageThis order would take your company over its licence.
2Another licence messageYour licence does not allow new orders at the moment.

Follow an order

CallWhat it returns
POST /DigitalSigningOrders/GetListOfOrdersThe most recent orders that match your search. All fields are optional: fromDate, toDate, fileStatus (a list of order statuses), sortBy and sortDesc.
GET /DigitalSigningOrders/{id}One order with its files and signatories. 404 if it does not exist.
GET /ActivitiesThe newest five orders that changed.

An order has a status. In responses it is a number:

NumberStatus
1Created
5InProgress
10Completed
20DownloadedFromSigningProvider
50Rejected
70Canceled
99Error

Each signatory has a signStatus as well, and a signingSequence (0 for Initial, 1 for DependsOnInitial, 2 for NoOrder). The sign status goes from not set (0) and created (1) through started (2) to completed (3), rejected (4), expired (5), forwarded (6) or canceled (7).

Get the files

CallWhat it returns
GET /DigitalSigningOrders/GetCertifiedPdf/{orderId}The signed files. Works for completed orders only.
GET /DigitalSigningOrders/GetPdfFromProvider/{orderId}The signed files as held by the signing provider. Works for completed orders only.
GET /DigitalSigningOrders/GetSignatureFile/{orderId}/{signatureId}The proof of one signature, for providers that supply one.
GET /DigitalSigningOrders/GetAllSignatureFiles/{orderId}The proof of every signature on every document.

A file that does not exist is answered with 404.

Remind, cancel and delete

  • GET /DigitalSigningOrders/SendReminders/{orderId} sends an email to every signatory who has not signed yet.
  • DELETE /DigitalSigningOrders/{orderId} cancels the order.
  • DELETE /DigitalSigningOrders/DeleteOrder/{orderId} deletes the order.

Each of these answers true or false in the body.

Webhooks

When the order is completed, Doc Gen calls completedWebhookUrl. When it is cancelled, Doc Gen calls cancelledWebhookUrl. The call is a GET without a body, so use it as a signal and then fetch the order with GET /DigitalSigningOrders/{id}. If Doc Gen cannot reach the URL, it tries again, up to four attempts in all, about half a second apart. An answer with an error status is not tried again.

Example

const axios = require('axios').default;

async function createOrder(accessToken) {
  const response = await axios({
      method: 'POST',
      url: 'https://api.digitalsigning.metaforce.net/DigitalSigningOrders',
      headers: {
          'content-type': 'application/json',
          'Authorization': `Bearer ${accessToken}`
      },
      data: {
          packageName: 'Employment contract, Ingrid Berg',
          language: 'en',
          emailNotificationSubject: 'Please sign your employment contract',
          emailNotificationMessage: 'Hi Ingrid, your employment contract is ready to sign.',
          signingNotificationTitle: 'Employment contract',
          signingNotificationMessage: 'Read the contract and sign it.',
          signatories: [
              { emailAddress: 'ingrid.berg@example.com', firstName: 'Ingrid', lastName: 'Berg', signUrl: '' }
          ],
          signingOrderFiles: [
              { name: 'contract.pdf', fileContent: '<base64 of the PDF>' }
          ]
      }
  });
  console.log(response.data.type, response.data.message);
}