Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.spitshake.io/llms.txt

Use this file to discover all available pages before exploring further.

JavaScript SDK

The DocuTrust JavaScript SDK provides a global window.DocuTrust API for programmatic control over embedded signing forms and template builders. Use the SDK when you need imperative mounting, dynamic configuration, or event-driven integration that goes beyond static HTML attributes.

Loading the SDK

Include the embed script in your HTML. The script registers window.DocuTrust and defines the <docuseal-form> and <docuseal-builder> web components.
<script src="https://your-app.com/js/docutrust-embed.js"></script>
For single-page applications, you can load the script dynamically:
function loadDocuTrustSDK(host) {
  return new Promise(function (resolve, reject) {
    if (window.DocuTrust) {
      resolve(window.DocuTrust);
      return;
    }
    var script = document.createElement('script');
    script.src = host + '/js/docutrust-embed.js';
    script.onload = function () { resolve(window.DocuTrust); };
    script.onerror = function () { reject(new Error('Failed to load DocuTrust SDK')); };
    document.head.appendChild(script);
  });
}

// Usage
loadDocuTrustSDK('https://your-app.com').then(function (DocuTrust) {
  DocuTrust.configure({ host: 'https://your-app.com' });
  console.log('DocuTrust SDK loaded');
});

Methods

DocuTrust.configure(options)

Set the DocuTrust instance URL. Call this once before mounting any forms or builders. Parameters:
PropertyTypeRequiredDescription
hoststringYesBase URL of your DocuTrust instance, e.g., "https://your-app.com"
DocuTrust.configure({
  host: 'https://your-app.com'
});

DocuTrust.mount(options)

Mount a signing form into a container element. Returns the created DOM element. Parameters:
PropertyTypeRequiredDefaultDescription
elementstring or HTMLElementYesCSS selector or DOM element to mount into
submitterSlugstringYesSubmitter signing slug (the SLUG from /s/SLUG)
withTitlebooleanNotrueShow the template title
withDownloadButtonbooleanNotrueShow the download button after completion
withSendCopyButtonbooleanNotrueShow the “Send a copy” button
allowToResubmitbooleanNofalseAllow the signer to resubmit
languagestringNoUI language code (e.g., "en", "es", "fr")
emailstringNoPre-fill signer email
namestringNoPre-fill signer name
rolestringNoTarget a specific submitter role
previewbooleanNofalseEnable read-only preview mode
goToLastbooleanNofalseJump to last incomplete field
expandbooleanNofalseExpand form to full content height
autoscrollbooleanNotrueAuto-scroll to next field
skipFieldsstringNoComma-separated field names to skip
readonlyFieldsstringNoComma-separated read-only field names
valuesobjectNoPre-fill field values as key-value pairs
metadataobjectNoCustom metadata object
completedRedirectUrlstringNoRedirect URL after completion
externalIdstringNoLink signer to your system ID
tokenstringNoJWT token for authentication
logostringNoCustom logo URL
i18nobjectNoCustom i18n key overrides
withDeclinebooleanNofalseShow decline button
withFieldNamesbooleanNotrueShow field labels
withFieldPlaceholderstringNoPlaceholder text for fields
withCompleteButtonbooleanNotrueShow complete button
onlyRequiredFieldsbooleanNofalseShow only required fields
allowTypedSignaturebooleanNotrueAllow typed signatures
signaturestringNoPre-fill signature (base64/URL/text)
sendCopyEmailbooleanNotrueAllow send-copy email
orderAsOnPagebooleanNofalseOrder fields by page position
backgroundColorstringNoBackground color (HEX code)
minimizeFirstStepbooleanNofalseCollapse first step into compact bar
customCssstringNoCustom CSS rules injected into the form iframe
completedMessageTitlestringNoCustom completion screen title
completedMessageBodystringNoCustom completion screen body text
completedButtonTitlestringNoCustom completion button text
completedButtonUrlstringNoCustom completion button URL
minimizebooleanNofalseAlways minimize (collapse) field panels
Returns: The created <docuseal-form> DOM element.
var formElement = DocuTrust.mount({
  element: '#signing-container',
  submitterSlug: 'aB3kL9mNpQ',
  email: 'jane.doe@example.com',
  name: 'Jane Doe',
  role: 'Recipient',
  externalId: 'usr_9f84b2a1',
  logo: 'https://your-app.com/assets/logo.png',
  language: 'en',
  withTitle: true,
  withDownloadButton: true,
  withSendCopyButton: true,
  withDecline: true,
  withFieldNames: true,
  withFieldPlaceholder: 'Enter value here',
  withCompleteButton: true,
  onlyRequiredFields: false,
  allowToResubmit: false,
  allowTypedSignature: true,
  goToLast: true,
  expand: true,
  autoscroll: true,
  preview: false,
  minimizeFirstStep: true,
  orderAsOnPage: false,
  sendCopyEmail: true,
  backgroundColor: '#ffffff',
  customCss: 'body { font-family: "Inter", sans-serif; } .field-label { color: #1e3a5f; }',
  completedMessageTitle: 'Thank you for signing!',
  completedMessageBody: 'Your signed document will be emailed to you shortly.',
  completedButtonTitle: 'Return to Dashboard',
  completedButtonUrl: 'https://your-app.com/dashboard',
  minimize: false,
  skipFields: 'Internal Notes',
  readonlyFields: 'Contract Amount,Start Date',
  signature: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...',
  values: {
    'Full Name': 'Jane Doe',
    'Email': 'jane.doe@example.com',
    'Company': 'Acme Inc',
    'Title': 'VP of Operations',
    'Date': '2026-04-08'
  },
  metadata: {
    customer_id: 'cust_8472',
    deal_id: 'deal_291',
    plan: 'enterprise',
    source: 'sdk_integration'
  },
  i18n: {
    submit: 'Confirm & Sign',
    next: 'Continue',
    decline: 'Decline to Sign'
  },
  completedRedirectUrl: 'https://your-app.com/signing-complete'
});

