API Based Flow

This flow is best suited for cases where you wish to build (or already have built) your own signing view or user interface. With the API Based Flow you'll take care of handling all the user interactions and use the eID Easy API endpointsopen in new window only.

At the highest level, an API based signing flow goes as follows:

  1. File is prepared for signing - this is a single API request
  2. User signs the file - this might require multiple API requests, polling and/or redirects depending on the signing method. TIP: We also have a couple of front-end components that can handle method specific user interactions and API requests for you. Take a look at our Browser Clientopen in new window and Widgetopen in new window
  3. Fetch the signed file - fetch and store the signed file, let the user download the signed file

Now, you're already off to a good start on your road to wielding the power of the strongest of the electronic signatures - the mighty QESopen in new window. Just follow the steps below and get your first file signed with eID Easy 🚀.

NOTE

For this guide, we assume that you wish to get PDF document signed. However, the flows for all other file types are very similar and we provide ample references to file type specific implementation details along the way. If you'd like to know more about specific API calls and all the available options, take a look at our API Referenceopen in new window.

BEFORE YOU CONTINUE

Make sure that you have your eID Easy API credentials at hand as you'll need them in the following steps. You can follow this short guide to obtain the API credentials.

API REFERENCE

In the following guide, we'll use only a small subset of all the available parameters to keep things simple. You can click on the blue endpoint links in this guide to learn more about all the available options. For the full API reference, see: https://documenter.getpostman.com/view/3869493/Szf6WoG1open in new window

1. Prepare the file for signing

eID Easy API provides two different endpoints for file preparation.

  1. https://id.eideasy.com/api/signatures/prepare-add-signatureopen in new window - use this for when you need to add signatures to an already signed .asice container
  2. https://id.eideasy.com/api/signatures/prepare-files-for-signingopen in new window - use this for all other cases, including signed PDF files (the first endpoint is only meant for .asice containers)

So, let's prepare a PDF file for signing.

For that we'll send a server-side POST request to https://id.eideasy.com/api/signatures/prepare-files-for-signing

The request body might look something like this:

