Bulk send
Bulk send takes one document and sends it to many clients in a single pass. The result is indistinguishable from sending each one by hand: every client gets a real envelope, filed under that client, filled in with that client's details, with its own audit trail, signing links, webhooks and — when enabled — automatic vaulting on completion.
All bulk-send endpoints are mounted under /api/v2/bulk-send, authenticated with the web
app session (Authorization: Bearer <access_token> + X-Org-Id), and admin-only.
How it works
- Create a batch with the document source and signing options.
- Open the document editor on the batch (
POST /api/v2/esign/builder-sessionwithbatch_id). This clones the template — or merges the package, or starts an empty editor for an upload — into the batch's master template. Fields are placed once, here. - Choose the clients (
POST /:id/items). Up to 1,000 per batch. - Accept the Vault-In Certification Terms (
POST /:id/vault-consent) when auto-vault is on. The acceptance is copied onto every envelope the batch creates. - Submit (
POST /:id/submit). A durable Workflow then creates and sends one envelope per client, in chunks, with automatic retries — a closed browser tab or a provider blip cannot leave the batch half-sent. - Poll
GET /:idfor per-client progress.
Per client, the Workflow does exactly what a single send does: it creates the envelope
under the client with status preparing (so it appears in the client's Documents at
once), attaches the signers, clones the master template for that envelope, prefills the
client's data into matching fields, creates the signing submission and emails the first
signer.
Signers
Each envelope is addressed to the client's primary contact (primary_contact_name,
falling back to the client name) at the client record's email. With
add_me_as_signer: true the batch creator signs every document as the second party.
preserve_signing_order | add_me_as_signer | Result |
|---|---|---|
true | true | The client signs first; the sender is emailed once they finish. |
true | false | The client signs. |
false | true | Client and sender are invited at the same time. |
false | false | The client signs. |
The master template must define exactly as many parties as the send has signers (one, or
two with add_me_as_signer). POST /:id/submit returns 422 otherwise.
With KBA on, only the client signer is challenged. The sender added via
add_me_as_signer is already authenticated to Loyva and is never asked to verify, so a
KBA batch bills one verification per client, not per signer.
Lifecycle
draft (setup) → ready (clients chosen) → running (Workflow active) → completed |
cancelled | failed
Per-client item statuses: pending → running → sent | failed | skipped |
cancelled.
skipped— the client has no email address, or its email is the sender's own. Recorded when the clients are added, so the outcome list is complete before anything is sent.failed— the send itself failed (the reason is inerror). The envelope stays under the client as Preparing and can be sent from there by hand.
Create a batch
POST/bulk-send
{
"name": "2027 Service Agreement",
"document_source": "template",
"source_template_id": "tpl_a1b2c3",
"preserve_signing_order": true,
"add_me_as_signer": true,
"auto_vault_enabled": true,
"tag_ids": ["tag_renewal"]
}
| Field | Type | Notes |
|---|---|---|
name | string | Document title; becomes envelope_name on every envelope. |
document_source | template | package | new | What the master is built from. |
source_template_id | string | Required for template. Word (pricing-table) templates are rejected. |
source_package_id | string | Required for package. |
kba_required | boolean | Only read for new; templates and packages already fixed it. |
preserve_signing_order | boolean | Default true. |
add_me_as_signer | boolean | Default false. |
auto_vault_enabled | boolean | Requires the terms acceptance below before submit. |
tag_ids | string[] | Applied to every envelope. |
Returns 201 with the batch. docuseal_instance and kba_required are derived from the
source and reported on the batch.
Open the editor on a batch
POST/esign/builder-session
{ "batch_id": "bsb_9f8e7d6c5b4a3210", "template_id": "tpl_a1b2c3", "template_name": "2027 Service Agreement" }
Same response as a per-envelope session, plus roles — the parties the master template
defines, in order. Reopening the editor on the same batch and source continues the same
master template rather than cloning again. batch_id and envelope_id are mutually
exclusive.
Persist the editor's template id back to the batch as it saves:
PATCH/bulk-send/:id
{ "master_template_id": "4312" }
Also accepts name, preserve_signing_order, add_me_as_signer, tag_ids,
auto_vault_enabled and (for new only, before the editor is opened) kba_required.
Allowed while the batch is draft or ready; 409 afterwards.
Record auto-vault consent
POST/bulk-send/:id/vault-consent
{ "auto_vault_enabled": true, "acknowledge_authoritative_copy": true }
Identical semantics to POST /envelopes/:id/auto-vault-consent, accepted once for the
batch. The acceptance — not the toggle — authorises the later unattended vault, and it is
stamped onto every envelope the batch creates (vault_in_terms_accepted_at/by). Pass
auto_vault_enabled: false to clear it.
Set the clients
POST/bulk-send/:id/items
{ "customer_ids": ["cust_1", "cust_2", "cust_3"] }
Replaces the batch's client list (1–1,000 ids). Ids outside the organization are
rejected; clients without an email address are kept as skipped.
{ "data": { "added": 3, "skipped_no_email": ["cust_3"], "rejected": [] } }
Submit
POST/bulk-send/:id/submit
Validates the setup and starts the Workflow. Returns 202 with the batch in running.
| Status | Meaning |
|---|---|
| 422 | No master template, no clients with an email, terms not accepted with auto-vault on, or the party count does not match the signer count. |
| 409 | Already submitted. |
| 502 | The master template could not be read from the signing provider. |
| 503 | Bulk send is not configured in this environment. |
Progress
GET/bulk-send/:id
{
"data": {
"batch": { "batch_id": "bsb_9f8e7d6c5b4a3210", "status": "running", "total_count": 3, "sent_count": 1, "failed_count": 0, "skipped_count": 1 },
"counts": { "pending": 1, "running": 0, "sent": 1, "failed": 0, "skipped": 1, "cancelled": 0 },
"items": [
{ "item_id": "bsi_1", "customer_id": "cust_1", "customer_name": "Acme Inc", "email": "[email protected]", "status": "sent", "envelope_id": "env_x7k9m2p4q1w3", "error": null, "sent_at": "2026-09-02T18:04:11Z" },
{ "item_id": "bsi_3", "customer_id": "cust_3", "customer_name": "Bob Lee", "email": null, "status": "skipped", "envelope_id": null, "error": "No email address", "sent_at": null }
]
}
}
Poll every couple of seconds while batch.status is running.
Cancel the remainder
POST/bulk-send/:id/cancel
Clients not yet processed are marked cancelled; documents already sent are unaffected.
The Workflow notices before its next chunk and finalises the batch.
Discard an unsent batch
DELETE/bulk-send/:id
Only while draft or ready. Soft-deletes the batch and archives its master template in
the signing provider.
Envelopes created by a batch
Every envelope carries the batch in its metadata, and its audit trail records the batch
on envelope.created:
{ "metadata": { "document_source": "template", "source_template_id": "tpl_a1b2c3", "bulk_send": { "batch_id": "bsb_9f8e7d6c5b4a3210", "item_id": "bsi_1" } } }
Nothing else about them is special: they list, sign, complete, vault and fire webhooks like any other envelope, and they count toward e-sign usage one each.