console.log('Form mounted:', formElement);

DocuTrust.mountBuilder(options)

Mount the template builder into a container element. Returns the created DOM element. Parameters:
PropertyTypeRequiredDefaultDescription
elementstring or HTMLElementYesCSS selector or DOM element to mount into
templateIdnumber or stringNoTemplate ID (session auth only)
tokenstringNoJWT token from POST /api/embed/token
languagestringNoUI language code
autosavebooleanNotrueEnable auto-save
previewbooleanNotrueShow document preview panel
withTitlebooleanNotrueShow editable template title
withSendButtonbooleanNotrueShow the “Send” button
withRecipientsbooleanNotrueShow recipients section
onlyDefinedFieldsbooleanNofalseOnly show pre-defined field types
fieldsarrayNoPre-defined field definitions
rolesarrayNoPre-defined submitter role names
hoststringNoOverride the configured host URL
submittersarrayNoDefault submitters with name and email
requiredFieldsarrayNoField names required before saving
fieldTypesstringNoComma-separated allowed field types
drawFieldTypestringNoDefault field type when drawing
customButtonTitlestringNoCustom primary button text
customButtonUrlstringNoURL for custom button navigation
withUploadButtonbooleanNotrueShow upload button
withAddPageButtonbooleanNofalseShow add blank page button
withSignYourselfButtonbooleanNotrueShow sign yourself button
withDocumentsListbooleanNotrueShow documents sidebar
withFieldsListbooleanNotrueShow fields sidebar
withFieldsDetectionbooleanNofalseShow AI field detection button
withTitleInputbooleanNotrueShow title input
withSendMyselfEmailbooleanNofalseShow email-to-self option
emailSubjectstringNoCustom email subject
emailBodystringNoCustom email body
backgroundColorstringNoBackground color (HEX code)
customCssstringNoCustom CSS rules injected into the builder iframe
inputModebooleanNofalseEnable data prefill mode instead of full editor
withSignatureIdbooleanNofalseShow signature ID alongside signature fields
extractFieldsbooleanNotrueAuto-extract fields from uploaded PDF forms
Returns: The created <docuseal-builder> DOM element.
var builderElement = DocuTrust.mountBuilder({
  element: '#builder-container',
  token: 'eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxNSIsImlzcyI6ImRvY3V0cnVzdCIsImF1ZCI6ImJ1aWxkZXIiLCJhaWQiOiIxIiwiaWF0IjoxNzQ0MTk1OTIwLCJleHAiOjE3NDQyMTAzMjAsIm9wdHMiOnsiYXV0b3NhdmUiOnRydWUsInByZXZpZXciOnRydWUsImZpZWxkcyI6W119fQ.abc123',
  language: 'en',
  autosave: true,
  preview: true,
  withTitle: true,
  withTitleInput: true,
  withSendButton: true,
  withRecipients: true,
  withUploadButton: true,
  withAddPageButton: false,
  withSignYourselfButton: true,
  withDocumentsList: true,
  withFieldsList: true,
  withFieldsDetection: true,
  withSendMyselfEmail: false,
  onlyDefinedFields: false,
  drawFieldType: 'text',
  fieldTypes: 'text,signature,initials,date,checkbox,select',
  customButtonTitle: 'Publish Template',
  customButtonUrl: 'https://your-app.com/templates/15/published',
  emailSubject: 'Please sign: {{template.name}}',
  emailBody: 'Hi, please review and sign the document: {{submitter.link}}',
  backgroundColor: '#f9fafb',
  customCss: 'body { font-family: "Inter", sans-serif; }',
  inputMode: false,
  withSignatureId: false,
  extractFields: true,
  roles: ['Sender', 'Recipient', 'Witness'],
  submitters: [
    { name: 'Recipient', email: 'jane@example.com' },
    { name: 'Witness', email: 'witness@example.com' }
  ],
  requiredFields: ['Signature', 'Sender Signature', 'Witness Signature'],
  fields: [
    { name: 'Full Name', type: 'text', role: 'Recipient', required: true },
    { name: 'Email', type: 'text', role: 'Recipient', required: true },
    { name: 'Signature', type: 'signature', role: 'Recipient', required: true },
    { name: 'Date', type: 'date', role: 'Recipient', required: true },
    { name: 'Sender Signature', type: 'signature', role: 'Sender', required: true },
    { name: 'Witness Signature', type: 'signature', role: 'Witness', required: true }
  ]
});