{
  "client_id": "{{client_id}}",
  "secret": "{{secret}}",
  "container_type": "pdf",
  "files": [
    {
      "fileContent": "JVBERi0xLjMNCiXi48/TDQoNCjEgMCBvYmoNCjw8DQovVHlwZSAvQ2F0YWxvZw0KL091dGxpbmVzIDIgMCBSDQovUGFnZXMgMyAwIFINCj4+DQplbmRvYmoNCg0KMiAwIG9iag0KPDwNCi9UeXBlIC9PdXRsaW5lcw0KL0NvdW50IDANCj4+DQplbmRvYmoNCg0KMyAwIG9iag0KPDwNCi9UeXBlIC9QYWdlcw0KL0NvdW50IDINCi9LaWRzIFsgNCAwIFIgNiAwIFIgXSANCj4+DQplbmRvYmoNCg0KNCAwIG9iag0KPDwNCi9UeXBlIC9QYWdlDQovUGFyZW50IDMgMCBSDQovUmVzb3VyY2VzIDw8DQovRm9udCA8PA0KL0YxIDkgMCBSIA0KPj4NCi9Qcm9jU2V0IDggMCBSDQo+Pg0KL01lZGlhQm94IFswIDAgNjEyLjAwMDAgNzkyLjAwMDBdDQovQ29udGVudHMgNSAwIFINCj4+DQplbmRvYmoNCg0KNSAwIG9iag0KPDwgL0xlbmd0aCAxMDc0ID4+DQpzdHJlYW0NCjIgSg0KQlQNCjAgMCAwIHJnDQovRjEgMDAyNyBUZg0KNTcuMzc1MCA3MjIuMjgwMCBUZA0KKCBBIFNpbXBsZSBQREYgRmlsZSApIFRqDQpFVA0KQlQNCi9GMSAwMDEwIFRmDQo2OS4yNTAwIDY4OC42MDgwIFRkDQooIFRoaXMgaXMgYSBzbWFsbCBkZW1vbnN0cmF0aW9uIC5wZGYgZmlsZSAtICkgVGoNCkVUDQpCVA0KL0YxIDAwMTAgVGYNCjY5LjI1MDAgNjY0LjcwNDAgVGQNCigganVzdCBmb3IgdXNlIGluIHRoZSBWaXJ0dWFsIE1lY2hhbmljcyB0dXRvcmlhbHMuIE1vcmUgdGV4dC4gQW5kIG1vcmUgKSBUag0KRVQNCkJUDQovRjEgMDAxMCBUZg0KNjkuMjUwMCA2NTIuNzUyMCBUZA0KKCB0ZXh0LiBBbmQgbW9yZSB0ZXh0LiBBbmQgbW9yZSB0ZXh0LiBBbmQgbW9yZSB0ZXh0LiApIFRqDQpFVA0KQlQNCi9GMSAwMDEwIFRmDQo2OS4yNTAwIDYyOC44NDgwIFRkDQooIEFuZCBtb3JlIHRleHQuIEFuZCBtb3JlIHRleHQuIEFuZCBtb3JlIHRleHQuIEFuZCBtb3JlIHRleHQuIEFuZCBtb3JlICkgVGoNCkVUDQpCVA0KL0YxIDAwMTAgVGYNCjY5LjI1MDAgNjE2Ljg5NjAgVGQNCiggdGV4dC4gQW5kIG1vcmUgdGV4dC4gQm9yaW5nLCB6enp6ei4gQW5kIG1vcmUgdGV4dC4gQW5kIG1vcmUgdGV4dC4gQW5kICkgVGoNCkVUDQpCVA0KL0YxIDAwMTAgVGYNCjY5LjI1MDAgNjA0Ljk0NDAgVGQNCiggbW9yZSB0ZXh0LiBBbmQgbW9yZSB0ZXh0LiBBbmQgbW9yZSB0ZXh0LiBBbmQgbW9yZSB0ZXh0LiBBbmQgbW9yZSB0ZXh0LiApIFRqDQpFVA0KQlQNCi9GMSAwMDEwIFRmDQo2OS4yNTAwIDU5Mi45OTIwIFRkDQooIEFuZCBtb3JlIHRleHQuIEFuZCBtb3JlIHRleHQuICkgVGoNCkVUDQpCVA0KL0YxIDAwMTAgVGYNCjY5LjI1MDAgNTY5LjA4ODAgVGQNCiggQW5kIG1vcmUgdGV4dC4gQW5kIG1vcmUgdGV4dC4gQW5kIG1vcmUgdGV4dC4gQW5kIG1vcmUgdGV4dC4gQW5kIG1vcmUgKSBUag0KRVQNCkJUDQovRjEgMDAxMCBUZg0KNjkuMjUwMCA1NTcuMTM2MCBUZA0KKCB0ZXh0LiBBbmQgbW9yZSB0ZXh0LiBBbmQgbW9yZSB0ZXh0LiBFdmVuIG1vcmUuIENvbnRpbnVlZCBvbiBwYWdlIDIgLi4uKSBUag0KRVQNCmVuZHN0cmVhbQ0KZW5kb2JqDQoNCjYgMCBvYmoNCjw8DQovVHlwZSAvUGFnZQ0KL1BhcmVudCAzIDAgUg0KL1Jlc291cmNlcyA8PA0KL0ZvbnQgPDwNCi9GMSA5IDAgUiANCj4+DQovUHJvY1NldCA4IDAgUg0KPj4NCi9NZWRpYUJveCBbMCAwIDYxMi4wMDAwIDc5Mi4wMDAwXQ0KL0NvbnRlbnRzIDcgMCBSDQo+Pg0KZW5kb2JqDQoNCjcgMCBvYmoNCjw8IC9MZW5ndGggNjc2ID4+DQpzdHJlYW0NCjIgSg0KQlQNCjAgMCAwIHJnDQovRjEgMDAyNyBUZg0KNTcuMzc1MCA3MjIuMjgwMCBUZA0KKCBTaW1wbGUgUERGIEZpbGUgMiApIFRqDQpFVA0KQlQNCi9GMSAwMDEwIFRmDQo2OS4yNTAwIDY4OC42MDgwIFRkDQooIC4uLmNvbnRpbnVlZCBmcm9tIHBhZ2UgMS4gWWV0IG1vcmUgdGV4dC4gQW5kIG1vcmUgdGV4dC4gQW5kIG1vcmUgdGV4dC4gKSBUag0KRVQNCkJUDQovRjEgMDAxMCBUZg0KNjkuMjUwMCA2NzYuNjU2MCBUZA0KKCBBbmQgbW9yZSB0ZXh0LiBBbmQgbW9yZSB0ZXh0LiBBbmQgbW9yZSB0ZXh0LiBBbmQgbW9yZSB0ZXh0LiBBbmQgbW9yZSApIFRqDQpFVA0KQlQNCi9GMSAwMDEwIFRmDQo2OS4yNTAwIDY2NC43MDQwIFRkDQooIHRleHQuIE9oLCBob3cgYm9yaW5nIHR5cGluZyB0aGlzIHN0dWZmLiBCdXQgbm90IGFzIGJvcmluZyBhcyB3YXRjaGluZyApIFRqDQpFVA0KQlQNCi9GMSAwMDEwIFRmDQo2OS4yNTAwIDY1Mi43NTIwIFRkDQooIHBhaW50IGRyeS4gQW5kIG1vcmUgdGV4dC4gQW5kIG1vcmUgdGV4dC4gQW5kIG1vcmUgdGV4dC4gQW5kIG1vcmUgdGV4dC4gKSBUag0KRVQNCkJUDQovRjEgMDAxMCBUZg0KNjkuMjUwMCA2NDAuODAwMCBUZA0KKCBCb3JpbmcuICBNb3JlLCBhIGxpdHRsZSBtb3JlIHRleHQuIFRoZSBlbmQsIGFuZCBqdXN0IGFzIHdlbGwuICkgVGoNCkVUDQplbmRzdHJlYW0NCmVuZG9iag0KDQo4IDAgb2JqDQpbL1BERiAvVGV4dF0NCmVuZG9iag0KDQo5IDAgb2JqDQo8PA0KL1R5cGUgL0ZvbnQNCi9TdWJ0eXBlIC9UeXBlMQ0KL05hbWUgL0YxDQovQmFzZUZvbnQgL0hlbHZldGljYQ0KL0VuY29kaW5nIC9XaW5BbnNpRW5jb2RpbmcNCj4+DQplbmRvYmoNCg0KMTAgMCBvYmoNCjw8DQovQ3JlYXRvciAoUmF2ZSBcKGh0dHA6Ly93d3cubmV2cm9uYS5jb20vcmF2ZVwpKQ0KL1Byb2R1Y2VyIChOZXZyb25hIERlc2lnbnMpDQovQ3JlYXRpb25EYXRlIChEOjIwMDYwMzAxMDcyODI2KQ0KPj4NCmVuZG9iag0KDQp4cmVmDQowIDExDQowMDAwMDAwMDAwIDY1NTM1IGYNCjAwMDAwMDAwMTkgMDAwMDAgbg0KMDAwMDAwMDA5MyAwMDAwMCBuDQowMDAwMDAwMTQ3IDAwMDAwIG4NCjAwMDAwMDAyMjIgMDAwMDAgbg0KMDAwMDAwMDM5MCAwMDAwMCBuDQowMDAwMDAxNTIyIDAwMDAwIG4NCjAwMDAwMDE2OTAgMDAwMDAgbg0KMDAwMDAwMjQyMyAwMDAwMCBuDQowMDAwMDAyNDU2IDAwMDAwIG4NCjAwMDAwMDI1NzQgMDAwMDAgbg0KDQp0cmFpbGVyDQo8PA0KL1NpemUgMTENCi9Sb290IDEgMCBSDQovSW5mbyAxMCAwIFINCj4+DQoNCnN0YXJ0eHJlZg0KMjcxNA0KJSVFT0YNCg==",
      "fileName": "somefiletest.pdf",
      "mimeType": "application/pdf"
    }
  ],
  "signature_redirect": "http://eid-sample-app.localhost/show-download-signed-file?file_id=AwX4I1Es5T49H2mr",
  "return_method_configs": true,
  "noemails": true
}
PropertyTypeDefaultDescription
client_idstringundefinedRequired. Get from id.eideasy.com after signing up.
secretstringundefinedRequired. Get from id.eideasy.com after signing up.
container_typestringundefinedRequired. Type of the container in which you wish to receive the signature. Possible values: "asice", "pdf", "cades" or "xades".
files[].fileContentstringundefinedRequired. A base64 encoded PDF document to be signed.
files[].fileNamestringundefinedRequired. Filename of the document to be signed.
files[].mimeTypestringundefinedRequired. mimeType of the document to be signed.
signature_redirectstringundefinedOptional. URL to where the user will be redirected after successful signing. This is only relevant in case you do not use Signature JSopen in new window for handling the browser-side user interactions.
return_method_configsbooleanfalseOptional. Whether to return the list of available signing method configs in the response.
noemailsbooleantrueOptional. Whether to send notification email or not. True will NOT send notification emails. Note that for API clients created before 2024-08-28, the default value is false.

