@esignglobal/envelope-cli
v0.5.0
Published
CLI for sending eSignGlobal envelopes
Readme
@esignglobal/envelope-cli
CLI for sending eSignGlobal envelopes, managing attachments, comparing contracts, and verifying PDF signatures.
Installation
npm install -g @esignglobal/envelope-cliOr run without installing via npx:
npx @esignglobal/envelope-cli <command>Commands
config health
Check API key validity and connectivity.
npx @esignglobal/envelope-cli config healthcreate-envelope
Create a draft envelope without uploading a file. Returns an envelopeId that can be used with sender-view to open the interactive sender page.
npx @esignglobal/envelope-cli create-envelope \
--subject <subject> \
[--remark <remark>] \
[--expire <seconds>] \
[--redirect-url <url>] \
[--callback-url <url>]Options:
| Flag | Required | Description |
|------|----------|-------------|
| --subject | Yes | Envelope subject / name |
| --remark | No | Message to recipients (max 1000 characters) |
| --expire | No | Expiration in seconds (86400–7776000, i.e. 1–90 days) |
| --redirect-url | No | HTTPS redirect URL shown to signers after signing |
| --callback-url | No | HTTPS webhook URL for envelope status events |
Example:
npx @esignglobal/envelope-cli create-envelope \
--subject "Service Agreement" \
--remark "Please review and send for signature" \
--expire 604800Output:
{
"success": true,
"message": "Envelope draft created successfully",
"data": {
"envelopeId": "c0c830ebf49641409048a53809d4de8e",
"envelopeStatus": 0
}
}sender-view
Get a sender view URL for a draft envelope (status 0). Open the URL in a browser or embed it in an iframe to add documents, configure signers, and send the envelope interactively.
npx @esignglobal/envelope-cli sender-view \
--envelope-id <id> \
--return-url <url> \
[--starting-page <page>] \
[--submit-action <action>] \
[--no-back-button] \
[--lock <document|signerInfo>]Options:
| Flag | Required | Description |
|------|----------|-------------|
| --envelope-id | Yes | Draft envelope ID (status must be 0) |
| --return-url | Yes | Redirect URL after the sender submits or saves |
| --starting-page | No | "Prepare Page" (default) or "Tagging Page" |
| --submit-action | No | "send" (default, shows Send button) or "save" (shows Save button) |
| --no-back-button | No | Hide the Back button on the Tagging Page |
| --lock | No | Comma-separated list of locked areas: document, signerInfo |
Example:
# Create a draft then open the sender view
npx @esignglobal/envelope-cli create-envelope --subject "Offer Letter"
npx @esignglobal/envelope-cli sender-view \
--envelope-id c0c830ebf49641409048a53809d4de8e \
--return-url "https://app.example.com/done"Output:
{
"success": true,
"message": "Sender view URL retrieved",
"data": {
"url": "https://app-sml.esignglobal.com/document/refine-info?envelopeId=...&tcode=...&dc=sml"
}
}send-envelope
Upload a PDF (or reference an existing file by key) and send it to one or more signers.
# Upload a local PDF file
npx @esignglobal/envelope-cli send-envelope \
--file <absolute-pdf-path> \
--signers '<json>' \
[--subject <subject>] \
--confirm
# Use an existing fileKey (e.g. from render-template)
npx @esignglobal/envelope-cli send-envelope \
--file-key <fileKey> \
--signers '<json>' \
[--subject <subject>] \
--confirmOptions:
| Flag | Required | Description |
|------|----------|-------------|
| --file | Yes* | Absolute path to a local PDF file |
| --file-key | Yes* | Existing file key (e.g. returned by get-render-result) |
| --signers | Yes | JSON array of signer objects (see format below) |
| --subject | No | Envelope subject line (defaults to "Please sign this PDF" when using --file-key) |
| --confirm | Yes | Required confirmation flag before sending |
* --file and --file-key are mutually exclusive — provide exactly one.
Signers format:
[
{ "userName": "Bob Smith", "userEmail": "[email protected]" }
]Sequential signing (via signOrder):
[
{ "userName": "Bob Smith", "userEmail": "[email protected]", "signOrder": 1 },
{ "userName": "Alice Jones","userEmail": "[email protected]","signOrder": 2 }
]Examples:
# Upload a local PDF
npx @esignglobal/envelope-cli send-envelope \
--file "/tmp/contract.pdf" \
--signers '[{"userName":"Bob Smith","userEmail":"[email protected]"}]' \
--subject "Please sign this contract" \
--confirm
# Use a fileKey from a rendered template
npx @esignglobal/envelope-cli send-envelope \
--file-key '$b8605de1-48a3-4a62-ba53-48764481c007$339228622' \
--signers '[{"userName":"Bob Smith","userEmail":"[email protected]"}]' \
--subject "Please sign this document" \
--confirmget-envelope
Retrieve details for an envelope, including its status, signers, and documents.
npx @esignglobal/envelope-cli get-envelope --envelope-id <id>Options:
| Flag | Required | Description |
|------|----------|-------------|
| --envelope-id | Yes | Envelope ID to query |
Example:
npx @esignglobal/envelope-cli get-envelope --envelope-id abc123Output:
{
"success": true,
"message": "Envelope detail retrieved",
"data": {
"envelopeId": "abc123",
"status": "In Progress (1)",
"subject": "Please sign this contract",
"remark": "",
"createTime": "2026-03-24 10:00:00 UTC+08:00",
"endTime": "",
"redirectUrl": "",
"declinedReason": "",
"canceledReason": "",
"initiator": { "userName": "Alice", "userEmail": "[email protected]" },
"signers": [
{
"userName": "Bob Smith",
"userEmail": "[email protected]",
"signOrder": 1,
"status": "Pending (0)",
"signDate": ""
}
],
"signFiles": [{ "fileKey": "4150a67c-d4f0-45e6-88e9-541ce6d0c73c" }],
"attachments": [],
"ccInfos": []
}
}Envelope status codes:
| Code | Status | |------|--------| | 0 | Draft | | 1 | In Progress | | 2 | Completed | | 3 | Expired | | 4 | Declined | | 5 | Canceled |
Signer status codes:
| Code | Status | |------|--------| | 0 | Pending | | 1 | Signing | | 2 | Signed |
cancel-envelope
Cancel an in-progress envelope that has not been fully signed. After cancellation the envelope is suspended and all signatures within it are rendered invalid.
npx @esignglobal/envelope-cli cancel-envelope \
--envelope-id <id> \
--reason <reason> \
--confirmOptions:
| Flag | Required | Description |
|------|----------|-------------|
| --envelope-id | Yes | Envelope ID to cancel |
| --reason | Yes | Reason for cancellation |
| --confirm | Yes | Required confirmation flag before cancelling |
Example:
npx @esignglobal/envelope-cli cancel-envelope \
--envelope-id abc123 \
--reason "Signer's information was wrong." \
--confirmOutput:
{
"success": true,
"message": "Envelope cancelled successfully"
}urge-envelope
Send a reminder to all pending signers of an in-progress envelope.
npx @esignglobal/envelope-cli urge-envelope --envelope-id <id>Options:
| Flag | Required | Description |
|------|----------|-------------|
| --envelope-id | Yes | Envelope ID to send reminders for |
Rate limit: Reminders can only be sent once every 30 minutes per envelope.
Example:
npx @esignglobal/envelope-cli urge-envelope --envelope-id abc123Output:
{
"success": true,
"message": "Reminder sent successfully"
}download-envelope
Download signed files for a completed envelope.
npx @esignglobal/envelope-cli download-envelope \
--envelope-id <id> \
[--type zip|list] \
[--output <absolute-dir>]Options:
| Flag | Required | Default | Description |
|------|----------|---------|-------------|
| --envelope-id | Yes | — | Envelope ID from send-envelope response |
| --type | No | zip | list returns file metadata and download URLs; zip downloads the archive |
| --output | No | cwd | Directory to save the downloaded zip |
Envelope status codes: 0=Draft 1=Signing 2=Completed 3=Expired 4=Rejected 5=Voided
Example:
# List files and download URLs
npx @esignglobal/envelope-cli download-envelope --envelope-id abc123 --type list
# Download zip archive
npx @esignglobal/envelope-cli download-envelope --envelope-id abc123 --output /tmpverify-signature
Verify digital signatures in a signed PDF. Runs fully offline — no API key required.
npx @esignglobal/envelope-cli verify-signature --file <absolute-pdf-path>Example:
npx @esignglobal/envelope-cli verify-signature --file "/tmp/signed_contract.pdf"Output:
{
"success": true,
"message": "Signature verification completed",
"data": {
"fileName": "signed_contract.pdf",
"signatureCount": 1,
"integrity": true,
"signatures": [
{
"id": "sig1",
"isValid": true,
"signer": "Example Signer",
"declaredTime": "2026-03-23 10:05:05 UTC+08:00",
"signatureAlgorithm": "RSA / SHA-256",
"timestampIssuer": "GlobalSign TSA ...",
"certificate": {
"serialNumber": "00FA",
"validFrom": "2025-02-27 19:30:10 UTC+08:00",
"validUntil": "2030-02-26 19:30:10 UTC+08:00"
}
}
]
}
}| Field | Values | Description |
|-------|--------|-------------|
| integrity | true / false / null | File unmodified / tampered / unknown |
| isValid | true / false / null | Signature valid / invalid / unknown |
| timestampIssuer | string | TSA certificate issuer, or "Local time" if no trusted timestamp |
get-template
Retrieve details of a template, including its fields and status.
npx @esignglobal/envelope-cli get-template --template-id <id>Options:
| Flag | Required | Description |
|------|----------|-------------|
| --template-id | Yes | Template ID to query |
Output:
{
"success": true,
"message": "Template detail retrieved",
"data": {
"templateId": "cbee61205be2443ea4bb1a7ea4227295",
"templateName": "My Template",
"templateStatus": 1,
"templateType": 0,
"createTime": 1774577174834,
"updateTime": 1774577229341,
"fields": [
{
"fieldId": "2915c4aa8bb941d880bed147622df2af",
"fieldName": "Text Field 1",
"fieldType": 8,
"required": true,
"fieldKey": null
}
]
}
}render-template
Create a file from a template by filling in field values. Returns a taskId to poll with get-render-result.
npx @esignglobal/envelope-cli render-template \
--template-id <id> \
[--file-name <name>] \
[--fields '<json>'] \
[--callback-url <url>]Options:
| Flag | Required | Description |
|------|----------|-------------|
| --template-id | Yes | Template ID to render |
| --file-name | No | Output file name |
| --fields | No | JSON array of field values (see format below) |
| --callback-url | No | HTTPS webhook URL called when rendering completes |
Fields format:
[
{ "fieldId": "2915c4aa8bb941d880bed147622df2af", "fieldValue": "Hello World" }
]Example:
npx @esignglobal/envelope-cli render-template \
--template-id cbee61205be2443ea4bb1a7ea4227295 \
--fields '[{"fieldId":"2915c4aa8bb941d880bed147622df2af","fieldValue":"Hello World"}]'Output:
{
"success": true,
"message": "Template render task created",
"data": {
"taskId": "818685a4bdf6426bbb3774a6825f4ee9"
}
}get-render-result
Poll the status of a render task. Once succeeded, returns a fileKey and temporary downloadUrl.
npx @esignglobal/envelope-cli get-render-result --task-id <id>Options:
| Flag | Required | Description |
|------|----------|-------------|
| --task-id | Yes | Task ID returned by render-template |
Output:
{
"success": true,
"message": "Render task detail retrieved",
"data": {
"taskId": "818685a4bdf6426bbb3774a6825f4ee9",
"taskStatus": "Succeeded (2)",
"fileKey": "$b8605de1-48a3-4a62-ba53-48764481c007$339228622",
"downloadUrl": "https://file-sml.esignglobal.com/...",
"description": "",
"fields": []
}
}The fileKey can be passed directly to send-envelope --file-key to send the rendered document for signing.
contract-compare
Compare two PDF contracts side by side. Returns a URL to the eSignGlobal contract comparison page where differences between the two documents are highlighted.
Both the standard (baseline) file and the comparative file can be provided either as a local PDF path (auto-uploaded) or as an existing file key.
# Compare two local PDF files
npx @esignglobal/envelope-cli contract-compare \
--standard-file <absolute-pdf-path> \
--comparative-file <absolute-pdf-path>
# Compare using existing file keys
npx @esignglobal/envelope-cli contract-compare \
--standard-file-key <key> \
--comparative-file-key <key>
# Mix: upload the standard file, reference the comparative by key
npx @esignglobal/envelope-cli contract-compare \
--standard-file <absolute-pdf-path> \
--comparative-file-key <key> \
[--filter-header-footer] \
[--filter-symbols <sym1,sym2,...>]Options:
| Flag | Required | Description |
|------|----------|-------------|
| --standard-file | Yes* | Absolute path to the baseline PDF (auto-uploaded) |
| --standard-file-key | Yes* | Existing file key for the baseline document |
| --comparative-file | Yes* | Absolute path to the PDF to compare against (auto-uploaded) |
| --comparative-file-key | Yes* | Existing file key for the document to compare against |
| --filter-header-footer | No | Exclude page headers and footers from the comparison |
| --filter-symbols | No | Comma-separated punctuation marks to ignore (e.g. ".,。") |
* --standard-file and --standard-file-key are mutually exclusive — provide exactly one. Same for the comparative pair.
Supports PDF files up to 30 MB each.
Examples:
# Compare two local contracts, ignoring headers/footers
npx @esignglobal/envelope-cli contract-compare \
--standard-file "/tmp/contract_v1.pdf" \
--comparative-file "/tmp/contract_v2.pdf" \
--filter-header-footer
# Compare using file keys returned by get-render-result
npx @esignglobal/envelope-cli contract-compare \
--standard-file-key '$b8605de1-48a3-4a62-ba53-48764481c007$339228622' \
--comparative-file-key '$c9706ef2-59b4-5b73-cb64-59875592d118$440339733'
# Ignore specific punctuation during comparison
npx @esignglobal/envelope-cli contract-compare \
--standard-file "/tmp/contract_v1.pdf" \
--comparative-file "/tmp/contract_v2.pdf" \
--filter-symbols ".,。、"Output:
{
"success": true,
"message": "Contract comparison URL retrieved",
"data": {
"contractCompareUrl": "https://esignglobal.cn/xxxx",
"contractCompareBizId": "501d7b6a95a74a478757ec49c89dcaba"
}
}Open contractCompareUrl in a browser to view the highlighted differences between the two documents.
add-attachments
Add one or more attachments to a draft envelope (status 0). Attachments are reference-only files (images, videos, recordings, etc.) that are not signed.
Upload each attachment first using the Upload Documents API to obtain its
fileKey, then pass it here.
npx @esignglobal/envelope-cli add-attachments \
--envelope-id <id> \
--file-keys '<json-array>'Options:
| Flag | Required | Description |
|------|----------|-------------|
| --envelope-id | Yes | Draft envelope ID (status must be 0) |
| --file-keys | Yes | JSON array of file key strings to attach |
Example:
npx @esignglobal/envelope-cli add-attachments \
--envelope-id abc123 \
--file-keys '["fileKey1","fileKey2"]'Output:
{
"success": true,
"message": "Attachments added successfully"
}delete-attachments
Delete one or more attachments from a draft envelope. Attachments can only be deleted before the envelope is initiated.
npx @esignglobal/envelope-cli delete-attachments \
--envelope-id <id> \
--file-keys '<json-array>' \
--confirmOptions:
| Flag | Required | Description |
|------|----------|-------------|
| --envelope-id | Yes | Envelope ID |
| --file-keys | Yes | JSON array of file key strings to remove |
| --confirm | Yes | Required confirmation flag before deleting |
Example:
npx @esignglobal/envelope-cli delete-attachments \
--envelope-id abc123 \
--file-keys '["fileKey1"]' \
--confirmOutput:
{
"success": true,
"message": "Attachments deleted successfully"
}add-cc
Add one or more CC (carbon copy) recipients to an envelope. Supported when the envelope is in Draft (status 0) or In Progress (status 1). CC recipients receive a notification and can view the envelope but cannot sign it.
npx @esignglobal/envelope-cli add-cc \
--envelope-id <id> \
--cc-infos '[{"userEmail":"...","userName":"..."}]'Options:
| Flag | Required | Description |
|------|----------|-------------|
| --envelope-id | Yes | Envelope ID |
| --cc-infos | Yes | JSON array of CC recipient objects |
Each CC recipient object must include:
userEmail— email address of the CC recipientuserName— display name shown on the signing page and in notifications
Example:
npx @esignglobal/envelope-cli add-cc \
--envelope-id abc123 \
--cc-infos '[{"userEmail":"[email protected]","userName":"Alice"},{"userEmail":"[email protected]","userName":"Bob"}]'Output:
{
"success": true,
"message": "CC recipients added successfully",
"data": {
"envelopeId": "abc123",
"CCInfos": [
{ "userEmail": "[email protected]", "userName": "Alice" },
{ "userEmail": "[email protected]", "userName": "Bob" }
]
}
}delete-cc
Remove one or more CC recipients from a draft envelope (status 0).
npx @esignglobal/envelope-cli delete-cc \
--envelope-id <id> \
--cc-infos '[{"userEmail":"..."}]' \
--confirmOptions:
| Flag | Required | Description |
|------|----------|-------------|
| --envelope-id | Yes | Envelope ID |
| --cc-infos | Yes | JSON array of objects with userEmail to remove |
| --confirm | Yes | Required confirmation flag before deleting |
Example:
npx @esignglobal/envelope-cli delete-cc \
--envelope-id abc123 \
--cc-infos '[{"userEmail":"[email protected]"}]' \
--confirmOutput:
{
"success": true,
"message": "CC recipients deleted successfully",
"data": {
"envelopeId": "abc123",
"CCInfos": [
{ "userEmail": "[email protected]", "userName": "Bob" }
]
}
}add-signers
Add one or more signers to a draft envelope (status 0). Signers can only be appended after any existing signers — inserting before someone who is currently signing or has already signed is not allowed. The same email address cannot be added twice; re-add to update signer information. Maximum 10 signers per envelope.
npx @esignglobal/envelope-cli add-signers \
--envelope-id <id> \
--signers '<json>'Options:
| Flag | Required | Description |
|------|----------|-------------|
| --envelope-id | Yes | Draft envelope ID (status must be 0) |
| --signers | Yes | JSON array of signer objects (see format below) |
Signers format:
[
{ "userName": "Bob Smith", "userEmail": "[email protected]", "signOrder": 1 }
]Each signer must include userName, userEmail, and signOrder. Optional fields per signer:
| Field | Description |
|-------|-------------|
| businessId | Developer-defined business number |
| deliveryMethods | Notification method: auto (default), none, email, sms, WhatsApp |
| freeFormSign | true to allow the signer to freely place stamps/signatures |
| authModes | Authentication method: noAuth (default), accessCode, sms, emailAuth, etc. |
Example:
npx @esignglobal/envelope-cli add-signers \
--envelope-id abc123 \
--signers '[{"userName":"Bob Smith","userEmail":"[email protected]","signOrder":1},{"userName":"Alice Jones","userEmail":"[email protected]","signOrder":2}]'Output:
{
"success": true,
"message": "Signers added successfully",
"data": {
"envelopeId": "abc123",
"signerInfos": [
{ "userEmail": "[email protected]", "userName": "Bob Smith", "signOrder": 1 },
{ "userEmail": "[email protected]", "userName": "Alice Jones", "signOrder": 2 }
]
}
}delete-signers
Remove one or more signers from a draft envelope (status 0). Requires --confirm.
npx @esignglobal/envelope-cli delete-signers \
--envelope-id <id> \
--signers '[{"userEmail":"..."}]' \
--confirmOptions:
| Flag | Required | Description |
|------|----------|-------------|
| --envelope-id | Yes | Draft envelope ID (status must be 0) |
| --signers | Yes | JSON array of objects with userEmail of signers to remove |
| --confirm | Yes | Required confirmation flag before deleting |
Example:
npx @esignglobal/envelope-cli delete-signers \
--envelope-id abc123 \
--signers '[{"userEmail":"[email protected]"}]' \
--confirmOutput:
{
"success": true,
"message": "Signers deleted successfully",
"data": {
"envelopeId": "abc123",
"signerInfos": []
}
}make-stamp
Generate a stamp image (PNG) locally — no API key required. Ported from the eSignGlobal online stamp tool.
Besides the original 8 web-tool templates, make-stamp now supports a higher-level mode:
--kind company: generate a round company seal with double rings, center star, arc text, and optional registration number.
8 templates are available, matching the web tool:
| Template | Shape | Description |
|----------|-------|-------------|
| 1 | Circle | Double-ring with arc outer text + center text |
| 2 | Circle | Corporate seal: gear outline + star band + top/bottom arc texts + center text |
| 3 | Circle | Gear + outer ring with arc text + center text |
| 4 | Rectangle | Top text + horizontal line + bottom text |
| 5 | Rectangle | 4 lines of text + signature line |
| 6 | Rectangle | 4 lines of text (large first two) |
| 7 | Ellipse | Inner ring + title + bottom text with line |
| 8 | Ellipse | Inner ring + 2 center lines |
npx @esignglobal/envelope-cli make-stamp \
--output <absolute-path.png> \
[--kind template|company] \
[--template <1-8>] \
[--color <hex>] \
[--font <font-name>] \
[--font-file <absolute-font-path>] \
[text flags per template]Common options:
| Flag | Required | Description |
|------|----------|-------------|
| --output | Yes | Absolute path for the output PNG file |
| --kind | No | Render mode: template (default) or company |
| --template | Template mode only | Template number 1–8 (default: 1) |
| --color | No | Stamp color as hex (default: #2446AA) |
| --font | No | Font family name (default: Arial) |
| --font-file | No | Absolute path to a local .ttf/.otf font file to register before rendering |
Size options:
| Flag | Applies to | Default |
|------|-----------|---------|
| --size | Templates 1–3 (circular) | 520 |
| --size | --kind company | 560 |
| --width | Templates 4–8 | 420 |
| --height | Templates 4–8 | 200 (4–6), 220 (7–8) |
Kind-specific flags:
| Kind | Flags |
|------|-------|
| company | --company-name or --company, --seal-label, --registration-no, --center-text |
Text flags by template:
| Template | Flags |
|----------|-------|
| 1 | --outer-text, --inner-text |
| 2 | --top-text, --bottom-text, --center-text |
| 3 | --outer-text, --inner-text |
| 4 | --top-text, --bottom-text |
| 5 | --line1, --line2, --line3, --line4 |
| 6 | --line1, --line2, --line3, --line4 |
| 7 | --title, --bottom-text |
| 8 | --line1, --line2 |
Use
|as a line separator in--inner-text,--center-text, e.g."COMMON|SEAL|UEN 123".
Examples:
# Round company seal
npx @esignglobal/envelope-cli make-stamp \
--kind company \
--company-name "ACME Global Technologies Ltd." \
--seal-label "Official Seal" \
--registration-no "91310000MA1K12345X" \
--output /tmp/acme-company-seal.png
# Template 1 – company double-ring seal
npx @esignglobal/envelope-cli make-stamp \
--template 1 \
--outer-text "ACME CORPORATION PVT. LTD." \
--inner-text "Authorised|Signatory" \
--color "#C00000" \
--output /tmp/seal1.png
# Template 2 – corporate seal with stars
npx @esignglobal/envelope-cli make-stamp \
--template 2 \
--top-text "CORPORATE SEAL" \
--bottom-text "EST. 2020" \
--center-text "ACME|CORP" \
--output /tmp/seal2.png
# Template 3 – gear circle seal
npx @esignglobal/envelope-cli make-stamp \
--template 3 \
--outer-text "YOUR COMPANY PTE LTD" \
--inner-text "COMMON|SEAL|UEN 12345678X" \
--output /tmp/seal3.png
# Template 4 – rectangular stamp
npx @esignglobal/envelope-cli make-stamp \
--template 4 \
--top-text "ACME Technologies" \
--bottom-text "Director" \
--output /tmp/stamp4.png
# Template 7 – elliptical stamp
npx @esignglobal/envelope-cli make-stamp \
--template 7 \
--title "ACME Technologies" \
--bottom-text "Approved" \
--output /tmp/stamp7.pngOutput:
{
"success": true,
"message": "Stamp image generated successfully",
"data": {
"kind": "template",
"template": 1,
"outputPath": "/tmp/seal1.png",
"width": 520,
"height": 520
}
}Note:
make-stamprequires thecanvaspackage. Install system dependencies first:# macOS brew install pkg-config cairo pango libpng jpeg giflib librsvg npm install canvas # Ubuntu / Debian sudo apt-get install build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev npm install canvas
Credential resolution
Required for all commands except verify-signature.
# Windows PowerShell
$env:ESIGNGLOBAL_APIKEY="your_api_key"
# macOS / Linux
export ESIGNGLOBAL_APIKEY="your_api_key"Get an API key:
- Sign in at
https://www.esignglobal.com - Go to Settings → Integration → Apps
- Create an application and copy the generated API key
Requirements
- Node.js 18 or later
canvaspackage (only required formake-stamp):npm install canvas- macOS:
brew install pkg-config cairo pango libpng jpeg giflib librsvg - Ubuntu/Debian:
sudo apt-get install build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev
- macOS:
