Title: Replaying failed Docusign Workflow Builder runs Short summary: Practical Baton playbook for replaying failed Docusign Workflow Builder runs: relay-side webhook replay vs Workflow Builder API restart, with duplicate-envelope guardrails.
A failed Docusign Workflow Builder run has two possible failure domains, and replay means something different in each. If the inbound trigger never reached Docusign, you replay the webhook payload from your relay (in Baton, from the Action log). If the workflow instance reached Docusign but failed mid-step, you can either retry from the failed step (the most convenient path when the step itself is recoverable) or cancel the failed instance and re-trigger a new one against the workflow's trigger URL, carrying an idempotency key so you do not duplicate the envelope.
This post is the practical version of replay failed docusign workflow run - the relay-side replay Docusign's own docs do not cover, plus the Workflow Builder API moves that do, in the order you actually run them at 09:05 on a Monday when a sales rep is asking why their contract did not go out.
What counts as a failed Workflow Builder run? #
Three distinct things get reported as 'the workflow failed' by the business:
- The trigger never arrived. Your CRM fired its webhook, but Docusign never recorded an instance. There is no row in
GET /v1/accounts/{accountId}/workflows/{workflowId}/instancesfor the deal id. This is a relay-layer failure. - The instance started but errored. An instance exists, status is
Failed, and a step (often an Extension App call or a missing template field) errored out. - The instance completed but the envelope is wrong. A signer is missing, the wrong template was used, or a merge field is blank. This is not a replay problem - it is a data problem in the trigger payload, and the fix is upstream.
Replay only solves the first two. The third needs a payload fix and a fresh trigger.
What does 'replay' actually mean at each layer? #
Before touching anything, name the layer:
- Relay-layer replay (inbound). You re-send a webhook payload that your CRM already delivered to Baton. Baton verifies the HMAC again, matches the payload to a Workflow Builder workflow, and POSTs to that workflow's trigger URL. The CRM is not involved in this replay - which is the point, because the CRM has usually moved on and will not re-fire the same event.
- Workflow-layer replay (instance). You can retry from the failed step on an existing instance (Workflow Builder's "Retry from failed step" action) [needs-source: Workflow Builder Retry from failed step documentation], or, when the instance is unrecoverable, cancel the failed instance and trigger a new one against the same workflow definition. The documented per-instance actions in the public Workflow Builder API include trigger (start), retry-from-failed-step, and cancel.
- Connect-layer replay (outbound, separate). If the problem is that your downstream system never learned the envelope was signed, that is a Docusign Connect issue, not a Workflow Builder one. Docusign exposes retryEventForEnvelopes for that, and you can read the Connect failure log via the API. That is a different failure domain - we mention it so you do not chase the wrong layer.
Most real 'replay failed Docusign workflow run' tickets are layer 1 or 2.
How to replay an inbound webhook from Baton's Action log #
The Action log records every inbound payload Baton accepted from a source platform, the HMAC verification result, the workflow it matched, and the response from the Workflow Builder trigger URL. That last field is the one that matters at 09:05: was the trigger call a 2xx, or did Docusign return a 4xx/5xx?
The replay path in Baton is short:
- Filter the Action log by the source platform and time window (for a sales rep asking about a specific deal, search by deal id or contact email in the payload preview).
- Open the failed action. Inspect the trigger response code and body. Common ones: a 4xx from Docusign means the payload did not match the workflow's
trigger_input_schema- re-fire will fail the same way until you fix the upstream payload or the workflow definition. A 5xx or a timeout means Docusign was unhealthy; re-fire is the right move. - Replay the action. Baton resends the same recorded payload to the same workflow's trigger URL. Nothing is fetched from the CRM, so the replay is deterministic for that payload.
- Confirm a new instance appears in
GET /v1/accounts/{accountId}/workflows/{workflowId}/instances.
The relay-layer replay is the move that does not exist in Docusign's docs, because Docusign does not see the upstream CRM. If you have built your own middleware instead of using Baton, you need an equivalent: the inbound webhook persisted on disk, idempotency on the receive side so duplicates do not double-trigger, and a replay button. Most teams discover they need this the first Monday after a Docusign incident. Our piece on why Docusign webhooks fail silently covers the visibility patterns in more depth.
When do you restart a Workflow Builder instance, and how? #
If the trigger landed but the instance failed mid-step, the relay-layer replay is the wrong tool - the trigger already worked. You restart the instance.
The most convenient option, when it is available, is Retry from the failed step. Workflow Builder exposes this both in the UI on a failed instance and as a per-instance API action [needs-source: Workflow Builder Retry from failed step documentation]. It picks up exactly where the instance errored, reusing the same instance id and the work already completed by earlier steps - so you do not re-execute the envelope-creation step if that step already succeeded. This is the right move when the failure was transient (an Extension App timeout, a downstream 5xx) and the upstream state is unchanged.
When retry-from-failed-step is not viable - because the workflow definition has changed, the payload was wrong, or an earlier step produced bad state - you fall back to cancel + re-trigger. That is two API calls, not one button. The per-instance actions in the Workflow Builder API relevant here are trigger (start a new instance) and cancel (stop an existing one):
# 1. Cancel the failed instance so it does not get retried by an operator later
POST /v1/accounts/{accountId}/workflows/{workflowId}/instances/{instanceId}/actions/cancel
Authorization: Bearer {access_token}
Content-Type: application/json
{}
# 2. Re-trigger the workflow with the original payload + an idempotency key
POST {trigger_http_config.url}
Authorization: Bearer {access_token}
Content-Type: application/json
{
"instance_name": "Deal-48213-replay-1",
"trigger_inputs": {
"deal_id": "48213",
"signer_email": "jordan@acme.test",
"signer_name": "Jordan Patel",
"idempotency_key": "deal-48213-v2"
}
}The trigger URL is the trigger_http_config.url field returned when you GET /v1/accounts/{accountId}/workflows/{workflowId}. Baton stores it per wired workflow; if you are doing this by hand from Postman, fetch it once.
A few things to know before you cancel:
- Cancellation is per-instance, not per-workflow. You will not break other in-flight runs.
- If the failed step is an Extension App and the app has already created an envelope, cancelling the instance does not cancel the envelope. You may need to void that envelope through the eSignature API separately. (This is also why Retry from failed step is gentler - it does not orphan a partially completed envelope.)
- The
instance_nameis the cheapest way to label a replay so it is greppable in the instances list later.original-name-replay-1works.
How do you avoid duplicate envelopes during replay? #
This is the single failure mode that turns a 20-minute replay into a customer-trust incident. Two protections together:
1. Stable idempotency key in the trigger payload. Pick something that already exists upstream: deal id, candidate id, agreement version. Pass it as a trigger_input so it flows into every workflow step. Workflow Builder uses at-least-once delivery to its consumers, which means Extension Apps must already be idempotent. The same key prevents replay duplicates.
2. Idempotency check inside the first step. Before the workflow asks eSignature to create an envelope, check whether an envelope already exists for that key. The cheapest implementation: store {idempotency_key -> envelope_id} in a small table (DynamoDB, Postgres) keyed by the idempotency key. If a row exists, return the existing envelope id and skip envelope creation.
With both in place, replaying the same payload three times produces one envelope, not three. Without them, every Monday-morning replay risks a duplicate signature request to the customer.
A 20-minute Monday-morning triage checklist #
When a rep pings 'the workflow did not fire for deal 48213':
- Minute 0-2: which layer? Search Baton's Action log for the deal id. If there is no action, the CRM never sent the webhook - go fix the CRM rule, not Baton. If there is an action with a non-2xx response, it is a relay-layer issue. If there is an action with a 2xx response, an instance exists - jump to step 4.
- Minute 2-5: inspect the inbound payload. Open the action, look at the recorded payload, and check it against the workflow's
trigger_input_schema. A missing required field is the most common cause. - Minute 5-8: replay or fix-and-replay. If the payload was valid and Docusign was unhealthy, replay. If the payload was invalid, fix the upstream mapping and have the CRM re-fire the event, or hand-craft a corrected payload and POST it to the trigger URL directly with an idempotency key.
- Minute 8-12: find the instance.
GET /v1/accounts/{accountId}/workflows/{workflowId}/instancesfiltered by the idempotency key or instance name. StatusFailedon a recoverable step means try Retry from failed step first. StatusIn Progresson a step that has been stuck for 10+ minutes usually means an Extension App is timing out; check that app's logs before you cancel. - Minute 12-17: retry, or cancel and re-trigger. If Retry from failed step is available and the upstream payload is still correct, fire it and skip to step 6. Otherwise cancel the failed instance and re-trigger with the same idempotency key plus a
-replay-Nsuffix oninstance_name. Confirm a new instance appears. - Minute 17-20: confirm the envelope. Check the eSignature API (or the workflow's instance detail) for exactly one envelope tied to the idempotency key. If there are two, void the older one and write yourself a note to add the idempotency check inside the first workflow step before this happens again.
That is the loop. The whole point is that every step has a fixed place to look, so you are not improvising under pressure.
Where this fits in your broader Docusign reliability story #
Replay is the recovery primitive. The prevention primitives are HMAC verification, retries on the inbound side, dead-letter queues for payloads that fail schema validation, and idempotency baked into every workflow step. Baton handles the relay-layer ones; the workflow-layer ones live in your Workflow Builder design. If you want broader Docusign IAM context (Workflow Builder is included in all IAM plans, App Center, Navigator, agentic AI on top), the fluidlabs resources library is where that strategic side lives.
If you are wiring up your first integration and want the replay path to exist on day one rather than rediscovering this in production: start with Baton, or browse the Baton resources library for integration recipes per source platform.