Note: Don’t forget to set header Content-Type: application/json

Prepare the file for signing response

The API responds with a doc_id and a list of signing methods that are available for this signing session like this:

{
  "status": "OK",
  "doc_id": "QLcJD03LUP0S7DUeTGNobQdsiJGfzqRnULrGE0iV",
  "method_configs": [
    {
      "action_type": "mid-signature",
      "supported_countries": [
        "EE"
      ]
    },
    {
      "action_type": "smart-id-signature",
      "supported_countries": [
        "EE",
        "LV",
        "LT"
      ]
    },
    ...
  ]
}

Make a note of the doc_id value you receive (do not use the one in this example, it is expired) as we'll use it in the next steps.

2. Let user sign the file

IMPORTANT!

For the signature to be valid, you must show the file contents to the use before signing. After signing, you must provide the signed file to the user.

So, you most probably want to have a user interface with a file preview, buttons for selecting different signing methods and elements to handle method specific user interactions. E.g. some signing methods require user input like entering their phone number or personal id code.

If building all that seems like quite a bit of work then you're totally right, it is. That's why we've built a couple of front-end components you can use to handle method specific user interactions and API calls.

Enter the front-end components:

  • Browser Clientopen in new window - only handles the method specific API calls. Does not include any UI elements. Useful for when you wish to write your own UI elements.
  • Widgetopen in new window - a full-fledged UI component to handle all the signing methods and their user interactions and API calls. Can be used in Vue 2 and React based web apps and works equally well on plain old HTML pages too.
  • Signature JSopen in new window - a small browser-side JavaScript library that you can use to handle eID Easy signing flows in a popup window.

