Getting Started
SealRoute API Documentation
Complete REST API reference for integrating SealRoute into your own applications.
Authentication
All API requests require the X-Auth-Token header (unless noted otherwise):
Code
Get your API key from Settings → API or via the User Management API.
User Management
List Users
Code
Returns all active users in the account. Admin only.
Response:
Code
Get Current User
Code
Returns the authenticated user's info.
Get User by ID
Code
Admin only.
Create User
Code
Admin only. Returns the new user with their API key.
| Parameter | Type | Required | Description |
|---|---|---|---|
email | string | Yes | User email address |
first_name | string | No | First name |
last_name | string | No | Last name |
password | string | No | Password (auto-generated if blank) |
role | string | No | admin, editor, or viewer (default: admin) |
Example:
Code
Response (201):
Code
Update User
Code
Admin only.
| Parameter | Type | Description |
|---|---|---|
email | string | New email |
first_name | string | New first name |
last_name | string | New last name |
password | string | New password |
role | string | admin, editor, or viewer |
Delete User
Code
Admin only. Soft-deletes (archives) the user. Cannot delete yourself.
Get User's API Key
Code
Admin only.
Response:
Code
Regenerate User's API Key
Code
Admin only. Generates a new API key (old key stops working immediately).
Templates
List Templates
Code
| Parameter | Type | Description |
|---|---|---|
q | string | Search by name |
folder | string | Filter by folder name |
archived | boolean | Include archived templates |
external_id | string | Filter by external ID |
limit | integer | Max results (default 10, max 100) |
after | integer | Cursor for pagination (ID) |
before | integer | Cursor for pagination (ID) |
Get Template
Code
Update Template
Code
| Parameter | Type | Description |
|---|---|---|
name | string | Template name |
external_id | string | External identifier |
folder_name | string | Move to folder |
roles | array | Update submitter roles |
fields | array | Update field definitions |
archived | boolean | Archive/unarchive |
Delete Template
Code
| Parameter | Type | Description |
|---|---|---|
permanently | boolean | If true, permanently delete (default: archive) |
Clone Template
Code
| Parameter | Type | Description |
|---|---|---|
name | string | Name for the clone |
folder_name | string | Target folder |
external_id | string | External ID for the clone |
Submissions
List Submissions
Code
| Parameter | Type | Description |
|---|---|---|
q | string | Search query |
template_id | integer | Filter by template |
template_folder | string | Filter by folder |
archived | boolean | Include archived |
limit | integer | Max results (default 10, max 100) |
after | integer | Cursor pagination |
before | integer | Cursor pagination |
Get Submission
Code
Create Submission
Code
Create a submission from an existing template.
Top-Level Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
template_id | integer | Yes | Template to use |
submitters | array | Yes | Array of submitter objects (see below) |
order | string | No | preserved (sequential) or random (parallel) |
send_email | boolean | No | Send invitation emails (default: true) |
message | object | No | Custom email { subject, body } |
consent_enabled | boolean | No | Require consent checkbox for all submitters |
consent_document_url | string | No | Terms and conditions URL |
consent_document_text | string | No | Consent checkbox label text |
preferences | object | No | Template-level preferences (see Template Preferences) |
Submitter-Level Parameters (submitters[])
| Parameter | Type | Required | Description |
|---|---|---|---|
role | string | Yes | Must match a role defined in the template |
email | string | Yes* | Submitter email (* or phone required) |
name | string | No | Display name |
phone | string | No | Phone number (E.164 format, e.g. +628123456789) |
external_id | string | No | Your external identifier |
values | object | No | Pre-fill {{...;type=X}} form field values (keyed by field name) |
variables | object | No | Role-scoped [[...]] data variables (merged with top-level variables) |
fields | array | No | Override field settings ([{ name, default_value, readonly, required }]) |
metadata | object | No | Custom key-value data stored with the submitter |
send_email | boolean | No | Send invitation email (overrides top-level) |
send_sms | boolean | No | Send invitation SMS |
completed_redirect_url | string | No | Redirect URL after signing |
order | integer | No | Position in signing sequence (0 = first, same number = parallel) |
completed | boolean | No | Mark as pre-completed (skip signing) |
go_to_last | boolean | No | Start at the last unfilled field |
require_phone_2fa | boolean | No | Require phone OTP verification to access |
require_email_2fa | boolean | No | Require email OTP verification to access |
consent_enabled | boolean | No | Per-submitter consent override |
consent_document_url | string | No | Per-submitter terms URL |
consent_document_text | string | No | Per-submitter consent checkbox text |
reply_to | string | No | Reply-to email address for invitation |
logo_url | string | No | White-label logo for this recipient only (overrides account default; never modifies account Personalization) |
company_name | string | No | White-label brand name for this recipient only |
stamp_url | string | No | Stamp image URL for this recipient only (falls back to logo_url) |
message.subject | string | No | Custom email subject for this submitter |
message.body | string | No | Custom email body for this submitter |
Create Submission from DOCX
Code
Create a one-off submission from a DOCX file with embedded tags. The DOCX can contain [[variable]] data placeholders and {{Field;type=X}} form field tags. See TEMPLATE_TAGS.md for full tag syntax.
Top-Level Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
documents | array | Yes | [{ name: "file.docx", file: "BASE64..." }] |
variables | object | No | Data variables for [[...]] placeholders |
submitters | array | Yes | Array of submitter objects (see below) |
name | string | No | Submission name |
order | string | No | preserved (sequential) or random (parallel) |
send_email | boolean | No | Send invitation emails (default: true) |
consent_enabled | boolean | No | Require consent checkbox for all submitters |
consent_document_url | string | No | Terms and conditions URL |
consent_document_text | string | No | Consent checkbox label text |
preferences | object | No | Template-level preferences (see Template Preferences) |
Submitter-Level Parameters (submitters[])
| Parameter | Type | Required | Description |
|---|---|---|---|
role | string | Yes | Must match role= in {{...}} tags |
email | string | Yes* | Submitter email (* or phone required) |
name | string | No | Display name |
phone | string | No | Phone number (E.164 format, e.g. +628123456789) |
external_id | string | No | Your external identifier |
values | object | No | Pre-fill {{...;type=X}} form fields (keyed by field name) |
variables | object | No | Role-scoped [[...]] variables (merged with top-level variables) |
fields | array | No | Override field settings ([{ name, default_value, readonly, required }]) |
metadata | object | No | Custom key-value data stored with the submitter |
send_email | boolean | No | Send invitation email (overrides top-level) |
send_sms | boolean | No | Send invitation SMS |
completed_redirect_url | string | No | Redirect URL after signing |
order | integer | No | Position in signing sequence (0 = first, same number = parallel) |
completed | boolean | No | Mark as pre-completed (skip signing) |
go_to_last | boolean | No | Start at the last unfilled field |
require_phone_2fa | boolean | No | Require phone OTP verification to access |
require_email_2fa | boolean | No | Require email OTP verification to access |
consent_enabled | boolean | No | Per-submitter consent override |
consent_document_url | string | No | Per-submitter terms URL |
consent_document_text | string | No | Per-submitter consent checkbox text |
reply_to | string | No | Reply-to email address for invitation |
logo_url | string | No | White-label logo for this recipient only (overrides account default; never modifies account Personalization) |
company_name | string | No | White-label brand name for this recipient only |
stamp_url | string | No | Stamp image URL for this recipient only (falls back to logo_url) |
message.subject | string | No | Custom email subject for this submitter |
message.body | string | No | Custom email body for this submitter |
Variables vs Values
| JSON Key | DOCX Tag | Purpose |
|---|---|---|
variables (top-level or submitters[].variables) | [[variable_name]] | Static text replacement before PDF generation |
submitters[].values | {{FieldName;type=X}} | Pre-fill interactive form fields |
Top-level variables and each submitter's variables are merged into a single map. Later submitters override duplicate keys.
DOCX Formatting Inheritance
The API automatically carries your Word document's formatting onto the rendered form fields, so the signed PDF matches the look of your DOCX:
| Property | Source in Word | Effect |
|---|---|---|
| Alignment | Paragraph alignment (center, right) | Field is rendered with the same alignment |
| Font family | Font of the surrounding text (Times New Roman → Times, Arial → Helvetica, Courier New → Courier) | Same font used for the rendered value |
| Font size | Font size of the surrounding text or the document default | Same point size used for the rendered value |
Explicit tag attributes (e.g., font=Courier;font_size=14) override DOCX formatting. For full details see Template Tags → DOCX Formatting Inheritance.
Template Preferences
Both POST /api/submissions and POST /api/submissions/docx accept a top-level preferences object that is persisted on the submission's template. These flags override account-level defaults (configured under Settings → Personalization) for this specific submission.
| Key | Type | Default | Description |
|---|---|---|---|
completed_notification_email_enabled | boolean | true | Send the sender a notification email when all submitters complete |
completed_notification_email_attach_audit | boolean | true | Attach the audit log PDF to the sender's completion-notification email |
completed_notification_email_attach_documents | boolean | true | Attach signed document PDFs to the sender's completion-notification email |
documents_copy_email_enabled | boolean | true | Email each signer a copy of the completed documents |
documents_copy_email_attach_audit | boolean | true | Attach the audit log PDF to the signer's copy email |
documents_copy_email_attach_documents | boolean | true | Attach signed document PDFs to the signer's copy email |
submitters_order | string | — | preserved (sequential) or random (parallel). Same effect as top-level order. |
bcc_completed | string | — | Comma-separated BCC addresses for completion notifications |
require_email_2fa | boolean | false | Require email OTP for every signer |
require_phone_2fa | boolean | false | Require phone OTP (requires phone OTP webhook config) |
shared_link_2fa | boolean | false | Require email 2FA when the signing link is shared |
Account-level toggles act as a ceiling: if e.g. attach_audit_log is disabled under Personalization, a template-level true here will not re-enable it. The audit trail PDF itself is always generated on completion regardless of these flags; they only control whether it is attached to outgoing emails.
Example
Code
Response (200): Array of submitter objects with signing URLs:
Code
Create Submission from PDF
Code
Create a submission from a PDF file with text tags.
| Parameter | Type | Required | Description |
|---|---|---|---|
documents | array | Yes | [{ name: "file.pdf", file: "BASE64..." }] |
submitters | array | Yes | Submitter objects |
name | string | No | Submission name |
Delete Submission
Code
| Parameter | Type | Description |
|---|---|---|
permanently | boolean | Permanently delete (default: archive) |
Get Submission Documents
Code
Returns signed document download URLs.
| Parameter | Type | Description |
|---|---|---|
merge | string | Set to true to get a single merged PDF |
Response:
Code
Submitters
List Submitters
Code
| Parameter | Type | Description |
|---|---|---|
q | string | Search by name/email |
submission_id | integer | Filter by submission |
template_id | integer | Filter by template |
external_id | string | Filter by external ID |
slug | string | Filter by slug |
completed_after | string | Filter by completion date (ISO 8601) |
completed_before | string | Filter by completion date (ISO 8601) |
limit | integer | Max results |
after | integer | Cursor pagination |
before | integer | Cursor pagination |
Get Submitter
Code
Update Submitter
Code
| Parameter | Type | Description |
|---|---|---|
name | string | Display name |
email | string | Email address |
phone | string | Phone number |
values | object | Field values |
metadata | object | Custom metadata |
send_email | boolean | Re-send invitation email |
send_sms | boolean | Re-send invitation SMS |
completed | boolean | Mark as completed |
fields | array | Override field settings |
logo_url | string | Per-submitter white-label logo URL (overrides account default; never modifies account Personalization). Pass empty string to clear. |
company_name | string | Per-submitter white-label brand name (overrides account default; never modifies account Personalization) |
stamp_url | string | Per-submitter signature stamp image (falls back to logo_url) |
Per-API-call White-Label Branding
You can override the SealRoute logo, brand name, and signature stamp image per recipient through the API. Branding sent through the API is scoped strictly to the receiving submitter — it never modifies your account's Personalization settings, never affects other recipients on the same submission, and never appears on the audit-trail certificate.
Precedence (first non-empty value wins):
submitters[].logo_url/company_name/stamp_url— per-recipient (the only API surface)- Account Personalization (Settings → Personalization, UI-only)
- SealRoute defaults
The values flow into:
- The signing page header (logo + brand name) for that recipient
- The post-completion receipt page (
/document/:slug/completed) for that recipient - The signature stamp image rendered into the recipient's signed copy (
stamp_url, thenlogo_url)
The values do not flow into:
- Account-level Personalization (
account_configs) — the API can never write here - The dashboard / settings UI
- The audit-trail PDF header (always uses account defaults)
- Other recipients on the same submission
Notes:
- Only public URLs are fetched. Non-image responses or redirect loops are silently dropped — the next layer in the chain is used.
- Sending an empty string on
PUT /api/submitters/:idclears a previously stored override. - These overrides are persisted on the submitter record, so reopening the link later still shows the same branding.
- Top-level
logo_url/company_name/stamp_urlonPOST /api/submissionsandPOST /api/submissions/docxis ignored; supply them insidesubmitters[]instead.
Tools
Merge PDFs
Code
Merge multiple PDF files into one.
| Parameter | Type | Description |
|---|---|---|
files | array | Array of base64-encoded PDF strings |
Response:
Code
Verify PDF Signature
Code
Verify digital signatures in a PDF.
| Parameter | Type | Description |
|---|---|---|
file | string | Base64-encoded PDF |
Response:
Code
Webhooks
Manage outgoing webhook URLs that receive HTTP POST callbacks when events occur. Admin only.
Supported Events
| Event | Triggered When |
|---|---|
form.viewed | A submitter views the signing form |
form.started | A submitter starts filling the form |
form.completed | A submitter finishes signing |
form.declined | A submitter declines to sign |
submission.created | A new submission is created |
submission.completed | All submitters have completed |
submission.expired | A submission expires |
submission.archived | A submission is archived |
template.created | A new template is created |
template.updated | A template is modified |
List Webhooks
Code
| Parameter | Type | Description |
|---|---|---|
limit | integer | Max results (default 10, max 100) |
after | integer | Cursor pagination (ID) |
before | integer | Cursor pagination (ID) |
Response:
Code
Get Webhook
Code
Create Webhook
Code
| Parameter | Type | Required | Description |
|---|---|---|---|
url | string | Yes | Destination URL (receives POST requests) |
events | array | No | Event types to subscribe to (default: all form events) |
secret | object | No | Custom HTTP header { "Header-Name": "value" } sent with each request |
Example:
Code
Response (201):
Code
Update Webhook
Code
| Parameter | Type | Description |
|---|---|---|
url | string | New destination URL |
events | array | Replace subscribed events |
secret | object | Replace secret header |
Delete Webhook
Code
Response:
Code
Test Webhook
Code
Sends a test form.completed event using the most recently completed submitter. Useful for verifying your endpoint works.
Response:
Code
Webhook Payload Format
When an event fires, SealRoute sends a POST request to your URL with this JSON body:
Code
The data shape depends on the event type:
form.*events include submitter details (id, email, name, status, values, documents)submission.*events include submission details (id, status, submitters, template)template.*events include template details (id, name, fields, submitters)
If a secret header is configured, it is included in every request for your server to verify authenticity.
Events (Polling)
As an alternative to webhooks, you can poll for events.
Form Events
Code
List form-related events (e.g., form.completed).
| Parameter | Type | Description |
|---|---|---|
limit | integer | Max results |
after | string | Unix timestamp cursor |
before | string | Unix timestamp cursor |
Submission Events
Code
List submission-related events (e.g., submission.completed).
Same pagination parameters as form events.
File Upload
Upload Attachment
Code
No authentication required — uses submitter slug for authorization.
| Parameter | Type | Description |
|---|---|---|
submitter_slug | string | Submitter's unique slug |
type | string | Field type (signature, initials, image, etc.) |
file | file | The file to upload |
Pagination
List endpoints support cursor-based pagination:
Code
Use after and before query parameters with the cursor values.
Error Responses
| Status | Description |
|---|---|
401 | Missing or invalid X-Auth-Token |
403 | Insufficient permissions (wrong role) |
404 | Resource not found |
422 | Validation error (check error field) |
429 | Rate limited |
Error format:
Code
Roles & Permissions
| Role | Templates | Submissions | Users | Settings |
|---|---|---|---|---|
admin | Full access | Full access | CRUD | Full access |
editor | Own + shared | Own templates | Read only | Limited |
viewer | Shared only | Shared only | Self only | None |
Rate Limits
The API does not enforce hard rate limits by default, but the phone verification endpoint (/api/send_phone_verification_code) has a 60-second cooldown per phone number.