Human-in-the-loop for n8n

Pause an n8n workflow until a person taps approve.

One HTTP Request node holds the run open until someone answers on their phone. No bot to build.

The integration

Add it to your n8n agent

Pushary gives an n8n workflow a real approval step. Add an HTTP Request node that POSTs to /api/v1/server/decisions, and the node blocks while the question goes to a phone as a push notification. It comes back with answered and value, and you branch on those with an IF node. The usual n8n answer here is a Telegram or Slack sendAndWait, which means the approver has to be in that chat and you inherit whatever that bot can render. Pushary sends to the person's lock screen instead, addressed by your own user id, and writes every answer to a durable ledger.

POST /api/v1/server/decisionsone HTTP node
// HTTP Request node
// Method:  POST
// URL:     https://pushary.com/api/v1/server/decisions
// Auth:    Header  Authorization: Bearer {{ $env.PUSHARY_API_KEY }}
// Body:    JSON

{
  "question": "Approve a {{ $json.amount }} refund for {{ $json.customer }}?",
  "externalId": "{{ $json.userId }}",
  "type": "confirm",
  "wait": true,
  "timeoutSeconds": 55
}

// Response:
// { "decisionId": "...", "question": "...", "type": "confirm",
//   "status": "answered", "answered": true, "value": "yes",
//   "pollUrl": "...", "expiresInSeconds": 600 }
//
// IF node:  {{ $json.answered && $json.value === "yes" }}

Waits longer than a minute

An HTTP node cannot sit open for an hour, and plenty of approvals take that long. For those, create the decision without blocking and give Pushary a callbackUrl pointing at an n8n Webhook node. The workflow resumes on the signed callback when the person answers, so nothing is holding a connection open in between. Use this for anything a human might sleep on.

webhook resume
// 1. HTTP Request node, fire and forget
{
  "question": "Approve this payout?",
  "externalId": "{{ $json.userId }}",
  "type": "confirm",
  "expiresInSeconds": 86400,
  "callbackUrl": "https://your-n8n.example.com/webhook/pushary-answer"
}
// omit "wait" and the call returns immediately as pending

// 2. Webhook node at that path receives the signed callback:
// { "decisionId": "...", "answer": "yes", "answeredAt": "..." }
//
// Verify the signature header before trusting it, then branch.

Why you need it

n8n pauses the agent. Pushary reaches the human.

n8n already knows how to wait. The Wait node and the sendAndWait operations on Telegram, Slack and Gmail all pause a run. What they do not give you is a decision addressed to a specific end-user who is not in your workspace, a fail-closed default when nobody answers, or a queryable record of who approved what. Pushary is the part that reaches the right person and comes back with an answer you can act on, which matters most when the workflow is doing something on behalf of a customer rather than on behalf of you.

What n8n already gives you

Wait, and sendAndWait on chat nodes

n8n has two native answers. The Wait node pauses a run for a duration or until a webhook arrives. The sendAndWait operations on Telegram, Slack, Gmail and a few others post a message with buttons and hold the execution until someone clicks. For an internal workflow where the approver is already in that Slack workspace, this is the right tool and you should just use it.

native
Telegram node
  Operation: sendAndWait
  Chat ID:   <your ops channel>
  → execution pauses until a button is clicked

Where it stops

  • The approver has to be in that chat. There is no shape of this that reaches a customer of yours.
  • It waits and it does not fail closed. An ignored message is an execution parked indefinitely, not a denial.
  • The record is the chat history. There is nothing to query or export when someone asks who approved a payout in March.

Before you ship it

Things that bite on n8n

The HTTP Request node has its own timeout
A blocking decision node is capped by whatever n8n allows a single HTTP request to take, and the server clamps its own wait near 55 seconds. Anything longer needs the callbackUrl and Webhook node pattern, not a bigger timeout.
Retries can ask twice
If the node retries on error, a second decision is created and the person gets asked again. Pass a stable idempotencyKey tied to the thing being approved so a retry resolves to the same decision.
IF nodes are truthy about missing fields
Check answered before you look at value. If the call errored, or the wait ended with nobody having replied, value is null and a loose comparison can send the run down the approved branch on a decision that never happened. There is no approved boolean in the REST response, that one is computed by the SDKs, so the expression has to be explicit.