NOTE

If all this seems like more than what you bargained for then you might want to check out this guide which covers our simpler, pre-built Signing Page Flow.

As for the current tutorial, we are going to use the Signature JSopen in new window to get up and running quickly.

2.1 Setting up the front-end parts

Install the Signature JS:

yarn add @eid-easy/signature-js
npm install @eid-easy/signature-js

We'll then initialize the Signature JS with the following parameters:

const signature = new Signature({
  onSuccess: () => {
    console.log('User has successfully signed the document');
  },
  onFail: (error) => {
    console.log('Signing failed');
  },
});
PropertyTypeDefaultDescription
onSuccessfunctionundefinedRequired. This function is called when the user has successfully signed the document.
onFailfunctionundefinedRequired. This function is called when the user cancels or fails to sign the document and is unable to continue with the signing process. Note that this function is not called on validation errors or on other errors that the end user can correct and then proceed.
baseUrlstringhttps://id.eaideasy.comOptional. eID Easy API baseUrl. If you wish to make requests against the sandbox environment, set this to https://test.eideasy.com

You can now call the signature.start method in response to a user action. E.g. when they click a "start signing" button in your UI. Note: it is important to call signature.start inside the user-triggered event handlers, because some browsers (e.g. Firefox) will otherwise block the popup window. See this articleopen in new window for more information.