console.log('Builder mounted:', builderElement);

DocuTrust.form(options)

Alias for DocuTrust.mount(). Accepts the same parameters and returns the same result.
var formElement = DocuTrust.form({
  element: '#signing-container',
  submitterSlug: 'aB3kL9mNpQ',
  email: 'jane.doe@example.com',
  name: 'Jane Doe',
  role: 'Recipient',
  externalId: 'usr_9f84b2a1',
  logo: 'https://your-app.com/assets/logo.png',
  language: 'en',
  withTitle: true,
  withDownloadButton: true,
  withSendCopyButton: true,
  withDecline: true,
  withFieldNames: true,
  withFieldPlaceholder: 'Enter value here',
  withCompleteButton: true,
  onlyRequiredFields: false,
  allowToResubmit: false,
  allowTypedSignature: true,
  goToLast: true,
  expand: true,
  autoscroll: true,
  minimizeFirstStep: false,
  orderAsOnPage: false,
  sendCopyEmail: true,
  backgroundColor: '#ffffff',
  customCss: 'body { font-family: "Inter", sans-serif; }',
  completedMessageTitle: 'Thank you for signing!',
  completedMessageBody: 'Your signed document will be emailed to you shortly.',
  completedButtonTitle: 'Return to Dashboard',
  completedButtonUrl: 'https://your-app.com/dashboard',
  minimize: false,
  signature: 'Jane Doe',
  values: {
    'Full Name': 'Jane Doe',
    'Email': 'jane.doe@example.com',
    'Company': 'Acme Inc',
    'Title': 'VP of Operations',
    'Date': '2026-04-08'
  },
  metadata: {
    customer_id: 'cust_8472',
    deal_id: 'deal_291',
    source: 'sdk_integration'
  },
  i18n: {
    submit: 'Confirm & Sign',
    next: 'Continue'
  },
  completedRedirectUrl: 'https://your-app.com/signing-complete'
});

