Relay Mode
How to trigger asynchronous, queue-based rendering for a single document via options.features.relay, how the request is routed through Service Bus, and how to confirm after the fact whether a render was queued or returned inline.
Overview
A render request to POST /api/render either returns the finished PDF immediately (inline) or is handed off to a queue and picked up by the Processor (relay). Relay mode is the per-request switch that selects the second behavior for a single document.
Relay mode is unrelated to REFRACT Dispatch batch processing - see Relay Mode vs. REFRACT Dispatch below.
Applies to templatePath + payloadPath requests only
Relay mode is only evaluated on requests that reference a template and payload by path (templatePath + payloadPath - the customer-storage-backed render route used by most ERP and CRM integrations). It has no effect on requests that send the payload inline in the request body, and no effect on rendering from a template on the Dispatcher's local disk.
Triggering Relay Mode
Set relay: true inside options.features on the render request:
{
"options": {
"features": {
"relay": true
}
}
}| Trigger | Notes |
|---|---|
options.features.relay: true | Recommended. Explicit and self-documenting. |
options.features.serviceBus: true | Legacy alias, still accepted and normalised to relay. Prefer relay in new integrations. |
Top-level priority and metadata, both non-null | Implicit trigger. Sending both fields routes the request through relay mode even without setting the relay flag. |
relay is a first-class flag alongside the others in the Feature Flags Reference and does not currently require a specific licence tier.
Full Example
{
"templatePath": "Templates/your-template.rpkg",
"payloadPath": "Payloads/your-payload.json",
"options": {
"documentId": "INV-2026-0831-TEST",
"docType": "Invoice",
"generatedBy": "billing@refractlogic.com",
"userGroup": "Internal",
"customColumns": { "SalesRep": "Jane Smith" },
"features": {
"relay": true,
"generatedDocuments": true,
"auditSnapshot": false,
"immutableAudit": true
}
}
}Adding "relay": true to options.features is the only change needed relative to a normal inline render request.
Flag-free alternative
Instead of features.relay, you can add top-level "priority": "standard" and any non-null "metadata": {} to the same request. Both fields being non-null routes through the same relay path.
Response Shapes
| Mode | Status | Body | Notes |
|---|---|---|---|
| Relay (queued) | 202 Accepted | JSON: { status: "queued", correlationId, queue, priority, reason, timestamp } | No PDF bytes are returned. The document is rendered asynchronously once the Processor picks up the message. |
| Inline | 200 OK | Binary PDF | Standard synchronous render response. |
The queued response's queue field reports which queue tier - standard, priority, or low - the request was routed to.
Confirming Whether a Render Was Relayed
The HTTP response is the fastest signal, but it's only visible to the original caller at request time. For after-the-fact confirmation, use one of the following - in order of reliability.
Check the VAULTPDF_Activity item's MetadataJSON
For a queued render, the activity record's MetadataJSON includes renderMode: "queue" and queueTier: "standard" | "priority" | "low". For an inline render, renderMode is absent entirely. Because this is part of the permanent SharePoint activity record, it's the most durable way to tell the two apart after the fact.
Look for the Processor's queue pickup log
The Processor logs Processing from {queue} queue... only when a message has actually reached and been picked up by its Service Bus trigger. This confirms the queue hop genuinely happened, not just that the Dispatcher reported queuing it.
(Advanced) Check the sealed audit archive's internal manifest
When immutableAudit or auditSnapshot triggers archiving for the render, the sealed .raudit archive contains its own internal metadata.json - distinct from the SharePoint MetadataJSON audit column - which also records queue: "queue" | "inline". This is only present when the render was archived. See Retention Policy for what else the archive contains.
Relay Mode vs. REFRACT Dispatch
Relay mode and REFRACT Dispatch both use the same Service Bus queue transport, but they are unrelated features that never overlap.
| Relay Mode | REFRACT Dispatch | |
|---|---|---|
| Triggered by | options.features.relay: true (or the implicit priority + metadata combination) on a normal templatePath + payloadPath request | dataSource as an array plus features.vaultDispatch: true |
| Processes | One document | An array of records, each rendered independently |
| Queue tier | Routed to standard, priority, or low | Always routed to the low queue |
| Governance | None - renders as soon as it's picked up | Optional approval flow, validation, per-record tracking |
| Response | 202 with a JSON status object | 202 with a batch intake receipt PDF |
Turning on relay does not activate batch behavior, and submitting a batch does not require relay. They share the same underlying queue transport and nothing else.
REFRACT Dispatch
Governed batch document generation: validation, approval, and independent per-record processing for arrays of records.
REFRACT PDF Rendering Pipeline
REFRACT PDF processes every template through a deterministic multi-stage rendering pipeline ensuring layout stability, visual consistency, and secure document generation, structured across 12 sequential stages from structure normalization to final PDF output.
Storage Providers
How to configure REFRACT PDF's storage system. Covers SharePoint setup, Azure Blob Storage setup, output routing via storage-config.json, required environment variables, and the response headers returned on each render.