Everything below the title and before the first H2. A purchase request waits because its approver is absent. Another changes after the budget owner signs off. A third is approved in the workflow, but its update fails in the ERP. These are the situations approval software must handle before a business can trust it. Approval workflow software design starts with clear decision authority, permitted state changes, escalation rules, and evidence. Routing a request to someone’s inbox is only one part of that process. The system must also establish which request version they reviewed, whether they were authorized to decide, and whether the approved outcome reached the authoritative business system. This guide follows a hypothetical $28,000 Marketing purchase request through submission, review, escalation, rework, and ERP writeback. We’ll use it to explain how roles, states, notifications, and audit records work together and what to validate before implementation.
Start Approval Workflow Software Design With the Decision, Not the Routing
Begin with the decision that changes an object’s business status, not with who an email gets sent to. In approval workflow software design, that decision anchors your state machine, authority model, and audit trail.
Our running example is a hypothetical Purchase Request (PR). The governed decision is simple to say and hard to do well: should this PR commit company funds under policy? That decision moves the PR’s status from Submitted to Approved, Rejected, or Returned for Rework. Everything else tasks, timers, notifications supports that status change.
Before drawing screens or swim lanes, define these boundaries:
- Approval object: A Purchase Request (PR) with key fields like requester, cost center, vendor, amount, and policy references.
- Business outcome: Authorized spend that’s compliant with budget, policy, and separation of duties.
- Decision owner: The accountable budget owner for the PR’s cost center (and, by policy, any higher authority if threshold rules trigger). They own the yes/no and the consequences.
- System of record: The purchasing/ERP module that stores the PR and, on approval, creates or updates the financial commitment.
- Workflow orchestrator: The approval service that evaluates rules, applies role-based approvals, enforces the approval workflow state machine, runs timed approval escalation rules, and records the approval audit trail.
Routing alone can’t do this. Email or chat routing doesn’t confer authority, enforce decision rules, preserve accountability, or handle exceptions and time-based behaviors. That’s where the boundary matters: only the system of record owns the PR and its financially effective status; the workflow orchestrator governs how a PR is evaluated and when it’s eligible to be written back.
Design consequence: the workflow can move a PR through internal states (for example, Submitted → Under Review → Approved Pending Writeback), apply escalations, and collect evidence. But the “Approved” business status that impacts spend is set in the system of record via an explicit, auditable handoff after all checks pass. Set this boundary now, and the next steps roles, thresholds, fields, and integrations fall into place with far less rework. If you want help planning software around a defined business decision, see our Business Software Consulting overview (services business software consulting).
Design Approval Roles, Thresholds, and Separation of Duties
Start by making authority explicit. In approval workflow software design, a clear role‑and‑permission matrix prevents confusion and closes audit gaps.
- Define roles by the actions they permit and the restrictions they enforce. Someone may request one purchase and approve another, but their authority must be checked against the specific request.
| Role | Permitted actions | Required restrictions |
|---|---|---|
| Requester | Prepare, submit, amend, or withdraw requests where policy permits | Cannot approve their own request |
| Approver | Review and decide within assigned scope and limits | Cannot exceed authority or approve a conflicting request |
| Override authority | Authorize defined policy exceptions | Must record justification, evidence, and any required independent approval |
| Administrator | Configure workflows, permissions, and policy versions | Cannot use administrative access to bypass approval controls |
| Auditor | Review decision history and supporting evidence | Read access is limited to authorized scope; historical decisions cannot be edited |
| Integration service | Read source data and apply approved outcomes | Cannot exercise discretionary human approval authority |
Where policy permits automatic approval, the workflow may evaluate explicit eligibility rules. Record the request version, policy version, rule results, and decision outcome. Missing inputs or unresolved exceptions must follow the defined review path.
Build a role‑and‑authority matrix
Define rules that turn organizational context into an eligible approver set. Use role‑based approvals, but anchor them to business data:
- Role and threshold: Define threshold boundaries precisely: up to $5,000; above $5,000 through $50,000; and above $50,000. Specify the currency, conversion basis, and whether the threshold applies to the total commitment, including applicable taxes or fees.
- Risk tier: Add Legal, InfoSec, or Compliance at higher risk levels.
- Department and budget ownership: Route to the cost center owner and the budget holder in the ERP.
- Org context: Project, location, vendor type, funding source, or customer impact.
Hypothetical example: A $28k vendor contract from Marketing (medium risk) requires Marketing’s budget owner (Level 1), then the Procurement manager (Level 2), and Legal review if the vendor uses customer data. No one outside the eligible set can approve.
Enforce separation of duties at two layers
Apply separation of duties through both account permissions and request-level checks. At provisioning time, restrict incompatible capabilities according to organizational policy for example, changing approval rules and independently authorizing exceptions under those same rules. At decision time, check the requester, approver, prior reviewers, authority limits, record scope, and delegation validity. Block self-approval and any additional conflicts defined by policy. A delegate must hold valid authority for the request and pass the same conflict checks as the original approver. For the $28,000 Marketing request, the budget owner and Procurement manager must satisfy the required authority checks. If customer data is involved, Legal review is also required. Whether the same person can satisfy more than one review role must be explicitly defined.
Exception Behavior and Request Lifecycle
- Reject: Terminates the current request version. The state moves to Rejected (a terminal state), stopping all further routing and decision activity.
- Request Rework: Unlocks the current request version for editing and places it in Rework Required status, returning ownership to the requester to update data or attach missing evidence.
- Withdraw: Cancels the active request version. The state transitions to Withdrawn (a terminal state), revoking all open reviewer tasks.
- Resubmit: Generates a new version of the request containing the updated fields and submits it back into the In Review state for re-evaluation.
Supersede:Marks a previously open or submitted request version as Superseded upon resubmission, preventing parallel approvals on outdated data.
Keep thresholds and routing rules versioned
Authority changes over time. Version your approval matrices and decision rules with effective dates and change reasons. Store the policy version ID on each decision so any reviewer can see exactly which policy governed the approval at that moment. That record lives in the approval audit trail and travels with the request. These role, threshold, and SoD decisions become enforceable when you encode them in the approval workflow state machine and define precise transition and escalation rules next.
Model the Approval Workflow as a State Machine
Now turn the role model into predictable behavior. A small, explicit state machine makes the process testable, reviewable, and easy to build.
Define a finite set of states for a purchase request:
- Draft: Created or held for editing; not yet submitted for formal review.
- Submitted: Accepted by system; routing and rule checks pending.
- In Review: Actively being evaluated by designated approvers or automated checks.
- Rework Required: Returned to requester for modifications or additional evidence.
- Approved: Internal decision approved; pending writeback to the system of record.
- Rejected: Terminal state; request denied by an authorized decision-maker.
- Withdrawn: Terminal state; requester canceled the submission prior to approval.
- Expired: Terminal state; request timed out per policy without action.
- Closed: Terminal state; approved outcome confirmed and written back to the system of record.
Terminal outcomes: Rejected, Withdrawn, Expired, and Closed. Temporary states like In Review and Rework Required can move back into review after controlled edits and checks. Approved is usually not terminal; it moves to Closed after the downstream system confirms the purchase order or fulfillment.
State transition matrix:
| Transition | Triggering Event | Actor | Required Checks | Audit Event |
|---|---|---|---|---|
| Draft → Submitted | Submit action | Requester | Required fields populated | Submission metadata recorded |
| Submitted → In Review | Routing evaluation | Workflow Service | Approver resolution & SoD | Policy version & path logged |
| In Review → Approved | Final approval recorded | Approver(s) | Authority limits & SoD satisfied | Approver decision & reasons logged |
| In Review → Rejected | Rejection decision | Approver | Rejection stop/continue policy | Rejection rationale logged |
| In Review → Rework Required | Changes requested | Approver | Comment/reason provided | Change notes logged |
| Rework Required → In Review | Resubmission | Requester | Updated fields validated | Diff of edits logged |
| In Review → Expired | SLA timeout | Timer Event | No action taken within window | SLA breach & expiration logged |
| Approved → Closed | ERP writeback confirmation | Integration Service | Matching amount & vendor | External reference ID logged |
| Any Pending → Withdrawn | Withdraw action | Requester | Withdrawal policy check | Withdrawal reason logged |
Sequential versus parallel approvals should follow the decision policy, not a one‑size pattern. Use your decision tables to emit “sequence” (e.g., Level 1 then Level 2) or “parallel” (e.g., Legal and Security at once), and let BPMN gateways enact that path.
Model the flow in BPMN‑style notation:
- Participants: lanes for Requester, Approver(s), Workflow/Integration services, and an Escalation Timer.
- Events: message (submit), timer (SLA), message (ERP confirmation), terminate (Closed).
- Gateways: exclusive (approve vs reject vs rework), parallel (simultaneous reviews), and inclusive if policy allows partial concurrence.
Keep thresholds, routing, and stop/continue logic in a separate, versioned decision‑table layer. The state machine stays stable; the policy can evolve without reworking the process. This also strengthens the approval audit trail because each transition records the policy version used.
Turn Approval Delays Into Explicit Escalation Rules
Your state machine defines where a request can wait. Now make the wait governed. Write approval escalation rules that tell the system when to nudge, when to escalate, and what to do if nobody responds. Treat time like any other policy variable, not a vague SLA.
- Timer definition: For every pending state, define the timer’s start event (e.g., “assignment to Approver A”), business‑calendar basis (business vs. elapsed days), time zone, pause/resume conditions (pause during rework, resume on reassignment), and a timer owner (the service that evaluates it). Use one timer per step; long chains often need step‑specific clocks.
- Reminders that matter: Specify recipients (assignee, backup, requester, or channel), reminder timing (e.g., T+24h, T+48h), and delivery outcome handling (retries, bounce handling, fallback channel). Mark each message as informational or action‑required. If action is required, include a direct action link and record the delivery outcome.
- Escalation target and scope: Name the escalation target (role, group, or named person), its authority scope (what amounts or categories they can decide), and conflict checks (no self‑approval; honor SoD). Decide if escalation reassigns the approver (transfers decision authority) or only raises visibility (adds a watcher/manager). In role‑based approvals, validate that the escalated role actually covers the request’s thresholds.
- Explicit timeout outcomes: Don’t assume a one‑size default. On timeout, choose: escalate (to the next role), expire (move to Expired), controlled fallback (route to a designated approver of last resort), or return for rework (if information gaps block a decision). Each outcome should be a named transition in your approval workflow software design with a clear audit event.
- Calendars, OOO, and delegation: Respect holidays and out‑of‑office. Allow delegation to a valid peer or designated alternate without bypassing authority limits or SoD controls. Record who delegated to whom, the validity window, and what was decided under delegation.
Log every timer start/stop, reminder, reassignment, escalation, and timeout in the approval audit trail with timestamps, actors, reason codes, and time zone. That’s where your evidence lives when questions come later.
Design Rework, Rejection, Withdrawal, and Overrides Without Losing Control
You’ve defined timing and escalation. Now make the “no” and “not yet” paths first‑class in your approval workflow state machine so control doesn’t leak into email or side chats.
Authority and transitions
- Reject: Approvers and required reviewers may move In Review → Rejected with a reason code. This ends the attempt.
- Request rework: Approvers may move In Review → Rework Required, returning ownership to the requester to update data or evidence.
- Withdraw: The requester (or a named business owner) may move any pending state → Withdrawn with a reason. No one else can withdraw.
- Reopen/resubmit: Only the requester may move Rework Required/Rejected/Withdrawn → Resubmitted. Create a new version; don’t overwrite.
- Supersede: When a newer version is submitted, any open Submitted/Pending item moves → Superseded to prevent parallel approvals.
Material Changes Triggering Reassessment
- Financial & Threshold Changes: Modifications to the total purchase amount, currency, or crossing policy threshold limits.
- Risk Classification: Changes to the risk tier, vendor risk profile, or handling of sensitive/customer data.
- Key Business Fields: Updates to the vendor/payee, cost center/GL account, department, contract duration, or funding source.
- Evidence & Documentation: Addition, removal, or revision of required attachments, risk memos, or compliance documents.
- Policy Governance Updates: Changes to the underlying approval routing matrix or policy rules occurring during review.
When any material change occurs, all prior sign-offs on the request are invalidated. The request must be resubmitted using the active role-based matrix, and timers and escalation rules are recalculated.
- Impact of In-Flight Policy Changes
- Policy Version Pinning: Requests already in progress remain pinned to the policy version active at the time of submission unless a material change forces a resubmission.
- Immediate Re-evaluation: If organizational compliance rules mandate immediate application of a new policy version, all active in-flight requests are re-evaluated against the new rule set, invalidating non-compliant prior approvals and re-routing as necessary.
- Preserve the story, don’t rewrite it
- Rework, rejection, withdrawal, supersede, and override must append to the approval audit trail. Record who acted, when, the reason code, fields changed (before/after), policy/rule version applied, and linked evidence. The result is a defensible record you can explain in minutes, not days and a resilient approval workflow software design that won’t buckle under exceptions.
Make Notifications and Audit Evidence Part of the Workflow Design
If your approval workflow software design can’t explain “who decided what, when, and under which authority,” it won’t stand up to scrutiny later. Build the approval audit trail as a first‑class element, not an afterthought.
Start by structuring the record around three anchors:
- Decision object: the thing being approved.
- Chronological event history: every meaningful action in order.
- Control context: the applicable authority model and policy/rule versions at the time.
Each state change in the approval workflow state machine should append an event. That includes initial submission, decisions, transitions, delegations, escalations, overrides, rework, and any integration write‑back to systems of record. Don’t collapse or overwrite; append with attribution.
Capture a consistent, minimal set of fields for every event so you can reason about history and defend it later:
- Request/Object IDs: Stable identifiers for the request and business object.
- Prior and Next State: Exact state names to trace transitions.
- Actor and Effective Authority: Who performed the action and what role/entitlement made it valid (ties to role‑based approvals).
- Action: submit, approve, reject, delegate, escalate, override, rework, withdraw, write‑back, etc.
- Timestamp and Source: When it happened and via which channel (UI, API, integration).
- Outcome/Reason: Result plus reason code and optional free text.
- Evidence Reference: Links to attachments, comments, or data snapshots used in the decision.
- Rule/Policy Version: The active policy or rule set used, including thresholds and approval escalation rules.
- Correlation ID: A trace ID to connect all related events and notifications across services.
Treat notifications as workflow events too. They aren’t side effects; they’re part of the control story and may prove timeliness and due diligence. For every notification, store:
- Recipient: Person, queue, or role.
- Purpose: Request for action, FYI, SLA warning, or escalation.
- Timing: Trigger condition (state change, due‑in, breach) and business calendar.
- Action Path: The link or instruction to act (kept behind auth).
- Delivery Outcome: Sent, failed, bounced, read/open if available (without over‑collecting personal data).
Design messages to minimize sensitive‑data exposure. Include just enough context to act, then link back to the secured app. That’s where the real details live under access control.
Keep business decision history distinct from platform and security logs. Platform logs (auth, sessions, API latency) support operations and security. Decision events explain the business outcome. Link them via correlation IDs, but don’t let one substitute for the other.
Finally, protect the audit store. Use least‑privilege access, append‑only semantics, and monitored administrative paths for corrections. Support retention and legal hold. And don’t claim immutability unless your implementation actually enforces it with appropriate controls.
Connect the Workflow to Systems of Record Reliably
A state machine only works if it can trust the data it reads and writes. Start with a simple contract: for every decision, name the system of record for inputs and the system that’s updated on outcome. Then make the connections boringly reliable.
Map critical elements to a single source of truth: requester identity and employment status (IdP/HRIS); organizational context (department, cost center, manager in HR/finance); budget ownership and spend authority (finance); the approval object (purchase request, contract, access role in its domain system); and the final business record (PO, signed agreement, account change in that same domain).
Use stable identifiers across systems. Issue a request ID at start, reference the business‑object ID, and carry a correlation ID through every call and event. That ties the approval audit trail to the source record during review and reconciliation. Guard retries with idempotency keys and version checks so duplicates don’t appear.
Own the messy middle. Spell out operational responsibilities, not just APIs:
- Failure ownership: Name who monitors integrations and clears exceptions product ops, integrations, or SRE.
- Retry strategy: Define timeouts, backoff, max attempts, and a circuit breaker per dependency.
- Duplicate protection: Use idempotency keys, conditional writes (ETag/If‑Match), and de‑dupe windows for events.
- Reconciliation queue: When states don’t match, land items in a queue with SLAs, context, and a safe re‑drive path.
- State correction: Define who can fix mismatched states (and how), with auditable, role‑based approvals for overrides.
Specify the write‑back authority in your approval workflow software design: the authoritative event (for example, “Approved.Final”), the service or team that performs the update, and the rule when workflow and source‑system statuses disagree. Decide which system wins on conflict and implement auto‑heal to converge.
- Writeback authorization & execution: Writeback is authorized by the Approved.Final event and executed by the Integration Service. To confirm success, the service must collect evidence including the request ID, request version, policy version, decision reference, and idempotency key.
- Pre-writeback verification & timeout safety: Before updating the system of record, verify that the request remains eligible and that material fields have not changed. If a writeback call times out, query the target system for the authoritative outcome before issuing any potentially duplicative update.
- Reconciliation & exception routing: Reconcile status mismatches using source-record version numbers and recorded decision evidence. Automatically repair only predefined, safe discrepancies; route any ambiguous or financially material differences to a designated finance operations owner rather than overwriting statuses merely to force convergence.
Add operational reporting leaders will use: overdue approvals, triggered approval escalation rules, exception queues awaiting action, failed integrations by connector, and reconciliation failures by source system. For a deeper look at designing reliable system connections and controls, see our Order‑to‑Cash Systems Integration Control Blueprint (blog order to cash systems integration control blueprint).
Use a State Diagram and Pre‑Build Checklist Before Implementation
Before engineering picks up tickets, lock your approval workflow software design in a clear state diagram and a pre‑build checklist. That way, roles, states, timers, and source‑system write‑backs are unambiguous and testable.
BPMN‑inspired compact state diagram (text form)
BPMN‑inspired compact state diagram (text form)
Participants: Requester, Manager, Finance Approver, Risk Approver, System (Workflow Engine), System of Record (SoR)
Legend: [State], (Event), {Gateway}, -> transition, (Timer) escalation
(Start) -> (Submit Request by Requester) -> [Submitted] -> {Gateway: Policy & Threshold?}
- Under threshold & clean risk -> [Auto-Approved]
- Else -> [Approval In Progress]
[Approval In Progress] -> {Gateway: Parallel Approvals Needed?}
- No -> [Manager Review]
- Yes -> [Manager Review] || [Risk Review] (parallel)
[Manager Review] -> (Approve) -> {Gateway: More Approvals?}
- -> (Request Changes) -> [Rework Requested] -> (Reject) -> [Rejected] -> (Timer) -> [Escalated to Manager’s Manager]
- Yes -> [Finance Review or Risk Review]
- No -> [Approved]
[Risk Review] -> (Approve/Reject/Request Changes) -> upstream as above -> (Timer) -> [Escalated to Risk Lead]
[Finance Review] -> (Approve/Reject/Request Changes) -> upstream as above -> (Timer) -> [Escalated to Finance Lead]
[Rework Requested] -> (Requester Updates) -> [Resubmitted] -> back to [Approval In Progress] -> (Withdraw) -> [Withdrawn]
[Escalated ...] -> (Approver Acts) -> returns to next required review or [Approved]/[Rejected]
[Override Requested] -> (Authorized Override by Policy Owner) -> [Approved with Override] -> (Denied) -> continue normal path
[Rejected] -> (Write Back to SoR) -> (Notify) -> (End) [Withdrawn] -> (Write Back to SoR) -> (Notify) -> (End) [Approved] or [Approved with Override] -> (Write Back to SoR) -> {Gateway: Write-back Success?}
Yes -> (Notify) -> (End)
No -> [Write-back Failed] -> (Alert Ops) -> (Retry/Manual Fix) -> (End)
Pre‑build checklist (make it executable)
- Decision object: Record type, identifier, versioning, and mutability rules during review.
- Roles & SoD: Approver roles, backups, delegation rules, and separation‑of‑duties constraints.
- Thresholds & policy: Approval thresholds, risk gates, override policy, and effective policy versioning.
- Transitions: Allowed state changes, who can trigger them, and preconditions per transition.
- Terminal outcomes: Approved, Approved with Override, Rejected, Withdrawn, Write‑back Failed.
- Timers & approval escalation rules: SLAs per step, escalation targets, business hours/holidays, and what happens on expiry.
- State diagram details: This diagram shows the main review and approval path. Define withdrawal, supersession, automatic approval, and override transitions separately using the same state names and authority rules. For parallel reviews, specify which decisions are mandatory, what happens after rejection, and how outstanding tasks are canceled or completed. A gateway coordinates branches; the approval policy determines whether the required decisions have been satisfied. Terminal outcomes: Rejected, Withdrawn, Expired, Superseded, and Closed for the current request version. Writeback Needs Recovery remains recoverable; Approved is not terminal when closure requirements remain.
- Exceptions: Rework loops, withdrawal, override, duplicate submission handling, and cancellation on source change.
- Notifications: Who, when, and channel; include escalation, rework, failure, and completion messages.
- Audit fields: Approval audit trail events with actor, role, policy version, state before/after, rationale, evidence links, and correlation IDs.
- Evidence versioning: Retain the evidence version used for each decision. A link to an editable attachment is insufficient if its contents can change after approval. Preserve an approved snapshot or version reference under the applicable access and retention controls.
- Notification tracking & fallback: Distinguish notification creation, dispatch, delivery, and acknowledgment. A delivery receipt or opened message does not establish that the recipient reviewed the request or made a decision. Define which notification outcomes require retries, escalation, or an alternative contact path.
- Integrations: Source‑system read/write, idempotency, retries/backoff, and dead‑letter handling.
- Operational reporting: Aging by state, SLA breaches, override rates, rework rates, and write‑back failures.
Edge‑case tests you must pass
- Self‑approval attempt: Same person as requester and approver is blocked by role‑based approvals and SoD.
- Stale delegation: Delegate expired; action is rejected or re‑routed.
- Out‑of‑office approver: Auto‑forward to delegate; timer continues under business‑hours rules.
- Parallel decisions: One approve and one reject arrive close together; resolve deterministically per policy.
- Material request changes: State rolls back to Resubmitted; prior approvals invalidated.
- Timer expiry: Escalation fires once, not repeatedly; audit shows both timer and escalation events.
- Duplicate events: Idempotent handling prevents double approvals or duplicate notifications.
- Notification behavior: Ensure notification failures trigger appropriate retries and escalate to alternate contacts when undelivered.
- Concurrent actions: Handle simultaneous reviews, approvals, or rejections deterministically without race conditions or state corruption.
- Failed or ambiguous writeback: Workflow holds “Approved” while flagging “Write-back Failed” or “Needs Recovery,” alerting ops and enabling safe reconciliation before retrying.
Acceptance scenarios (write per material path) For each path (auto‑approve, single‑approve, parallel approve, rework, reject, withdraw, override, write‑back failure), verify:
- Expected state
- Authorized actor and role
- Policy version applied
- Emitted approval audit trail event(s)
- Notification dispatched and delivered (or fallback triggered)
- Source‑system outcome (including successful or failed write‑back)
To formalize acceptance and test execution, many teams pair this checklist with a QA plan; see our Software Testing & QA services for structured support (services software testing and qa).
Conclusion
Reliable approval workflows make authority, request versions, and completion conditions explicit. Every decision should apply to identifiable evidence under a recorded policy, and the workflow should distinguish approval granted from an outcome confirmed in the authoritative system.
Start with one approval process. Define its roles, states, escalation rules, exception paths, and writeback recovery, then test the situations most likely to cause confusion: absent approvers, changed requests, conflicting decisions, and uncertain integration outcomes.
- Moltech Solutions Inc. can help turn those decisions into buildable requirements and a bounded first release. Discuss your approval process, integration boundaries, and control requirements with our custom software development team.
- Integrations: Are write‑backs, idempotency, retries, and failure handling defined with system ownership?