DocuTrust.builder(options)

Alias for DocuTrust.mountBuilder(). Accepts the same parameters and returns the same result.
var builderElement = DocuTrust.builder({
  element: '#builder-container',
  token: 'YOUR_JWT_TOKEN',
  language: 'en',
  autosave: true,
  preview: true,
  withTitle: true,
  withTitleInput: true,
  withSendButton: true,
  withRecipients: true,
  withUploadButton: true,
  withAddPageButton: false,
  withSignYourselfButton: true,
  withDocumentsList: true,
  withFieldsList: true,
  withFieldsDetection: false,
  withSendMyselfEmail: false,
  onlyDefinedFields: false,
  drawFieldType: 'text',
  fieldTypes: 'text,signature,date',
  customButtonTitle: 'Publish',
  customButtonUrl: 'https://your-app.com/templates/published',
  emailSubject: 'Please sign: {{template.name}}',
  emailBody: 'Please review and sign: {{submitter.link}}',
  backgroundColor: '#f9fafb',
  customCss: 'body { font-family: "Inter", sans-serif; }',
  inputMode: false,
  withSignatureId: false,
  extractFields: true,
  roles: ['Sender', 'Recipient'],
  submitters: [
    { name: 'Recipient', email: 'jane@example.com' }
  ],
  requiredFields: ['Signature'],
  fields: [
    { name: 'Full Name', type: 'text', role: 'Recipient', required: true },
    { name: 'Signature', type: 'signature', role: 'Recipient', required: true },
    { name: 'Date', type: 'date', role: 'Recipient', required: true },
    { name: 'Sender Signature', type: 'signature', role: 'Sender', required: true }
  ]
});

DocuTrust.on(event, callback)

Subscribe to an event. Returns the DocuTrust SDK instance for method chaining. Parameters:
PropertyTypeRequiredDescription
eventstringYesEvent name (see Events section)
callbackfunctionYesCallback function receiving the event detail
Returns: DocuTrust (for chaining)
DocuTrust
  .on('loaded', function (detail) {
    console.log('Form loaded for submitter:', detail.submitter_id);
  })
  .on('completed', function (detail) {
    console.log('Submission completed:', detail.submission_id);
  })
  .on('declined', function (detail) {
    console.log('Signer declined:', detail.reason);
  });

DocuTrust.off(event, callback)

Unsubscribe from an event. Returns the DocuTrust SDK instance for method chaining. Parameters:
PropertyTypeRequiredDescription
eventstringYesEvent name
callbackfunctionYesThe same function reference passed to on()
Returns: DocuTrust (for chaining)
function onCompleted(detail) {
  console.log('Submission completed:', detail.submission_id);
}

// Subscribe
DocuTrust.on('completed', onCompleted);

// Later, unsubscribe
DocuTrust.off('completed', onCompleted);

Events

Form events

These events fire when a signing form is mounted via DocuTrust.mount() or DocuTrust.form().

loaded

Fired when the form content has fully rendered and is interactive.
DocuTrust.on('loaded', function (detail) {
  console.log('Submitter ID:', detail.submitter_id);
  console.log('Submission ID:', detail.submission_id);
  console.log('Template:', detail.template_name);
  console.log('Role:', detail.role);
  console.log('Fields:', detail.fields.length);
});
Callback argument:
{
  "submitter_id": 142,
  "submission_id": 89,
  "template_id": 15,
  "template_name": "Employment Agreement",
  "role": "Recipient",
  "status": "opened",
  "fields": [
    {
      "name": "Full Name",
      "type": "text",
      "required": true,
      "value": "Jane Doe"
    },
    {
      "name": "Signature",
      "type": "signature",
      "required": true,
      "value": null
    },
    {
      "name": "Date",
      "type": "date",
      "required": true,
      "value": "2026-04-08"
    },
    {
      "name": "Contract Amount",
      "type": "text",
      "required": false,
      "value": "$150,000"
    }
  ]
}