How it works

From ask to resume

Connect the phone once, then ask a human from the tool or step that guards the action. The waiting, the delivery, and the record are handled for you.

  1. 01

    Add an API key

    Put your Pushary key in n8n as an environment variable or a header credential. It is one Bearer token, so the generic HTTP Request node is enough and there is nothing to install.

  2. 02

    Connect the approver's phone

    POST the person's id to /api/v1/server/enroll once. You get back a one-tap connect link to send them. They have no Pushary account, no app to install, and no key of their own.

  3. 03

    Drop the decision node where the risk is

    Put the HTTP Request node immediately before the step you want gated: the refund, the outbound email, the delete. It holds the run there until the answer arrives.

  4. 04

    Branch on answered and value

    Feed the response into an IF node testing answered && value === "yes". It is fail-closed, so a timeout or an unanswered question leaves answered false and the risky branch never runs.

A decision is a yes or no confirm, a multiple-choice select, or a free-text input. Every one is stored with its outcome and kept in the audit log.

The Partner plan

Your agent asks your users, not just you

Ship the agent to real users and let each of them approve their own decisions from their phone, under your brand.

$99/ month, every framework included

Your users never see a Pushary login or bill.

Your users answer on their own phones

The externalId is your own id for the end-user. Connect their phone once with a keyless one-tap link, and every approval lands with the right person. No account, no app, no key on their side.

Durable, fail-closed waits

The agent stays open on a durable wait backed by a decisions ledger. If nobody answers in the window you set, the decision comes back denied, so a timeout or a restart never turns into an unapproved action.

Phone-first delivery

Pushary reaches the person on the device they carry: native app push first, then PWA push notifications, then Slack if you route it there. You do not build a delivery pipeline.

Signed webhooks and an audit trail

Every decision is written to a durable ledger you can query and export, and resolved decisions post a signed webhook to your callback URL. You have the record of who approved what and when.

FAQ

Questions, answered

Is there a Pushary node in the n8n community catalogue?
Not yet. You use the built-in HTTP Request node, which is the whole integration: one POST to /api/v1/server/decisions with a Bearer token. Nothing to install and nothing to keep updated.
How is this different from Telegram or Slack sendAndWait in n8n?
Those are the standard n8n answers and they work when the approver is already in your Telegram chat or Slack workspace. Pushary is for when they are not. The question goes to a phone as a push notification, addressed by your own user id, and the person needs no account with us and no app. You also get a fail-closed default and a decisions ledger you can export, which a chat message does not give you.
Can the workflow wait longer than the HTTP node timeout?
Yes. Leave wait off so the call returns immediately as pending, pass a callbackUrl pointing at an n8n Webhook node, and let the workflow resume on the signed callback. The decision stays answerable for its full expiresInSeconds window, so an approval that arrives the next morning still lands. Blocking is capped anyway: the server clamps a waiting request to 55 seconds and hands you a pollUrl for anything longer.
Does this work with the n8n AI Agent node?
Yes, in two shapes. You can put the decision node in the workflow around the agent, gating whatever the agent hands off. Or you can expose it to the agent as a tool with the Call n8n Workflow Tool, so the model itself decides when a human should be asked.
What happens to the execution if the approver never taps anything?
It fails closed. The response comes back with answered false and a null value, so your IF node takes the safe branch and the run continues down it rather than hanging. Because the wait is backed by a durable ledger rather than an open connection, an n8n restart in the middle does not lose the request, and you can still read the outcome later from the pollUrl or the callback.
Can each customer approve their own actions?
That is what externalId is for. Pass your own id for the end-user and the notification goes to that specific person's phone, under your brand, on the Partner plan. One workflow serves every customer without you routing anything by hand.

Let your n8n agent ask a human.

Connect a user with one tap, ask a human with one call, and act on a fail-closed decision. Every decision is saved to a durable ledger you can audit.

Partner plan, $99 a month. Your users never see a Pushary login or bill.