> ## 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

> Programmatically mount signing forms and template builders, handle events, and control the DocuTrust embed lifecycle using the JavaScript SDK.

# 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.

```html theme={null}
<script src="https://your-app.com/js/docutrust-embed.js"></script>
```

For single-page applications, you can load the script dynamically:

```javascript theme={null}
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:**

| Property | Type   | Required | Description                                                         |
| -------- | ------ | -------- | ------------------------------------------------------------------- |
| `host`   | string | Yes      | Base URL of your DocuTrust instance, e.g., `"https://your-app.com"` |

```javascript theme={null}
DocuTrust.configure({
  host: 'https://your-app.com'
});
```

### DocuTrust.mount(options)

Mount a signing form into a container element. Returns the created DOM element.

**Parameters:**

| Property                | Type                  | Required | Default | Description                                        |
| ----------------------- | --------------------- | -------- | ------- | -------------------------------------------------- |
| `element`               | string or HTMLElement | Yes      | --      | CSS selector or DOM element to mount into          |
| `submitterSlug`         | string                | Yes      | --      | Submitter signing slug (the `SLUG` from `/s/SLUG`) |
| `withTitle`             | boolean               | No       | `true`  | Show the template title                            |
| `withDownloadButton`    | boolean               | No       | `true`  | Show the download button after completion          |
| `withSendCopyButton`    | boolean               | No       | `true`  | Show the "Send a copy" button                      |
| `allowToResubmit`       | boolean               | No       | `false` | Allow the signer to resubmit                       |
| `language`              | string                | No       | --      | UI language code (e.g., `"en"`, `"es"`, `"fr"`)    |
| `email`                 | string                | No       | --      | Pre-fill signer email                              |
| `name`                  | string                | No       | --      | Pre-fill signer name                               |
| `role`                  | string                | No       | --      | Target a specific submitter role                   |
| `preview`               | boolean               | No       | `false` | Enable read-only preview mode                      |
| `goToLast`              | boolean               | No       | `false` | Jump to last incomplete field                      |
| `expand`                | boolean               | No       | `false` | Expand form to full content height                 |
| `autoscroll`            | boolean               | No       | `true`  | Auto-scroll to next field                          |
| `skipFields`            | string                | No       | --      | Comma-separated field names to skip                |
| `readonlyFields`        | string                | No       | --      | Comma-separated read-only field names              |
| `values`                | object                | No       | --      | Pre-fill field values as key-value pairs           |
| `metadata`              | object                | No       | --      | Custom metadata object                             |
| `completedRedirectUrl`  | string                | No       | --      | Redirect URL after completion                      |
| `externalId`            | string                | No       | --      | Link signer to your system ID                      |
| `token`                 | string                | No       | --      | JWT token for authentication                       |
| `logo`                  | string                | No       | --      | Custom logo URL                                    |
| `i18n`                  | object                | No       | --      | Custom i18n key overrides                          |
| `withDecline`           | boolean               | No       | `false` | Show decline button                                |
| `withFieldNames`        | boolean               | No       | `true`  | Show field labels                                  |
| `withFieldPlaceholder`  | string                | No       | --      | Placeholder text for fields                        |
| `withCompleteButton`    | boolean               | No       | `true`  | Show complete button                               |
| `onlyRequiredFields`    | boolean               | No       | `false` | Show only required fields                          |
| `allowTypedSignature`   | boolean               | No       | `true`  | Allow typed signatures                             |
| `signature`             | string                | No       | --      | Pre-fill signature (base64/URL/text)               |
| `sendCopyEmail`         | boolean               | No       | `true`  | Allow send-copy email                              |
| `orderAsOnPage`         | boolean               | No       | `false` | Order fields by page position                      |
| `backgroundColor`       | string                | No       | --      | Background color (HEX code)                        |
| `minimizeFirstStep`     | boolean               | No       | `false` | Collapse first step into compact bar               |
| `customCss`             | string                | No       | --      | Custom CSS rules injected into the form iframe     |
| `completedMessageTitle` | string                | No       | --      | Custom completion screen title                     |
| `completedMessageBody`  | string                | No       | --      | Custom completion screen body text                 |
| `completedButtonTitle`  | string                | No       | --      | Custom completion button text                      |
| `completedButtonUrl`    | string                | No       | --      | Custom completion button URL                       |
| `minimize`              | boolean               | No       | `false` | Always minimize (collapse) field panels            |

**Returns:** The created `<docuseal-form>` DOM element.

```javascript theme={null}
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:**

| Property                 | Type                  | Required | Default | Description                                       |
| ------------------------ | --------------------- | -------- | ------- | ------------------------------------------------- |
| `element`                | string or HTMLElement | Yes      | --      | CSS selector or DOM element to mount into         |
| `templateId`             | number or string      | No       | --      | Template ID (session auth only)                   |
| `token`                  | string                | No       | --      | JWT token from `POST /api/embed/token`            |
| `language`               | string                | No       | --      | UI language code                                  |
| `autosave`               | boolean               | No       | `true`  | Enable auto-save                                  |
| `preview`                | boolean               | No       | `true`  | Show document preview panel                       |
| `withTitle`              | boolean               | No       | `true`  | Show editable template title                      |
| `withSendButton`         | boolean               | No       | `true`  | Show the "Send" button                            |
| `withRecipients`         | boolean               | No       | `true`  | Show recipients section                           |
| `onlyDefinedFields`      | boolean               | No       | `false` | Only show pre-defined field types                 |
| `fields`                 | array                 | No       | --      | Pre-defined field definitions                     |
| `roles`                  | array                 | No       | --      | Pre-defined submitter role names                  |
| `host`                   | string                | No       | --      | Override the configured host URL                  |
| `submitters`             | array                 | No       | --      | Default submitters with name and email            |
| `requiredFields`         | array                 | No       | --      | Field names required before saving                |
| `fieldTypes`             | string                | No       | --      | Comma-separated allowed field types               |
| `drawFieldType`          | string                | No       | --      | Default field type when drawing                   |
| `customButtonTitle`      | string                | No       | --      | Custom primary button text                        |
| `customButtonUrl`        | string                | No       | --      | URL for custom button navigation                  |
| `withUploadButton`       | boolean               | No       | `true`  | Show upload button                                |
| `withAddPageButton`      | boolean               | No       | `false` | Show add blank page button                        |
| `withSignYourselfButton` | boolean               | No       | `true`  | Show sign yourself button                         |
| `withDocumentsList`      | boolean               | No       | `true`  | Show documents sidebar                            |
| `withFieldsList`         | boolean               | No       | `true`  | Show fields sidebar                               |
| `withFieldsDetection`    | boolean               | No       | `false` | Show AI field detection button                    |
| `withTitleInput`         | boolean               | No       | `true`  | Show title input                                  |
| `withSendMyselfEmail`    | boolean               | No       | `false` | Show email-to-self option                         |
| `emailSubject`           | string                | No       | --      | Custom email subject                              |
| `emailBody`              | string                | No       | --      | Custom email body                                 |
| `backgroundColor`        | string                | No       | --      | Background color (HEX code)                       |
| `customCss`              | string                | No       | --      | Custom CSS rules injected into the builder iframe |
| `inputMode`              | boolean               | No       | `false` | Enable data prefill mode instead of full editor   |
| `withSignatureId`        | boolean               | No       | `false` | Show signature ID alongside signature fields      |
| `extractFields`          | boolean               | No       | `true`  | Auto-extract fields from uploaded PDF forms       |

**Returns:** The created `<docuseal-builder>` DOM element.

```javascript theme={null}
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.

```javascript theme={null}
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.

```javascript theme={null}
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:**

| Property   | Type     | Required | Description                                  |
| ---------- | -------- | -------- | -------------------------------------------- |
| `event`    | string   | Yes      | Event name (see Events section)              |
| `callback` | function | Yes      | Callback function receiving the event detail |

**Returns:** `DocuTrust` (for chaining)

```javascript theme={null}
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:**

| Property   | Type     | Required | Description                                  |
| ---------- | -------- | -------- | -------------------------------------------- |
| `event`    | string   | Yes      | Event name                                   |
| `callback` | function | Yes      | The same function reference passed to `on()` |

**Returns:** `DocuTrust` (for chaining)

```javascript theme={null}
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.

```javascript theme={null}
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:**

```json theme={null}
{
  "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.

```javascript theme={null}
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:**

```json theme={null}
{
  "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.

```javascript theme={null}
DocuTrust.on('declined', function (detail) {
  console.log('Declined by:', detail.email);
  console.log('Reason:', detail.reason);
});
```

**Callback argument:**

```json theme={null}
{
  "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.

```javascript theme={null}
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:**

```json theme={null}
{
  "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.

```javascript theme={null}
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:**

```json theme={null}
{
  "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.

```javascript theme={null}
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:**

```json theme={null}
{
  "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.

```javascript theme={null}
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.

```javascript theme={null}
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:**

```json theme={null}
{
  "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.

```javascript theme={null}
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:**

```json theme={null}
{
  "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.

```html theme={null}
<!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:

```javascript theme={null}
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);
  });
```

<Warning>
  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).
</Warning>
