Autogram SDK is a TS/JS library that allows you to use the Autogram signer family (Autogram, Autogram V Mobile) from web. Not only does it provide an API to sign documents, but it also adds a UI for a consistent process of choosing the signer process (desktop/mobile).
UI is implemented using lit-element and lit-html, so it's lightweight and easy to customize and thanks to shadow DOM, it's encapsulated and it won't interfere with your styles.
npm install autogram-sdk
Some dependencies (zod, js-base64, idb-keyval, …) are declared as peer dependencies; npm 7+ installs them automatically. The self-contained builds in Distribution formats have everything inlined and need no install at all.
The package exposes four entry points. Pick the highest-level one that fits — most applications only need autogram-sdk/with-ui.
| Import | What it contains | Where it can run |
|---|---|---|
autogram-sdk/with-ui |
CombinedClient / createAutogramClient — the full signing flow with the built-in dialog UI for choosing between desktop and mobile signing. autogram-sdk/ui is an alias. |
Browser page only — importing it registers custom elements as a side effect. |
autogram-sdk |
The headless core: DesktopClient, MobileClient, error classes (AutogramError, …), shared types, and the RPC helpers (defineRpcService, …) used to bridge contexts. |
Anywhere — pages, service workers, extension background scripts. No UI, no side effects. |
autogram-sdk/autogram-api |
Low-level HTTP client (apiClient) for the Autogram desktop app's local server. |
Anywhere. |
autogram-sdk/avm-api |
Low-level client for the Autogram v mobile (AVM) server API, including device pairing (AutogramVMobileIntegration) and the QR-pairing simulation helper (AutogramVMobileSimulation). |
Anywhere. |
The layering: with-ui builds on DesktopClient/MobileClient from the core, which in turn build on autogram-api/avm-api. Drop down a level when you need your own UI (see the DesktopClient demo) or your own transport (see channels).
Every entry point is built in three flavors:
| Files | Format | Dependencies | Intended consumer |
|---|---|---|---|
dist/*.mjs, dist/*.js + .d.ts |
ESM + CJS (the npm exports map) |
External (dependencies / peerDependencies) |
Projects with a bundler (Vite, webpack, …) — gives tree-shaking and dependency deduping. |
dist/bundled/*.mjs |
ESM, self-contained | Inlined | <script type="module"> straight from a static server or CDN, no bundler needed. |
dist/*.iife.js |
IIFE, self-contained (AutogramSDK global) |
Inlined | Classic <script> tag; index-all.iife.js is the usual choice (core + UI). |
import { createAutogramClient } from "autogram-sdk/with-ui";
const client = await createAutogramClient();
const { content, mimeType, signatures } = await client.sign(
{
content: "hello world",
mimeType: "text/plain",
filename: "hello.txt",
},
{
form: "XAdES",
container: "ASiC_E",
}
);
// content is Base64; signatures is [{ signedBy, issuedBy }, ...]
Pass an array to sign several documents together with a single signature ("spoločná autorizácia dokumentov"). Each document carries its own MIME type and optional XML Datacontainer parameters. Requires the Autogram desktop app 2.8.0 or newer; the method chooser is skipped (Autogram v mobile cannot do this).
const { content, mimeType } = await client.sign(
[
{
content: formXml,
mimeType: "application/xml",
filename: "form.xml",
xdcParameters: { autoLoadEform: true },
},
{
content: pdfBase64,
mimeType: "application/pdf",
encoding: "base64",
filename: "attachment.pdf",
},
],
{ form: "XAdES", container: "ASiC_E" }
);
The SDK detects the running Autogram version: 2.8.0 and newer is used through
POST /api/v1/sign, older versions through the legacy POST /sign (one
document only). Requests an older Autogram cannot fulfil (multiple
documents, requireQualifiedCertificate, checkPDFEmbeddedAttachments)
fail with an app-version-too-low error and the dialog asks the user to
update Autogram.
Upgrading from 0.6.x? See docs/MIGRATION.md — legacy
calls convert with fromLegacySignArgs().
Serve the file yourself or point at a CDN that mirrors npm (e.g. https://cdn.jsdelivr.net/npm/autogram-sdk/dist/…).
AutogramSDK global)<script src="dist/index-all.iife.js"></script>
<script type="module">
// type="module" only for top-level await; the AutogramSDK global works
// from any script, see demos/iife-combined.html for a classic-script setup
const client = await AutogramSDK.createAutogramClient();
const { content, mimeType, signatures } = await client.sign(
{
content: "hello world",
mimeType: "text/plain",
filename: "hello.txt",
},
{
form: "XAdES",
container: "ASiC_E",
}
);
</script>
Same API as the npm build, but with dependencies inlined so the browser can load it directly:
<script type="module">
import { createAutogramClient } from "./dist/bundled/index-all.mjs";
const client = await createAutogramClient();
// …same sign() call as above
</script>
All SDK errors carry a machine-readable code. Classify them with
AutogramError.is() (works even for errors that crossed a postMessage
boundary, where instanceof fails):
import { AutogramError } from "autogram-sdk";
try {
await client.sign(...);
} catch (e) {
if (AutogramError.is(e, "user-cancelled")) {
// user closed the dialog — not a failure
} else if (AutogramError.is(e, "app-not-installed")) {
// point the user to autogram.slovensko.digital
} else if (AutogramError.is(e, "app-version-too-low")) {
// the dialog already asked the user to update Autogram
} else {
throw e;
}
}
See docs/API.md for the full API reference, docs/MIGRATION.md for upgrade notes, and docs/API-PROPOSAL.md for the redesign roadmap. Generated TypeDoc reference is published at https://slovensko-digital.github.io/autogram-extension/autogram-sdk/.
For most web applications the basic usage above is all you need — CombinedClient.init() called without arguments works out of the box.
Channels become relevant when the SDK runs in an environment where it cannot make direct network requests from the page. A channel is simply an object that implements the communication contract with a signing back-end (desktop app or AVM cloud service). CombinedClient delegates all actual network calls to its two channels, keeping UI and transport completely separate.
This separation makes it possible to move the network calls into a different execution context — for example a service worker or a browser-extension background script — and forward them over a message bridge instead. Autogram Extension uses this: instead of the default channels it passes its own implementations that proxy every call through the content-script ↔ injected-script message bridge.
// Simple case — use defaults, no channels needed, communicate directly
const client = await createAutogramClient();
// Advanced case — inject custom channel implementations
const client = await createAutogramClient({
mobileChannel: new MyAvmChannel(), // implements AutogramVMobileIntegrationInterfaceStateful
desktopChannel: new MyDesktopChannel(), // implements AutogramDesktopIntegrationInterface
});
A user who pairs a phone with your integration gets later signing requests as push notifications in Autogram v mobile, with no QR scan. Turn it on with pairingEnabled:
const client = await createAutogramClient({ pairingEnabled: true });
The dialog then shows a pairing link on the QR screen. Once a phone is paired there, the dialog confirms it and sends the request to the phone; the user can still go back to the signing QR. After a successful mobile signature with no paired phone, the dialog shows a success page offering pairing; sign() has already resolved by then. Users who already have a paired phone skip it.
Notifications are an optional capability of the mobile channel. The default channel supports them. A custom mobileChannel supports them only if it implements getPairingQrCodeUrl(), sendNotification() and getPairedDevices(). If it leaves them out, users sign by scanning the per-document QR code and are never asked to pair.
Pairings are bound to the integration identity (key pair + GUID). By default it is kept in the page origin's IndexedDB. Pass mobileStorage (any { get, set } store) to keep it elsewhere. See docs/API.md for details.
npm run build:release
# or
npm run build:watch
using npm run build:watch is usefult when developing using npm link
npm run generate-autogram-api-types
npm run generate-avm-api-types
Autogram Desktop types are generated from local app running on default port. AVM types are generated from server.
npm run generate-docs
The deploy-pages workflow regenerates the docs on every push to master and publishes them to https://slovensko-digital.github.io/autogram-extension/autogram-sdk/.
npm run build:watch in the autogram-sdk directorynpm link in the autogram-sdk directorynpm link autogram-sdk in the project where you want to use autogram-sdkSometimes the link breaks and you need to do whole process again.
npm run demo
Build the lib first (npm run build), then npm run demo starts a static server on port 8080 and opens http://localhost:8080/demos/ with one demo page per build flavor:
| Demo | Build flavor | How it loads the SDK |
|---|---|---|
esm-bundled.html |
dist/bundled/*.mjs — ESM, dependencies inlined |
<script type="module">, works from any static server |
esm-external.html |
dist/*.mjs — ESM, dependencies external (the npm package build) |
<script type="module"> + import map resolving bare imports to esm.sh (needs network) |
iife-combined.html |
dist/index-all.iife.js — IIFE, dependencies inlined |
Classic <script> tag, AutogramSDK global; signs a PDF via CombinedClient |
iife-desktop.html |
dist/index-all.iife.js — IIFE, dependencies inlined |
Classic <script> tag; headless DesktopClient with custom progress UI |