completed

Fired when the signer successfully submits the form.
DocuTrust.on('completed', function (detail) {
  console.log('Submitter:', detail.submitter_id);
  console.log('Completed at:', detail.completed_at);
  console.log('Documents:', detail.documents);
  console.log('Values:', detail.values);
});
Callback argument:
{
  "submitter_id": 142,
  "submission_id": 89,
  "template_id": 15,
  "role": "Recipient",
  "email": "jane.doe@example.com",
  "name": "Jane Doe",
  "status": "completed",
  "completed_at": "2026-04-08T14:32:18.000Z",
  "audit_log_url": "https://your-app.com/submissions/89/audit_log",
  "documents": [
    {
      "name": "Employment Agreement - Signed",
      "url": "https://your-app.com/blobs/proxy/eyJfcm...",
      "content_type": "application/pdf",
      "size": 284716
    }
  ],
  "values": {
    "Full Name": "Jane Doe",
    "Email": "jane.doe@example.com",
    "Company": "Acme Inc",
    "Title": "VP of Operations",
    "Date": "2026-04-08",
    "Signature": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."
  },
  "metadata": {
    "customer_id": "cust_8472",
    "deal_id": "deal_291",
    "plan": "enterprise",
    "source": "sdk_integration"
  }
}

declined

Fired when the signer declines to sign the document.
DocuTrust.on('declined', function (detail) {
  console.log('Declined by:', detail.email);
  console.log('Reason:', detail.reason);
});
Callback argument:
{
  "submitter_id": 142,
  "submission_id": 89,
  "template_id": 15,
  "role": "Recipient",
  "email": "jane.doe@example.com",
  "name": "Jane Doe",
  "status": "declined",
  "declined_at": "2026-04-08T14:35:02.000Z",
  "reason": "Terms not acceptable"
}

field-value

Fired each time the signer fills in or changes a field value.
DocuTrust.on('field-value', function (detail) {
  console.log('Field changed:', detail.field_name, '=', detail.value);
  console.log('Progress:', detail.completed_fields + '/' + detail.total_fields);
});
Callback argument:
{
  "submitter_id": 142,
  "submission_id": 89,
  "field_name": "Full Name",
  "field_type": "text",
  "value": "Jane Doe",
  "page": 1,
  "completed_fields": 3,
  "total_fields": 7
}

Builder events

These events fire when a template builder is mounted via DocuTrust.mountBuilder() or DocuTrust.builder().

loaded

Fired when the builder UI has fully rendered.
DocuTrust.on('loaded', function (detail) {
  console.log('Builder loaded for template:', detail.template_id);
  console.log('Documents:', detail.documents.length);
  console.log('Fields:', detail.fields.length);
});
Callback argument:
{
  "template_id": 15,
  "template_name": "Employment Agreement",
  "account_id": 1,
  "submitters": [
    {
      "name": "Sender",
      "uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
    },
    {
      "name": "Recipient",
      "uuid": "b2c3d4e5-f6a7-8901-bcde-f12345678901"
    }
  ],
  "documents": [
    {
      "id": 42,
      "filename": "employment_agreement.pdf",
      "content_type": "application/pdf",
      "page_count": 4
    }
  ],
  "fields": [
    {
      "name": "Full Name",
      "type": "text",
      "required": true,
      "submitter_uuid": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
      "page": 1
    },
    {
      "name": "Signature",
      "type": "signature",
      "required": true,
      "submitter_uuid": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
      "page": 4
    }
  ]
}

