REFRACT Dispatch
REFRACT Dispatch is a governed batch document generation engine. Submit a payload with hundreds of records, get a validation report, obtain approval, and let the Processor render and deliver each document independently - with a per-record audit trail and REFRACT Delivery integration.
REFRACT Dispatch extends the REFRACT PDF render engine with a governed batch layer. Rather than submitting one document at a time, you submit an array of records in a single POST /api/render call. REFRACT Dispatch validates the records, generates a batch intake receipt, routes to an approver (when configured), and - after approval - hands off to the Processor to render and deliver each document independently.
Enterprise Feature
REFRACT Dispatch requires the vaultDispatch feature gate on your licence. Set features.vaultDispatch: true in the render request.
Auto-derive: If your template already has distribution.enabled: true and distribution.requireApproval: true in templateSettings, the vaultDispatch feature is activated automatically - you do not need to pass it explicitly. Passing it explicitly is recommended for clarity.
Not the same as Relay Mode
REFRACT Dispatch governs batches of records (dataSource as an array). For queuing a single document asynchronously, see Relay Mode instead - a different flag on a different request shape.
What REFRACT Dispatch Does
Batch Record Validation
Each record in the batch is validated against the template's field rules and filename template before any PDF is rendered. An intake receipt PDF summarises the readiness of each record.
Governed Approval Flow
When requireApproval is true, the batch enters pending-approval state. A designated approver reviews the intake receipt and decides to approve, request changes, or reject before any PDFs are generated.
Independent Per-Record Processing
After approval, the Processor renders each record independently. Each gets its own correlationId, PDF, and audit trail. Failures in one record do not block others.
REFRACT Delivery Integration
Each rendered PDF can be delivered to its recipient via REFRACT Delivery secure email automatically. The recipientEmail field in each record drives delivery.
Distribution Modes
Individual mode renders one PDF per record. Combined mode merges all records into a single PDF. Both modes support ZIP bundle download.
Partial Failure Handling
A batch that processes some records successfully and others with errors completes in partially-failed state. Processed and error counts are tracked separately, and each recipient's email result is reported back as sent, failed, or pending.
Batch Lifecycle States
| State | Description |
|---|---|
pending-approval | Batch submitted and validated; awaiting approver decision. |
invalid | One or more records failed validation with error severity. Batch cannot proceed until corrected and resubmitted. |
changes-requested | Approver returned the batch with comments. Submitter must correct and resubmit. |
approved | Approver's decision response reports this state; the batch is queued immediately in the same call. |
queued | The batch's stored state once approved. Enqueued to the low Service Bus queue. Awaiting Processor pickup. |
processing | Processor is actively rendering records. processedCount and errorCount update as records complete. |
completed | All records processed successfully. |
partially-failed | Processing finished; some records succeeded and some failed. |
rejected | Approver rejected the batch. No PDFs are produced. |
cancelled | Cancelled by the submitter before processing began. |
Template Distribution Settings
Batch dispatch is controlled by a distribution block in the template's templateSettings. This block can be set in the .rpkg template file or overridden per request in templateSettings.distribution.
{
"templateSettings": {
"distribution": {
"mode": "individual",
"requireApproval": true,
"fileNameTemplate": "Statement_{{accountNumber}}_{BATCHID_1}",
"approversEmail": "ap-approver@contoso.com",
"validationFields": ["accountNumber", "balance"],
"deliveryConfig": {
"mode": "secure-email",
"expiresInHours": 168
},
"zipBundle": false
}
}
}| Setting | Type | Description |
|---|---|---|
mode | individual | combined | individual renders one PDF per record. combined merges all records into one PDF. Default: individual. |
requireApproval | boolean | When true, batch enters pending-approval before processing. When false, the batch is auto-approved and queued immediately. |
fileNameTemplate | string | Filename pattern for each rendered PDF. Supports {{fieldName}} tokens from the record, {BATCHID_1} (1-based index), {BATCHID} (0-based). |
validationFields | string[] | Fields every record must have, also shown for each record in the intake receipt and the batch's validation results for the approver to check. A field that is missing, null or blank makes the record invalid, with an issue naming it; zero and false are values. One invalid record refuses the whole batch. Accepts top-level names, a.b paths into nested objects, and Array[].field paths, which need at least one value. Each one is checked on every record and stored with that record's result, so each adds to intake time and to the receipt: keep it to two or three of the fields that matter most, such as the account number and the balance. |
approversEmail | string | string[] | Approver email(s) to notify when the batch reaches pending-approval. Overridden by the tenant-level approver config if absent. |
deliveryConfig.mode | secure-email | none | Whether to create a REFRACT Delivery session per record after rendering. none disables delivery; secure-email creates a session for each recipientEmail in the record. |
deliveryConfig.expiresInHours | number | Delivery session TTL. Defaults to 168 hours (7 days). |
zipBundle | boolean | When true (individual mode only), all rendered PDFs are also bundled into a single ZIP and stored in blob storage. |
How Batch Intake Works
Batch dispatch is triggered via the standard render endpoint with an array dataSource and the vaultDispatch feature enabled.
At most 1,000 records per batch
A batch holds at most 1,000 records, or fewer where your license sets a lower limit. A larger batch is refused before anything is stored: the response is an error-report PDF with status 400 and code BATCH_TOO_LARGE, stating the limit and the number of records received, and no batch, receipt or Activity item is created and nothing is sent. To send more documents, split the records into several smaller batches and submit each one.
Submit the batch via POST /api/render
Pass dataSource as an array of records. Include distribution settings in templateSettings and set features.vaultDispatch: true.
Dispatcher validates records
Each record must have every field named in validationFields and used in the fileNameTemplate, and, when the batch sends to recipients, a recipient email. Any recipient addresses must be valid. The batch's overall readiness is one of VALID, WARNINGS, or INVALID; one invalid record makes it INVALID, and the batch is refused.
Batch intake receipt returned
The Dispatcher returns HTTP 202 with a batch intake receipt PDF as the response body. The X-Refract-BatchId and X-Refract-CorrelationId headers carry the batch identifiers. File the receipt against the originating record in your source system.
The receipt states the batch's status in words ("Queued", "Pending approval", or "Refused") and its readiness as "Valid", "Valid, with warnings", or "Invalid", coloured green, amber, or red. Its times are printed in UTC with the zone shown, for example "Oct 9, 2026 2:41 PM UTC". Recipient email addresses in the validation details are masked to the first character and the domain, for example j***@example.com. The "Submitted By" value is printed as submitted.
Approval (when requireApproval: true)
The batch enters pending-approval. The configured approver(s) receive an email notification. The approver reviews the intake receipt via REFRACT Lifecycle and calls POST /api/dispatch/batch/{batchId}/decide. Decision comments are limited to 1,000 characters; see Decision comments.
Processing
After approval (or immediately when requireApproval: false), the batch is enqueued. The Processor renders each record independently, uploads each PDF, posts a REFRACT_Activity item per record, and (if delivery is configured) creates a REFRACT Delivery session per recipient. Each recipient's email outcome then comes back to the batch; see Delivery Results.
Delivery Results
When a batch sends its documents to recipients, the outcome of each recipient's invitation email is reported back to the batch and recorded on the batch's audit chain, one event per recipient per document.
| Result | Meaning |
|---|---|
| Sent | The email service accepted the email for sending. This does not confirm that it reached the inbox or was opened: a recipient's access and download are recorded on that document's REFRACT Delivery session. |
| Failed | The email could not be sent once every automatic retry was used, or the message was dead-lettered, or the document's delivery job failed before the recipient's invitation was queued. The result records the stage that failed (render, send, handoff, dead-letter, or session) and a short error code, never the error text or the address. |
| Pending | Expected recipients with no result reported yet: the number of recipients on documents queued for delivery, minus those sent or failed. Pending is not an error. |
A failed result can later be followed by a sent one for the same recipient and document, for example when a dead-lettered invitation is resubmitted by hand and then sent; that recipient counts as sent. A failed result is never recorded after a sent one.
When results appear. With the default shared email service, your Processor collects results from REFRACT's notification service every 2 minutes, so a sent result can take about 2 minutes to appear. Failures appear only after the last automatic retry, or at the next 5-minute check for dead-lettered messages, so they can take longer. With EMAIL_PROVIDER=customer-acs, your Processor sends the email itself and records the result straight away. A result that is never collected is deleted from REFRACT's service after 30 days. The batch view in REFRACT Lifecycle does not refresh by itself: select Refresh to see new results.
Where to see them
Open the batch's record in REFRACT Lifecycle and go to the Batch Timeline tab. Batch records require the Lifecycle.Reader role.
- The Completed entry summarises the batch, for example "2 documents stored and queued for delivery, 1 failed." followed by "Delivery: 5 sent, 1 failed, 2 pending." The same delivery summary appears as the Delivery row on the Properties tab and the Delivery figure in Dispatch Review. For a batch whose recipient counts were not recorded, pending reads "pending not known".
- Failed recipients are listed under the Completed entry, one line for each recipient whose latest result is a failure, with the record number, a short recipient identifier, the stage it failed at, and the error code. Sent recipients get no line, at any batch size: they are counted in the summary and recorded on the audit chain.
- The Audit chain card below the timeline lists every event on the batch's chain, every delivery result included, 50 per page, with Export, and states whether the chain verifies, for example "Verified: N events, each signed and chained to the one before." A delivery event's title names the record and recipient ("Delivery sent after a failure" when it follows one). A sent event reads "accepted by the email service at time · recorded time"; a failure gives the stage, error code, and reporting service with the same two times. The first time is when the email service reported the result and the second is when it was added to the chain, so they can differ by up to the 2-minute collection interval.
What the chain records
Each result is a BATCH_DOCUMENT_DELIVERY_SENT or BATCH_DOCUMENT_DELIVERY_FAILED event carrying the record number, the document's correlation ID, the recipient's identifier, which service reported it, and when; a failure also carries the stage and error code. The recipient identifier is a keyed hash of the address (HMAC-SHA256 of the trimmed, lower-cased address, under a key derived from your deployment's audit key), never the address itself. Your Processor computes it, so REFRACT's notification service holds only the finished hash and never the key.
To read results through the API, see deliveryResults on Get Batch and kind=delivery on Get Audit Chain.
Decision comments
An approver's comments are limited to 1,000 characters, not counting leading and trailing spaces. The Dispatch Review shows a running count ("n / 1,000 characters") and disables Submit Decision while the comments are over the limit. The API refuses longer comments with 400 and code DECISION_COMMENTS_TOO_LONG, and the batch is not changed.
The batch's audit chain records a SHA-256 hash of the comments and their length, not the text. The text itself is kept with the batch record. REFRACT Lifecycle shows comments as plain text with their line breaks kept.
Per-Record Data Requirements
Each record in the dataSource array is a plain JSON object. The fields available depend on the template, but two fields have special meaning for REFRACT Dispatch:
| Field | Description |
|---|---|
recipientEmail | Email address for REFRACT Delivery session creation (email is read too). Required on every record when the batch sends to recipients: deliveryConfig.mode: secure-email, or the request turning on vaultDelivery without mode: none. A record without one is invalid, whether or not validationFields lists it. Supports semicolon-separated addresses for multiple recipients per record; each one is checked. |
recipientName | Display name used in the delivery notification email. Optional. Supports semicolon-separated names aligned by index to recipientEmail. |
The documentIdTemplate option in options allows dynamic document IDs per record using {{fieldName}} tokens:
{
"options": {
"documentIdTemplate": "STMT-{{accountNumber}}"
}
}API Reference
Full reference for batch management endpoints: list, get, decide, and cancel.
Dispatcher Deployment and Link Lifecycle
What happens to outstanding delivery links from batch records when you redeploy or move your Dispatcher, and how to plan around it.
REFRACT Notification
REFRACT Notification is the shared notification layer for the REFRACT Platform. It routes email notifications for REFRACT Delivery and REFRACT Workflow through either REFRACT Shared Services ACS or your own Azure Communication Services instance.
REFRACT Dispatch API Reference
HTTP endpoint reference for batch dispatch management - get batch detail, validation results and audit chain, approve or reject, and cancel.