A submission is a single instance of a template sent out for signing. When you create a submission, you assign real people (with names and emails) to each submitter role defined in the template. DocuTrust handles sending invitation emails, tracking progress, and assembling the final signed document.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.
Submission object
The standard submission object returned by list and create endpoints:| Field | Type | Description |
|---|---|---|
id | integer | Unique submission identifier. |
slug | string | URL-safe unique identifier. |
source | string | How the submission was created: api, web, embed, bulk, or draft. |
status | string | Current status: draft, pending, completed, declined, expired, or archived. |
template_id | string | ID of the template this submission was created from. |
submitter_count | integer | Number of submitter roles in this submission. |
created_at | string | ISO 8601 creation timestamp. |
updated_at | string | ISO 8601 last-modified timestamp. |
completed_at | string or null | ISO 8601 timestamp when all submitters completed, or null. |
expire_at | string or null | ISO 8601 expiration timestamp, or null if no expiration set. |
archived_at | string or null | ISO 8601 timestamp when the submission was archived, or null. |
Full submission object
When retrieving a single submission by ID, the response includes additional nested data:Status lifecycle
Submissions move through these statuses:| Status | Enum | Description |
|---|---|---|
draft | 0 | The submission has been created but not yet sent to submitters. No invitation emails are dispatched. |
pending | 1 | At least one submitter has not yet completed their form. This is the status after sending. |
completed | 2 | All submitters have completed their forms. The signed document is ready for download. |
declined | 3 | A submitter declined to sign the document, causing the submission to terminate. |
expired | 4 | The submission passed its expire_at timestamp without all parties completing. |
archived | — | The submission was manually archived via the API or dashboard. |
A submission moves to
completed only when every submitter’s status is completed. If even one submitter is still waiting or sent, the submission remains pending. A submission moves to declined when any submitter declines.Creating submissions
Basic creation
Send a template for signing by creating a submission with submitter details mapped to the template’s roles.Request parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
template_id | string | Yes | The template to create a submission from. |
send_email | boolean | No | Whether to send invitation emails to submitters. Defaults to true. |
submitters_order | string | No | "sequential" (submitters sign in order) or "parallel" (all sign simultaneously). Defaults to "sequential". |
quick_sign_mode | string | No | Controls quick-sign behavior for the submission. Defaults to "confirmation_modal" when omitted. Set "normal" to force legacy behavior. |
prefill_behavior | object | No | Submission-level prefill behavior. Defaults to { "skip_if_prefilled": true, "editable_if_prefilled": false } when omitted. |
expire_at | string | No | ISO 8601 timestamp when the submission should expire. |
metadata | object | No | Custom key-value pairs attached to the submission for your application’s use. |
preferences | object | No | Submission-level preferences (for example message overrides, redirect URLs, reminder templates). |
submitters | array | Yes | Array of submitter objects (see below). |
Submitter parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
role | string | Yes | Must match a submitter role name from the template. |
email | string | Yes | Submitter’s email address. |
name | string | No | Submitter’s full name. |
phone | string | No | Phone number in E.164 format (e.g., +15551234567). Required if the template has phone_verification fields. |
external_id | string | No | Your custom identifier for mapping to external systems. |
metadata | object | No | Custom key-value pairs attached to this specific submitter. |
values | object | No | Pre-filled field values keyed by field key. See Pre-filling field values. |
preferences | object | No | Submitter-level preferences. See below. |
completed | boolean | No | When true, the submitter is immediately marked as completed without going through the signing flow. See Auto-sign. |
send_sms | boolean | No | When true, sends an SMS notification to the submitter’s phone number instead of an email. Requires phone to be set in E.164 format. |
fields | array | No | Per-submitter field overrides. Each entry sets a default_value for a specific field by name. See Per-submitter field overrides. |
Submitter preferences
| Preference | Type | Default | Description |
|---|---|---|---|
send_email | boolean | true | Whether to send an invitation email to this specific submitter. |
Auto-sign
When a submitter’s role is pre-approved (e.g., the sender or an internal representative), you can skip their signing flow entirely by settingcompleted: true. The submitter is immediately recorded as completed, and the submission moves forward to the next party (or finishes if this was the last submitter).
Pre-filling field values
Pre-fill fields by passing avalues object keyed by field key/name or field UUID. This is useful for populating known information like names, addresses, or dates so signers do not have to type them manually.
Repeated key behavior (fan-out)
If a single key/name matches multiple fields in the template schema:- Scalar value: value is applied to all matching field UUIDs.
- Array value with exact length: values are distributed positionally in document order.
- Array length mismatch: request fails with
422 invalid_field_values. - Mixed UUID + key payloads: UUID-keyed values win for explicitly targeted fields; key-based values fill remaining matches.
X-Submission-Warning: name_key_ambiguous:<key>
Per-submitter field overrides
Use thefields array on a submitter to set default values for specific fields by name. This is different from the values object (which uses field keys): fields targets fields by their human-readable name and lets you set a default_value that the signer sees when they open the form.
fields sets the default value shown in the form (the signer can change it unless the field is readonly in the template schema). values pre-fills the field and records it as the submitted value. You can use both together — values takes precedence for any overlapping fields.Value types by field
| Field type | Value format | Example |
|---|---|---|
text | Any scalar, coerced to string (null/undefined -> "") | "Jane Smith" or 150 |
number | Number, or numeric string (non-numeric strings rejected) | "42500" or 42500 |
date | ISO date (YYYY-MM-DD) or ISO timestamp (coerced to date) | "2026-04-08" or "2026-04-08T17:26:13Z" |
checkbox | Boolean, or boolean-like strings (true/false/1/0/y/n/yes/no) | true or "yes" |
select | String (must match an option) | "Credit Card" |
radio | String (must match an option) | "Option A" |
cells | String | "123456789" |
signature | String data URL, or { "image": "data:image/png;base64,..." } | "data:image/png;base64,..." |
initials | String data URL, or { "image": "data:image/png;base64,..." } | "data:image/png;base64,..." |
file | Not pre-fillable | Files must be uploaded by the signer. |
Quick sign modes
Control the signing experience for the submission using top-levelquick_sign_mode.
When omitted, the API defaults to:
quick_sign_mode: "confirmation_modal"prefill_behavior: { "skip_if_prefilled": true, "editable_if_prefilled": false }
| Mode | Description |
|---|---|
normal | Standard signing flow. The signer scrolls through the document and fills each field individually. |
review_and_sign | The signer reviews the entire document first, then completes all fields in a guided step-by-step flow at the end. |
confirmation_modal | A bottom-sheet carousel walks the signer through signature and initials fields only. Text fields are pre-filled and shown as read-only overlays on the document. Signatures are grouped by type — the signer signs once and it applies to all signature fields, same for initials. Typically a 2-step flow. The start screen is auto-skipped. Falls back to normal if required text fields are empty. |
auto_scroll_signature | The document auto-scrolls to each signature field in sequence. Optimized for documents with many signature lines. |
Draft submissions
Create a draft submission that is not sent to submitters until you explicitly send it. This is useful for building submissions incrementally or requiring approval before sending.Create a draft
Update a draft
Modify the draft before sending:Send a draft
When the draft is ready, send it to all submitters:Bulk creation
Send the same template to many recipients at once. Each entry in the array creates an independent submission.Preview before sending
Use the bulk preview endpoint to validate your data without actually creating submissions:Email-based bulk creation
Create one submission per email address from a comma-separated string. This is a convenience endpoint that avoids the overhead of building the fullsubmissions array when you only need simple single-role submissions.
POST /api/submissions/emails
Request parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
template_id | string | Yes | The template to create submissions from. |
emails | string | Yes | Comma-separated list of email addresses. One submission is created per email. |
send_email | boolean | No | Whether to send invitation emails. Defaults to true. |
send_sms | boolean | No | Whether to send SMS notifications instead of email. Requires phone-capable template. Defaults to false. |
quick_sign_mode | string | No | Quick-sign mode for each created submission. Defaults to "confirmation_modal" when omitted. |
prefill_behavior | object | No | Prefill behavior for each created submission. Defaults to { "skip_if_prefilled": true, "editable_if_prefilled": false } when omitted. |
name | string | No | Default display name assigned to each submitter. |
role | string | No | The submitter role to assign. Must match a role in the template. Defaults to the first role. |
message | object | No | Custom email message with subject and body. Supports tokens: {{submitter.name}}, {{submitter.email}}, {{template.name}}, {{account.name}}. |
expire_at | string | No | ISO 8601 expiration timestamp applied to all created submissions. |
metadata | object | No | Custom key-value pairs attached to each created submission. |
embed_src URL for embedding the signing form:
Listing submissions
Filter parameters
| Parameter | Type | Description |
|---|---|---|
status | string | Filter by status: draft, pending, completed, declined, expired, archived. |
template_id | string | Filter by template. |
after | integer | Cursor for pagination (return items after this ID). |
before | integer | Cursor for pagination (return items before this ID). |
limit | integer | Items per page (1-100, default 10). |
Retrieving a submission
Sending reminders
Send reminder emails (or SMS) to all submitters who have not yet completed a pending submission.POST /api/submissions/:id/send_reminder
Reminders are only sent to submitters whose status is
waiting, sent, or opened. Submitters who have already completed, declined, or expired are skipped. The reminded count reflects how many submitters actually received a reminder. If the submission is already completed, expired, or archived, the endpoint returns a 422 error.Customizable reminder emails
Customize the subject and body of reminder emails by includingreminder_subject and reminder_body in the submission preferences when creating or updating a submission.
| Token | Description |
|---|---|
{{submitter.name}} | The submitter’s display name. |
{{submitter.email}} | The submitter’s email address. |
{{submitter.link}} | The unique signing URL for this submitter. |
{{template.name}} | The template name. |
{{submission.expire_at}} | The submission expiration date (formatted). |
{{account.name}} | Your account/company name. |
Subscription payments
Collect subscription payments from signers as part of the signing workflow. UsePOST /api/payments/subscribe to create a subscription payment linked to a submission.
| Parameter | Type | Required | Description |
|---|---|---|---|
submission_id | integer | Yes | The submission this payment is linked to. |
submitter_id | integer | Yes | The submitter making the payment. |
plan_id | string | Yes | Your internal plan identifier. |
price_cents | integer | Yes | Price in cents (e.g., 4999 for $49.99). |
currency | string | Yes | ISO 4217 currency code (e.g., "usd", "eur", "gbp"). |
interval | string | Yes | Billing interval: "day", "week", "month", or "year". |
interval_count | integer | No | Number of intervals between billings. Defaults to 1. |
trial_days | integer | No | Number of free trial days before the first charge. Defaults to 0. |
metadata | object | No | Custom key-value pairs attached to the subscription. |
Subscription payments require payment configuration to be set up in your account settings. See the Payments feature guide for initial setup.
Downloading completed documents
Download all documents as a ZIP
Download as a merged PDF
Merge all documents in the submission into a single PDF file. This is useful when a submission contains multiple documents (e.g., agreement + addendum + audit trail) and you want a single combined file.merge=true query parameter instructs the server to concatenate all submission documents in order and return a single PDF. Without this parameter, the endpoint returns a ZIP archive containing each document as a separate file.
Download by document type
Request a specific document type instead of the full package:?inline=true to return with Content-Disposition: inline for in-browser preview instead of download.
Documents are generated asynchronously after all submitters complete. If
GET /api/submissions/:id/documents returns an empty array for a completed submission, the document generation job hasn’t finished yet. Wait a few seconds and retry.List available documents
Archiving submissions
Archive a submission to remove it from active views. The submission data is preserved and can still be retrieved via the API.Archiving is a soft delete. The submission and all its documents remain accessible. The
archived_at timestamp is set and the status changes to archived.