Skip to content

n8n: ask for approval before acting (Wait node)

Some things should not happen automatically: a refund, a discount, a social media post. The Wait step pauses the workflow until you decide. n8n sends you a link on Telegram, you open it on your phone, choose Approve or Reject, and the workflow continues with your answer.

Time needed 30 minutes
You need An n8n agent from LusoVPS (Sign in and build your first AI agent), your Telegram bot saved in n8n (step 1 of the contact form recipe) and your numeric Telegram ID. To send a test request, a terminal with curl, as in Receive data with a webhook
Result A refund request arrives, you get Refund request from Rui Costa ... Approve or reject here: (link) on Telegram, and the workflow continues only after you choose

This is the finished workflow:

The finished workflow

Webhook receives the request → Ask for approval sends you the details and a link on Telegram → Wait for my decision pauses until you answer the form behind the link → Approved? checks your answer → Refund approved or Refund rejected (here: a Telegram message; in real life, the action itself, for example an email to the customer).

Anyone with the link can answer

The approval link is not protected by a password. Send it only to yourself (your own Telegram chat), and do not forward it.

1. Receive the request (Webhook)

  1. Create a new workflow and name it, for example Refund approval.
  2. Click Add first step, choose On webhook call and set it:

    The Webhook step after a test

    1. Webhook URLs: the test and production addresses (more about them).
    2. HTTP Method: POST.
    3. Path: refund-request.
    4. Respond: Immediately. Your website gets its answer at once; the decision can come hours later.
    5. After a test (step 6), the OUTPUT shows what was sent, under body: name, amount and reason.

Any other trigger works too: a form, a schedule, an AI step that writes a draft for you to check.

  1. Add a Telegram step after Webhook: search Telegram, choose Send a text message and rename it Ask for approval.
  2. Set it:

    The Ask for approval step after a test

    1. Chat ID: your numeric Telegram ID. (Credential: your Telegram bot.)
    2. Text: click Expression and paste:

      Refund request from {{ $json.body.name }}
      Amount: {{ $json.body.amount }} EUR
      Reason: {{ $json.body.reason }}
      
      Approve or reject here: {{ $execution.resumeFormUrl }}
      

      {{ $execution.resumeFormUrl }} is the link to the approval page of this run. Each run gets its own link.

    3. After a test, the OUTPUT shows ok true: the message was sent.

    4. The text that arrived, with the link (blurred here).

    Also switch Append n8n Attribution off under Additional Fields → Add Field.

3. Pause until you decide (Wait)

  1. Add a Wait step after Ask for approval (search Wait). Rename it Wait for my decision.
  2. Set it:

    The Wait step after a test

    1. Resume: On Form Submitted. The workflow continues when someone sends the form behind the link.
    2. n8n reminds you: The form url will be generated at run time. It can be referenced with the $execution.resumeFormUrl variable. Send it somewhere before getting to this node. That is what step 2 does.
    3. Form Title: Refund request.
    4. Form Description: click Expression and paste:

      {{ $('Webhook').item.json.body.name }} asks for a refund of {{ $('Webhook').item.json.body.amount }} EUR. Reason: {{ $('Webhook').item.json.body.reason }}
      
    5. Form Elements: Field Name Decision, Element Type Dropdown. Under Field Options, add two options: Approve and Reject. Switch Required Field on.

    6. After you answer, the OUTPUT shows your choice: Decision Approve.

Limit Wait Time

Lower in the same panel, Limit Wait Time sets a maximum time to wait for your answer. We did not test it for this guide.

4. Act on the answer (If)

  1. Add an If step after Wait for my decision and rename it Approved?.
  2. Set the condition:

    The Approved? step after a test

    1. First box: Expression {{ $json.Decision }}. Operator: String → is equal to. Value: Approve.
    2. After a test with Approve, the item is in True Branch (1 item).
  3. Click the + at the right of the true exit and add what should happen after an approval. We used a Telegram Send a text message step, Refund approved, with the text (Expression):

    Approved: refund of {{ $('Webhook').item.json.body.amount }} EUR for {{ $('Webhook').item.json.body.name }}.
    
  4. Do the same on the false exit: Refund rejected with Rejected: no refund for {{ $('Webhook').item.json.body.name }}.

5. Test it

  1. Click Execute workflow at the bottom of the canvas. The Webhook waits for one test call.
  2. Send a test request to the Test URL, for example with curl (use your own address):

    curl -X POST https://yourname-n8n.agents.lsvps.net/webhook-test/refund-request \
      -H 'Content-Type: application/json' \
      -d '{"name":"Rui Costa","amount":24.50,"reason":"The cake arrived damaged"}'
    

    The answer is {"message":"Workflow was started"}.

  3. The Telegram message with the link arrives. On the canvas, Wait for my decision is highlighted (1) and the Logs say Waiting (2): the workflow is paused.

    The workflow is waiting

  4. Tap the link in Telegram. The approval page opens (during a test it has the yellow banner This is a test version of your form). Choose your Decision (1) and click Submit (2):

    The approval page

  5. The page says Form Submitted - Your response has been recorded, and the workflow continues. In our test the run took about 36 seconds in total, most of it waiting for us. The approval message arrived on Telegram:

    The Refund approved step

    1. The text with the values from the request.
    2. ok true: Telegram accepted it.
    3. The message that arrived: Approved: refund of 24.5 EUR for Rui Costa.

We ran the test a second time with Sofia Reis and chose Reject: the run went through Refund rejected and Telegram got Rejected: no refund for Sofia Reis.

6. Publish it

Click Publish at the top right, then Publish in the window. Give your website the Production URL of the Webhook (with /webhook/, not /webhook-test/), as in Receive data with a webhook. Every request then sends you its own approval link.

Note

For this guide we tested with Execute workflow only and did not leave the workflow published.

Check that it worked

  • The Telegram message has a link, and opening it shows your approval page with the request details.
  • After Submit, the next steps run: you get the Approved or Rejected message.
  • In Executions, the run is finished (not waiting any more).

Common problems

The link only says: Form Submitted - Your response has been recorded

Someone already answered this request. Each link works once: when we opened a used link again, n8n showed only this message, without the form.

The Telegram message has no link

The text must be an Expression and contain {{ $execution.resumeFormUrl }} exactly, and the Wait step must be set to Resume On Form Submitted.

The test does not start: the webhook answers with an error

Click Execute workflow before you send the test request: the Test URL works for one call after each click. See Receive data with a webhook.

Next steps