template-saved

Fired when the template is saved.
DocuTrust.on('template-saved', function (detail) {
  console.log('Template saved:', detail.template_id);
  console.log('Updated at:', detail.updated_at);
  console.log('Fields:', detail.fields.length);
});
Callback argument:
{
  "template_id": 15,
  "template_name": "Employment Agreement",
  "updated_at": "2026-04-08T14:22:45.000Z",
  "submitters": [
    {
      "name": "Sender",
      "uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
    },
    {
      "name": "Recipient",
      "uuid": "b2c3d4e5-f6a7-8901-bcde-f12345678901"
    }
  ],
  "documents": [
    {
      "id": 42,
      "filename": "employment_agreement.pdf",
      "content_type": "application/pdf",
      "page_count": 4
    }
  ],
  "fields": [
    {
      "name": "Full Name",
      "type": "text",
      "required": true,
      "submitter_uuid": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
      "page": 1,
      "areas": [{"x": 0.15, "y": 0.32, "w": 0.35, "h": 0.03, "page": 1}]
    },
    {
      "name": "Signature",
      "type": "signature",
      "required": true,
      "submitter_uuid": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
      "page": 4,
      "areas": [{"x": 0.10, "y": 0.72, "w": 0.30, "h": 0.08, "page": 4}]
    }
  ]
}

template-data

Fired in response to a getTemplate() call or internal state changes.
DocuTrust.on('template-data', function (detail) {
  console.log('Template data received:', detail.template_id);
});
Callback argument: Same structure as template-saved.

send

Fired when the user clicks the “Send” button inside the builder.
DocuTrust.on('send', function (detail) {
  console.log('Send requested for template:', detail.template_id);
  console.log('Submitter roles:', detail.submitters.map(function (s) { return s.name; }));
  // Open your own send dialog
});
Callback argument:
{
  "template_id": 15,
  "template_name": "Employment Agreement",
  "submitters": [
    {
      "name": "Sender",
      "uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
    },
    {
      "name": "Recipient",
      "uuid": "b2c3d4e5-f6a7-8901-bcde-f12345678901"
    }
  ]
}

change

Fired when any change occurs in the builder — field added, moved, resized, deleted, or properties updated.
DocuTrust.on('change', function (detail) {
  console.log('Builder changed:', detail.change_type);
  console.log('Template:', detail.template_id);
  console.log('Fields:', detail.fields.length);
});
Callback argument:
{
  "template_id": 15,
  "template_name": "Employment Agreement",
  "change_type": "field_added",
  "submitters": [
    {
      "name": "Sender",
      "uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
    },
    {
      "name": "Recipient",
      "uuid": "b2c3d4e5-f6a7-8901-bcde-f12345678901"
    }
  ],
  "documents": [
    {
      "id": 42,
      "filename": "employment_agreement.pdf",
      "content_type": "application/pdf",
      "page_count": 4
    }
  ],
  "fields": [
    {
      "name": "Full Name",
      "type": "text",
      "required": true,
      "submitter_uuid": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
      "page": 1,
      "areas": [{"x": 0.15, "y": 0.32, "w": 0.35, "h": 0.03, "page": 1}]
    },
    {
      "name": "Signature",
      "type": "signature",
      "required": true,
      "submitter_uuid": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
      "page": 4,
      "areas": [{"x": 0.10, "y": 0.72, "w": 0.30, "h": 0.08, "page": 4}]
    }
  ]
}

Complete integration example

This example shows a full SPA integration that loads the SDK dynamically, mounts a signing form, handles all events, and provides a fallback builder flow.
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>DocuTrust Integration</title>
  <style>
    body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; margin: 0; padding: 24px; }
    .embed-container { max-width: 960px; margin: 0 auto; min-height: 600px; border: 1px solid #e5e7eb; border-radius: 8px; }
    #status { padding: 12px; margin-bottom: 16px; border-radius: 6px; font-size: 14px; }
    .status-loading { background: #fef3c7; color: #92400e; }
    .status-ready { background: #d1fae5; color: #065f46; }
    .status-completed { background: #dbeafe; color: #1e40af; }
    .status-declined { background: #fee2e2; color: #991b1b; }
    .controls { margin-bottom: 16px; }
    .controls button { padding: 8px 16px; margin-right: 8px; border: 1px solid #d1d5db; border-radius: 6px; background: white; cursor: pointer; }
    .controls button:hover { background: #f9fafb; }
  </style>
</head>
<body>

<div id="status" class="status-loading">Loading DocuTrust SDK...</div>

<div class="controls">
  <button id="btn-mount-form">Mount Signing Form</button>
  <button id="btn-mount-builder">Mount Builder</button>
</div>

<div id="signing-container" class="embed-container"></div>
<div id="builder-container" class="embed-container" style="display: none;"></div>

<script>
  var DOCUTRUST_HOST = 'https://your-app.com';
  var SUBMITTER_SLUG = 'aB3kL9mNpQ';
  var BUILDER_TOKEN = 'eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxNSJ9.abc123';

  function updateStatus(message, className) {
    var el = document.getElementById('status');
    el.textContent = message;
    el.className = className;
  }

  // Load SDK dynamically
  var script = document.createElement('script');
  script.src = DOCUTRUST_HOST + '/js/docutrust-embed.js';
  script.onload = function () {
    DocuTrust.configure({ host: DOCUTRUST_HOST });
    updateStatus('SDK loaded. Click a button to mount.', 'status-ready');

    // Register global event handlers with chaining
    DocuTrust
      .on('loaded', function (detail) {
        updateStatus('Form loaded for submitter ' + detail.submitter_id, 'status-ready');
      })
      .on('completed', function (detail) {
        updateStatus(
          'Submission ' + detail.submission_id + ' completed at ' + detail.completed_at,
          'status-completed'
        );
        console.log('Completed submission:', detail);
        console.log('Documents:', detail.documents);
        console.log('Values:', detail.values);
        console.log('Metadata:', detail.metadata);
        console.log('Audit log:', detail.audit_log_url);
      })
      .on('declined', function (detail) {
        updateStatus('Signer declined: ' + detail.reason, 'status-declined');
        console.log('Declined:', detail);
      })
      .on('field-value', function (detail) {
        console.log(
          'Field "' + detail.field_name + '" (' + detail.field_type + ') = ' + detail.value +
          ' [' + detail.completed_fields + '/' + detail.total_fields + ']'
        );
      })
      .on('template-saved', function (detail) {
        updateStatus('Template ' + detail.template_id + ' saved at ' + detail.updated_at, 'status-ready');
        console.log('Saved template:', detail);
      })
      .on('send', function (detail) {
        console.log('Send clicked for template:', detail.template_id);
        console.log('Roles:', detail.submitters.map(function (s) { return s.name; }));
      });
  };
  document.head.appendChild(script);

  // Mount signing form on button click
  document.getElementById('btn-mount-form').addEventListener('click', function () {
    // Clear previous content safely
    var signingContainer = document.getElementById('signing-container');
    while (signingContainer.firstChild) {
      signingContainer.removeChild(signingContainer.firstChild);
    }
    signingContainer.style.display = 'block';
    document.getElementById('builder-container').style.display = 'none';

    DocuTrust.mount({
      element: '#signing-container',
      submitterSlug: SUBMITTER_SLUG,
      email: 'jane.doe@example.com',
      name: 'Jane Doe',
      role: 'Recipient',
      externalId: 'usr_9f84b2a1',
      logo: 'https://your-app.com/assets/logo.png',
      language: 'en',
      withTitle: true,
      withDownloadButton: true,
      withSendCopyButton: true,
      withDecline: true,
      withFieldNames: true,
      withFieldPlaceholder: 'Enter value here',
      withCompleteButton: true,
      onlyRequiredFields: false,
      allowToResubmit: false,
      allowTypedSignature: true,
      goToLast: true,
      expand: true,
      autoscroll: true,
      minimizeFirstStep: true,
      orderAsOnPage: false,
      sendCopyEmail: true,
      backgroundColor: '#ffffff',
      values: {
        'Full Name': 'Jane Doe',
        'Email': 'jane.doe@example.com',
        'Company': 'Acme Inc',
        'Title': 'VP of Operations',
        'Date': '2026-04-08'
      },
      metadata: {
        customer_id: 'cust_8472',
        deal_id: 'deal_291',
        plan: 'enterprise',
        source: 'sdk_integration'
      },
      i18n: {
        submit: 'Confirm & Sign',
        next: 'Continue'
      },
      completedRedirectUrl: 'https://your-app.com/signing-complete'
    });

    updateStatus('Mounting signing form...', 'status-loading');
  });

  // Mount builder on button click
  document.getElementById('btn-mount-builder').addEventListener('click', function () {
    // Clear previous content safely
    var builderContainer = document.getElementById('builder-container');
    while (builderContainer.firstChild) {
      builderContainer.removeChild(builderContainer.firstChild);
    }
    builderContainer.style.display = 'block';
    document.getElementById('signing-container').style.display = 'none';

    DocuTrust.mountBuilder({
      element: '#builder-container',
      token: BUILDER_TOKEN,
      language: 'en',
      autosave: true,
      preview: true,
      withTitle: true,
      withTitleInput: true,
      withSendButton: true,
      withRecipients: true,
      withUploadButton: true,
      withAddPageButton: false,
      withSignYourselfButton: true,
      withDocumentsList: true,
      withFieldsList: true,
      withFieldsDetection: true,
      withSendMyselfEmail: false,
      drawFieldType: 'text',
      fieldTypes: 'text,signature,date,checkbox',
      customButtonTitle: 'Publish Template',
      emailSubject: 'Please sign: {{template.name}}',
      emailBody: 'Hi, please review and sign: {{submitter.link}}',
      backgroundColor: '#f9fafb',
      roles: ['Sender', 'Recipient'],
      submitters: [
        { name: 'Recipient', email: 'jane@example.com' }
      ],
      requiredFields: ['Signature', 'Sender Signature'],
      fields: [
        { name: 'Full Name', type: 'text', role: 'Recipient', required: true },
        { name: 'Email', type: 'text', role: 'Recipient', required: true },
        { name: 'Signature', type: 'signature', role: 'Recipient', required: true },
        { name: 'Date', type: 'date', role: 'Recipient', required: true },
        { name: 'Sender Signature', type: 'signature', role: 'Sender', required: true }
      ]
    });

    updateStatus('Mounting template builder...', 'status-loading');
  });
</script>

</body>
</html>

Chaining pattern

The on() and off() methods return the SDK instance, enabling a fluent chaining pattern:
DocuTrust
  .configure({ host: 'https://your-app.com' })

DocuTrust
  .on('loaded', function (detail) {
    console.log('Ready:', detail.submitter_id);
  })
  .on('completed', function (detail) {
    fetch('/api/internal/signing-complete', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        submission_id: detail.submission_id,
        submitter_id: detail.submitter_id,
        completed_at: detail.completed_at,
        document_urls: detail.documents.map(function (d) { return d.url; })
      })
    });
  })
  .on('declined', function (detail) {
    fetch('/api/internal/signing-declined', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        submission_id: detail.submission_id,
        submitter_id: detail.submitter_id,
        reason: detail.reason,
        declined_at: detail.declined_at
      })
    });
  })
  .on('field-value', function (detail) {
    console.log(detail.field_name, '=', detail.value);
  })
  .on('change', function (detail) {
    console.log('Builder changed:', detail.change_type, detail.template_id);
  });
When using both form and builder events with DocuTrust.on(), the loaded event fires for both. Differentiate by checking for detail.submitter_id (form) vs. detail.template_id without detail.submitter_id (builder).