Human-in-the-loop for support agents

Your support agent should not issue that refund alone.

The escalation reaches a person on their phone and comes back as an answer, not a ticket in a queue.

How do I add human approval to an AI customer support agent?

Pushary gives an AI support agent one call that reaches a real person and waits for their answer. Wrap the refund, the account change, or the credit in decisions.ask(), and the agent holds until a human approves, denies, or types a replacement. If nobody answers inside your window it fails closed, so an unattended escalation never resolves itself into a payout.

Where it stops

The calls that should not be automatic

issueRefund(orderId, amount)
Money leaving the account is the one support action with no clean undo. A confidence score is not the same thing as a person agreeing to spend it.
applyAccountCredit(userId, amount)
Goodwill credits are where an agent that wants to please the customer gets expensive fastest, and where a policy written in a prompt drifts furthest from the one in the finance spreadsheet.
cancelSubscription(userId)
A cancellation the customer did not clearly ask for is a support failure that surfaces weeks later as a chargeback rather than a reply.
updateBillingEmail(userId, email)
Changing where invoices and password resets land is an account takeover vector, which is why it is usually the step a human is supposed to confirm.
escalate(ticketId, reason)
Handing off is only a handoff if somebody receives it. Most escalation paths assume a person is looking at a console at that moment.

The integration

Two calls inside the step you already have

Wrap the action, not the whole agent. Everything the agent does that is safe keeps running without asking anyone.

npm i @pushary/servertwo calls
import { createPusharyServer } from "@pushary/server"

const px = createPusharyServer({ apiKey: process.env.PUSHARY_API_KEY! })

async function resolveTicket(ticket: Ticket, proposed: RefundPlan) {
  // Small refunds inside policy do not need a person.
  if (proposed.amount <= POLICY.autoRefundCeiling) {
    return issueRefund(ticket.orderId, proposed.amount)
  }

  const decision = await px.decisions.ask({
    externalId: ticket.assignedAgentId,
    type: "confirm",
    question: `Refund $${proposed.amount} on order #${ticket.orderId}? ${proposed.reason}`,
  })

  if (!decision.approved) return replyWithAlternative(ticket)
  return issueRefund(ticket.orderId, proposed.amount)
}

Who answers

The approver is usually not an engineer

In support the approver is a team lead, a duty manager, or the account owner, and none of them live in your admin console. They are on a shift, between calls, or away from a desk entirely. That is why an approval built as an inbox message quietly becomes a six hour delay: the action is correctly blocked, it is just blocked for the rest of the afternoon. Pushary addresses the person by the id you already store for them and reaches the device they are actually carrying, so the decision comes back in the length of a conversation rather than the length of a shift.

Our agent already hands off to a human. Why add anything?

A handoff and a decision are different things. Handing off moves the ticket into a queue and ends the agent's run, so the customer waits for someone to pick it up and start again from the beginning. A decision keeps the run alive: the agent has already gathered the order, the history, and the proposed remedy, and it needs one person to say yes before it finishes the job it was doing. The second shape is faster for the customer and cheaper for you, because nobody re-reads the thread. It only works if the person can answer from wherever they are, and if the call fails closed when they cannot.

Worth reading: LangGraph on interrupts and resuming a paused run.

$99/ month, Partner plan

Embed it in your product. Your users never see a Pushary login or bill.

FAQ

Questions, answered

Put a person on the step that needs one.

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.