signature.start({
    clientId: /* your client_id */,
    docId: /* doc_id you received from the /prepare-files-for-signing API call */,
    actionType: 'smart-id-signature',
    country: 'EE',
    language: 'en', // ISO 639-1 two letter language code,
    inputValues: { // optional
        email: 'dummy@dummy.it',
        username: 'testuser',
        phone: '+37212345678',
        idcode: '987654321',
    },
});
PropertyTypeDefaultDescription
clientIdstringundefinedRequired. Get from id.eideasy.com after signing up.
docIdstringundefinedRequired. doc_id you receive from the /prepare-files-for-signing API call.
actionTypestringundefinedRequired. actionType is the identifier of the signing method you wish to use. You can find the available actionTypes for the current signing session in the response body (the method_configs property) of the prepare files call we made in step 1.
countrystringundefinedRequired. ISO 3166-1 alpha-2open in new window country code. You can find the available countries per each actionType for the current signing session in the response body (the method_configs property) of the prepare files call we made in step 1.
languagestringundefinedOptional Two letter ISO 639-1open in new window language code.
inputValues.emailstringundefinedOptional. Signer's email address. This is used to pre-fill the email field in the signing form.
inputValues.usernamestringundefinedOptional. Signer's method specific username. This is used to pre-fill the username field in the signing form.
inputValues.phonestringundefinedOptional. Signer's method specific phone number. This is used to pre-fill the phone number field in the signing form.
inputValues.idcodestringundefinedOptional. Signers's national id code. This is used to pre-fill the id code field in the signing form.

And we are almost done! Our end-user can now sign the document we prepared for them. After they have completed the signing process we probably want to fetch the signed file and let the end-user download it.

3. Fetch the signed file

Wait but how do I know when the user has signed the file?

  • If you are using our widget, browser client or signature js you can use the onSuccess callback function to for example send an AJAX request to your backend.
  • If you're using the method specific endpointsopen in new window directly (without the help of our widget or browser client), then you'll be polling the /complete endpoint.
  • Additionally, you can log in to your eID Easy admin dashboard and configure the "Signature notification URL" in the "EDIT" > "Notification hooks" view of your website. eID Easy server will send a POST request (that contains singer_id and doc_id) to this url every time a file gets signed.

NOTE for when you are not using Signature JS to handle the browser-side user interactions

Some signing methods (like the Latvian eParaksts Mobile) are redirect based. This means that end-user gets redirected to the method provider´s website to complete the signing process after which they'll be redirected back to the url you provided for signature_redirect in the https://id.eideasy.com/api/signatures/prepare-files-for-signing request. In these cases you can't use the widget's or browser client's onSuccess callback function. Our recommendation is to use a separate view for displaying the signature success. Provide the url of that view in the /prepare-files-for-signing request and redirect the user to that same view in the widget's onSuccess callback. Or in case of SPAs, just render the success view.

Alright, let's get this thing wrapped up. The only thing left to do is to download the signed file. For that, make a POST request to https://id.eideasy.com/api/signatures/download-signed-fileopen in new window:

{
  "secret": "{{secret}}",
  "client_id": "{{client_id}}",
  "doc_id":"{{doc_id}}"
}

doc_id - the same doc_id you got in step "1. Prepare the file for signing"

Example response:

{
  "status":"OK",
  "signed_file_contents":"UEsDBBQAAAgAAHI6z06KIflFHwAA",
  "signer_id":"34501234215",
  "filename":"signed_doc.pdf"
}

signed_file_contents - signed file in base64 encoding.

signer_id - signee’s personal ID code.

If the status is not OK, then you should not consider the signature to be verified.

And that’s it. Good job! 🙌 You're now able to use the eID Easy API to collect strong electronic signatures in your projects.

Don't forget to check out our showcase of possible integrations with the eID Easy API at https://demo.eideasy.comopen in new window. You can view the source code here: https://github.com/eideasy/eid-sample-appopen in new window

Last Updated: