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.

Frequently Asked Questions

How do I test without sending real emails?

DocuTrust supports a test mode that suppresses email delivery while still creating submissions and signing URLs. To use test mode:
  1. When creating a submission via the API, set the send_email option to false:
{
  "template_id": 57,
  "send_email": false,
  "submitters": [
    {
      "role": "First Party",
      "email": "test@example.com",
      "name": "Test Signer",
      "external_id": "test-001",
      "phone": "+15551234567",
      "values": {},
      "metadata": {},
      "send_email": false,
      "send_sms": false
    }
  ]
}
  1. Retrieve the signing URL from the submission response and open it directly in your browser:
{
  "id": 1042,
  "slug": "abc123def456",
  "status": "pending",
  "template_id": 57,
  "created_at": "2026-04-08T10:00:00Z",
  "updated_at": "2026-04-08T10:00:00Z",
  "submitters": [
    {
      "id": 2089,
      "slug": "xyz789ghi012",
      "email": "test@example.com",
      "name": "Test Signer",
      "role": "First Party",
      "status": "waiting",
      "signing_url": "https://your-app.com/s/xyz789ghi012",
      "external_id": "test-001",
      "phone": "+15551234567",
      "completed_at": null,
      "opened_at": null,
      "sent_at": null,
      "created_at": "2026-04-08T10:00:00Z",
      "updated_at": "2026-04-08T10:00:00Z",
      "metadata": {},
      "values": {}
    }
  ]
}
This creates a fully functional submission without sending any emails, allowing you to test the complete signing flow.

What file formats are supported?

DocuTrust supports the following formats for template documents:
FormatExtensionNotes
PDF.pdfThe primary format. Supports multi-page documents. Fields are placed on the PDF pages.
Microsoft Word.docxConverted to PDF on upload. The original DOCX is stored alongside the converted PDF.
HTML.htmlRendered to PDF. Useful for dynamically generated documents and templates with complex layouts.
All signed documents are output as PDF, regardless of the original upload format.

Can multiple people sign one document?

Yes. DocuTrust supports both sequential and parallel multi-signer workflows.

Sequential Signing

Submitters sign in a defined order. Each submitter receives their signing invitation only after the previous submitter completes their fields.
{
  "template_id": 57,
  "submitters_order": "sequential",
  "submitters": [
    {
      "role": "Employee",
      "email": "employee@company.com",
      "name": "Jane Smith",
      "external_id": "emp-442",
      "phone": "+15551234567",
      "values": {},
      "metadata": {},
      "send_email": true,
      "send_sms": false
    },
    {
      "role": "Manager",
      "email": "manager@company.com",
      "name": "Bob Johnson",
      "external_id": "mgr-118",
      "phone": "+15559876543",
      "values": {},
      "metadata": {},
      "send_email": true,
      "send_sms": false
    }
  ]
}
In this example, “Manager” only receives their signing link after “Employee” completes their fields.

Parallel Signing

All submitters receive their signing invitations simultaneously and can sign in any order.
{
  "template_id": 57,
  "submitters_order": "parallel",
  "submitters": [
    {
      "role": "Party A",
      "email": "alice@company-a.com",
      "name": "Alice Chen",
      "external_id": "party-a-001",
      "phone": "+15551112222",
      "values": {},
      "metadata": {},
      "send_email": true,
      "send_sms": false
    },
    {
      "role": "Party B",
      "email": "bob@company-b.com",
      "name": "Bob Williams",
      "external_id": "party-b-001",
      "phone": "+15553334444",
      "values": {},
      "metadata": {},
      "send_email": true,
      "send_sms": false
    }
  ]
}

How do I pre-fill form fields?

Use the values object when creating a submission to pre-fill fields for a submitter. The keys are the field names defined in your template schema:
{
  "template_id": 57,
  "submitters": [
    {
      "role": "Employee",
      "email": "jane@company.com",
      "name": "Jane Smith",
      "external_id": "emp-442",
      "phone": "+15551234567",
      "send_email": true,
      "send_sms": false,
      "metadata": {},
      "values": {
        "Full Name": "Jane Smith",
        "Job Title": "Senior Engineer",
        "Start Date": "2026-05-01",
        "Department": "Engineering",
        "Employee ID": "EMP-442",
        "Annual Salary": "145000"
      }
    }
  ]
}
Pre-filled fields appear already completed when the submitter opens the signing page. Depending on the field configuration, the signer may or may not be able to edit pre-filled values.

Is my data encrypted?

Yes. DocuTrust encrypts data at multiple layers: At rest:
  • All documents (PDFs, DOCX, HTML) are encrypted with AES-256-GCM before being written to storage. Each file has a unique initialization vector.
  • Submitter PII (email, name, phone, IP address, user agent, submitted values, metadata) is encrypted in the database using Active Record Encryption.
  • Email addresses use deterministic encryption (enabling lookups), while all other fields use non-deterministic encryption (maximum privacy).
In transit:
  • All connections use TLS 1.2+. Older TLS versions and unencrypted HTTP are rejected.
  • Webhook deliveries to your endpoints are sent over HTTPS.
Key management:
  • Three separate encryption keys for documents, database fields, and configuration.
  • Keys are rotatable with zero downtime via the KeyRotationService.
  • HKDF derivation fallback from SECRET_KEY_BASE if explicit keys are not set.
See the Encryption page for full technical details.

Do you support webhooks?

Yes. DocuTrust supports 14 webhook event types with HMAC-SHA256 signed payloads for verification.

Supported Events

EventTrigger
submission.createdA new submission is created.
submission.sentA submission is sent to submitters.
submission.completedAll submitters have completed a submission.
submission.expiredA submission has passed its expiration date.
submission.archivedA submission is archived.
submitter.sentAn email invitation is sent to a submitter.
submitter.openedA submitter opens the signing link.
submitter.completedA submitter completes their fields.
submitter.declinedA submitter declines to sign.
template.createdA new template is created.
template.updatedA template is modified.
document.generatedA signed PDF document is generated.
form.startedA submitter begins filling out a form.
form.completedA submitter finishes filling out a form.

Payload Verification

Every webhook payload includes an X-DocuTrust-Signature header containing an HMAC-SHA256 signature computed from the payload body and your webhook secret:
X-DocuTrust-Signature: sha256=a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2
Verify this signature on your server before processing the webhook to ensure the payload was sent by DocuTrust and has not been tampered with. Configure webhooks in Settings > Webhooks or via the API. See the Webhooks guide for implementation details.

Can I embed signing in my app?

Yes. DocuTrust offers three approaches for embedding the signing experience:

1. Iframe Embedding

Embed the signing page directly in your application using an iframe:
<iframe
  src="https://your-app.com/s/SUBMITTER_SLUG"
  width="100%"
  height="800px"
  frameborder="0"
  allow="camera"
></iframe>
Listen for completion events via postMessage:
window.addEventListener("message", (event) => {
  if (event.data.type === "submitter.completed") {
    console.log("Signing completed:", event.data.submitter_id);
  }
});

2. Redirect Flow

Redirect the signer to the DocuTrust signing page, then back to your application on completion:
https://your-app.com/s/SUBMITTER_SLUG?redirect_url=https://yoursite.com/signing-complete
After signing, the submitter is redirected to your redirect_url with query parameters indicating the result.

3. API-Driven

Create submissions and retrieve signing URLs entirely via the API, giving you full control over the user experience:
  1. Create a submission via POST /api/submissions.
  2. Extract the signing_url from each submitter in the response.
  3. Present the URL to the signer in your own UI (link, button, or iframe).
  4. Receive a webhook when the submitter completes signing.
See the Embedding guide for detailed implementation instructions.

What happens when a submission expires?

When a submission passes its expire_at timestamp:
  1. The submission status changes to expired.
  2. All submitters who have not yet completed their fields have their status changed to expired.
  3. Submitters who have already completed their fields retain their completed status.
  4. Expired submitters are notified via email that the signing request has expired.
  5. The signing URL returns an expiration notice instead of the signing form.
  6. A submission.expired webhook event is fired.
To set an expiration date, include expire_at when creating the submission:
{
  "template_id": 57,
  "expire_at": "2026-05-01T23:59:59Z",
  "submitters": [
    {
      "role": "First Party",
      "email": "signer@example.com",
      "name": "Jane Smith",
      "external_id": "sig-001",
      "phone": "+15551234567",
      "values": {},
      "metadata": {},
      "send_email": true,
      "send_sms": false
    }
  ]
}
Expired submissions can be archived but not reactivated. To collect signatures after expiration, create a new submission from the same template.