---
title: "Electronic Signature Module"
url: "https://developer.incode.com/sdk-reference/web-sdk-2-module-electronic-signature/"
section: "sdk-reference"
group: "Incode Web SDK 2 Reference / Web SDK 2 Individual Modules"
version: "v1.1"
status: "live"
---
# Electronic Signature Module

:::note
This guide is specific to Web SDK 2.0. If you are still using 1.x, you can find documentation [here](/sdk-reference/web-sdk-reference).  Contact your Incode Representative for upgrade information and check if you are a candidate for this upgrade. <br /><br />Full rollout to all clients still TBD.
:::

The Electronic Signature module handles eIDAS-aligned electronic signing flows: render documents to be signed, collect compliance consents, capture the signature, and finalize. Three variants exist: base AES, Advanced Electronic Signature (AE), and Qualified Electronic Signature (QE). All three share a single state machine and manager API.

> Follows the [document-signing pattern](/sdk-reference/web-sdk-2-module-patterns/#4-document-signing-modules). See the patterns page for the shared lifecycle.

## Variants

`ae-signature` and `qe-signature` are thin wrappers around `electronic-signature`:

| Module                                  | Manager factory                    | Consent keys               |
| --------------------------------------- | ---------------------------------- | -------------------------- |
| `@incodetech/core/electronic-signature` | `createElectronicSignatureManager` | Caller-provided            |
| `@incodetech/core/ae-signature`         | `createAeSignatureManager`         | `AE_CONSENT_KEYS` (3 keys) |
| `@incodetech/core/qe-signature`         | `createQeSignatureManager`         | `QE_CONSENT_KEYS` (5 keys) |

The wrappers hardcode `variant: 'ae'` or `'qe'` and re-export the same state machine, state types, and helpers from the base module (`AeSignatureState` is `ElectronicSignatureState`, etc.).

Web components: `<incode-electronic-signature>`, `<incode-ae-signature>`, `<incode-qe-signature>`. All three import paths register their own tag and ship their own CSS.

```ts
// Base AES
import '@incodetech/web/electronic-signature';
import '@incodetech/web/electronic-signature/styles.css';

// Advanced Electronic Signature
import '@incodetech/web/ae-signature';
import '@incodetech/web/ae-signature/styles.css';

// Qualified Electronic Signature
import '@incodetech/web/qe-signature';
import '@incodetech/web/qe-signature/styles.css';
```

## Properties

| Property   | Type                        | Required | Description                   |
| ---------- | --------------------------- | -------- | ----------------------------- |
| `config`   | `ElectronicSignatureConfig` | ❌       | Configuration options         |
| `onFinish` | `() => void`                | ❌       | Called when signing completes |
| `onError`  | `(error: string) => void`   | ❌       | Called when the user dismisses (`closed`) |

## Configuration

```typescript
type ElectronicSignatureConfig = {
  variant?: 'ae' | 'qe'; // Hardcoded by the AE/QE wrapper modules
  uploadDocument?: boolean;
  downloadDocument?: boolean;
};
```

| Option             | Type           | Required | Description                                                        |
| ------------------ | -------------- | -------- | ------------------------------------------------------------------ |
| `variant`          | `'ae' \| 'qe'` | ❌       | Set automatically by the AE/QE wrapper modules. Omit for base AES. |
| `uploadDocument`   | `boolean`      | ❌       | Allow the user to upload a custom document to be signed.           |
| `downloadDocument` | `boolean`      | ❌       | Allow the user to download the signed document afterwards.         |

### Consent keys

The user must check all required consent boxes before signing. Each variant defines its own keys (re-exported from the variant's module):

```typescript
const AE_CONSENT_KEYS = [
  'terms',
  'signElectronically',
  'signDisplayed',
] as const;

const QE_CONSENT_KEYS = [
  'issuance',
  'qesAcknowledgement',
  'qscdConfirmation',
  'termsAgreement',
  'documentsReviewed',
] as const;
```

Helpers from `@incodetech/core/electronic-signature` (also re-exported from the AE/QE wrappers): `getDefaultConsentChecks(variant)` returns a fresh `ConsentChecks` map for the given variant (`'ae' | 'qe'`); `areAllConsented(consents)` returns whether every key in that map is checked.

## State machine

`ElectronicSignatureState` is a discriminated union over `status`:

| Status       | Description                                                      |
| ------------ | ---------------------------------------------------------------- |
| `loading`    | Fetching the documents to be signed.                             |
| `uploading`  | User selects a document to upload (when `uploadDocument` is set). |
| `reviewing`  | Document preview before upload confirmation.                       |
| `signing`    | Documents shown; user toggles consent checkboxes.                |
| `processing` | Server-side signing in progress.                                 |
| `success`    | Signing accepted (auto-finishes after 3s unless download flow).  |
| `signError`  | Signing failed; error screen shown for 3s then auto-finishes.    |
| `finished`   | Terminal success.                                                  |
| `closed`     | User dismissed.                                                    |
| `error`      | Recoverable upload/fetch-docs failure (Try Again).               |

The `state.documents` array (when populated) carries the `ElectronicSignatureDocument[]` to render: `{ documentRef, documentUrl }`.

A few states carry additional fields beyond `documents`: `uploading` and `reviewing` add `fileName` (`reviewing` also adds `fileUrl`); `signing` adds `variant`, `consentChecks`, `allConsented`, and `viewingDocumentUrl` (set while `viewDocument()` is open); `success` adds `signedDocuments: { signed: boolean; signedDocumentUrl?: string }[]` and `downloadDocument`. The base AES endpoint returns a `signedDocumentUrl` per document; the QES endpoint acknowledges with `{ success: true }` and no document URL, so `signedDocumentUrl` is absent for QE signatures — check `signed` rather than assuming a URL is always present.

## API methods

| Method                                      | Purpose                                                      |
| ------------------------------------------- | ------------------------------------------------------------ |
| `load()`                                    | Fetch documents.                                             |
| `setConsent(name, checked)`                 | Toggle a consent checkbox by key.                            |
| `selectFile(fileName, fileData, fileUrl)`   | Provide a custom document (when `uploadDocument` is `true`). |
| `replaceFile()`                             | Clear the previously selected file.                          |
| `confirmFile()`                             | Confirm document selection and proceed to signing.           |
| `viewDocument(url)` / `closeDocumentView()` | Open / close the document preview.                           |
| `sign()`                                    | Produce the signature once consents are checked.             |
| `finish()`                                  | Acknowledge `success` and finish.                            |
| `retry()`                                   | After `error`, restart.                                      |
| `close()`                                   | Dismiss (transitions to `closed`).                           |

Plus the base lifecycle: `subscribe`, `getState`, `stop`. Unlike the face-capture and ID-capture managers, this manager has no `reset()` — create a new manager instance to start over.

## See also

- [Module: Signature](/sdk-reference/web-sdk-2-module-signature/): handwritten signature on canvas (no document review)
- [Module Patterns → document-signing](/sdk-reference/web-sdk-2-module-patterns/#4-document-signing-modules)
- [Individual Modules](/sdk-reference/web-sdk-2-individual-modules/)