I am planning a Make workflow for creative requests where one step remains intentionally manual. A request would enter through a form, create a review record, and notify a designer. The designer may use a browser tool such as Muse Video to shape a prompt-led video concept, then attach the resulting draft URL to the record. Muse Video is still presented as preview-stage, so I am not assuming a native Make module or public generation API.
The part I need advice on is how to pause and resume the scenario cleanly around human review. My current idea is:
The intake scenario creates a record with a unique request ID and status waiting_for_draft.
A second scenario watches for the draft URL and changes status to waiting_for_review.
The reviewer receives an email or Slack message with approve and revise links.
A webhook records the decision and starts the next branch.
Would you keep this as several short event-driven scenarios, or use one scenario with a data store and scheduled polling? Separate scenarios seem easier to retry, but I am concerned about duplicate webhook submissions and keeping the request state consistent.
I would also like a reliable idempotency pattern. Is storing the request ID plus the last processed status in a Make data store sufficient, or is there a better way to prevent the same approval event from publishing twice?
I am looking for architecture guidance rather than a native integration. Examples from other human-in-the-loop content or approval workflows would be useful.
Decoupling this into separate event-driven scenarios is definitely the right choice. Polling loops in Make get expensive fast (wasting ops) and make error handling messy if something fails mid-loop.
Here is how I structure human-in-the-loop approval flows to keep state consistent and prevent duplicate webhook triggers:
1. Decoupled Scenario Flow
Scenario A (Intake): Form → Create Record (status: waiting_for_draft) → Notify Designer.
Scenario B (Draft Attached): Watch for draft URL → Update Record (status: waiting_for_review) → Send Slack message with interactive approval/reject Webhook links (https://hook.make.com/...&requestId=123&action=approve).
Scenario C (Approval Handler): Webhook → State Guard → Process decision.
2. Idempotency & Race Condition Guard
To stop reviewers from accidentally double-clicking links or submitting duplicate approvals, implement an Atomic Lock right at the start of Scenario C:
Webhook Receives payload:requestId + action.
Fetch Current State: Get record from Make Data Store / DB.
Filter / Router Guard:
IF status is ALREADY approved OR processing_approval → Halt scenario (ignore duplicate trigger).
IF status == waiting_for_review → Proceed.
Immediate Lock (Key Step): Update status to processing_approval IMMEDIATELY, before triggering any heavy downstream API calls.
If the reviewer clicks twice, the second webhook execution hits the filter and dies silently because the status was already mutated to processing_approval.
3. Revisions
If action == revise, update status back to waiting_for_draft and re-notify the designer. Scenario B will pick it up cleanly when the new draft URL is ready.
This keeps operations minimal, isolates errors, and prevents double-processing.
I like the event-driven approach you’ve outlined. Personally, I’d lean toward separating the workflow into smaller scenarios because they’re generally easier to monitor, retry, and maintain over time, especially when human approval is involved.
For idempotency, storing the request ID together with the last processed status in a Make Data Store sounds like a sensible starting point. I’d also consider checking the current status before processing any approval webhook so duplicate submissions can be safely ignored if the request has already moved to the next stage.
I’m interested to see how others handle human-in-the-loop approvals as well, especially for creative workflows where multiple revisions are common.
To build a highly robust, enterprise-grade human-in-the-loop workflow, you should avoid attempting to “pause” or delay a single scenario run (which will hit execution timeouts and waste operations).
The optimal architectural pattern is to split this into two asynchronous scenarios connected by a database (such as Airtable or a Make Data Store) and a Webhook.
Here is how you structure this pattern:
Scenario 1: Intake, Hold & Notify (The “Pause”)
This scenario handles the initial request and halts the automated flow until a human acts.
Trigger: New Form Submission (Form / request enters).
Action: Create Record (Airtable / Make Data Store)
Store all request details.
Set a field called “Status” to: Pending Review.
Action: Generate Review Action Link
If using Airtable, you can use an Airtable Interface with an “Approve” button that triggers a webhook.
There is a dedicated module available for Enterprise customers: Human in the loop.
For non-Enterprise users, the best approach is to split the scenario into smaller ones.
So instead of one huge scenario, create one scenario that processes the data and sends it for manual review, and then a second one that watches for the review being approved.
You can use many tools for that, for example Tally forms if you want to have a form-based human UI, or Airtable. Or even built your human-in-the-loop scenario using webhook and webhook response modules.
Example workflow:
Scenario processes data and created webhook URL with necessary query parameters
Scenario watches for webhook creates by scenario 1 and returns form via webhook response. Form is triggering webhook from scenario 3 once saved.
3rd scernario is triggered by form returned by webhook response in scenario 2.