Human-in-the-loop for finance agents

Money moves when a person says so.

The approver signs off from their phone, your agent waits for them, and you keep the record without building one.

How do I put a human approval step in front of an AI finance agent?

Pushary puts a human approval step in front of an AI finance agent with one call. Add it before the payment run, the journal entry or the write-off. The named approver gets a notification on their phone and taps Approve or Deny. Your agent waits for that answer. If time runs out, the money does not move. Every answer is saved, so you can show who authorized each payment when someone asks.

What needs a yes

The calls that should not be automatic

executePaymentRun(batchId)
A batch payment is many actions you cannot undo, packed into one call. One wrong payee in a run of 200 is still money gone. That makes it the worst thing to leave to a confidence threshold.
postJournalEntry(entry)
An entry posted to a closed or nearly closed period is the kind of fix that turns into a restatement conversation.
writeOffBalance(accountId, amount)
Writing off a receivable is a judgment about whether it will ever be paid. The agent has the aging report. The controller has the context.
changeVendorBankDetails(vendorId, iban)
This is the exact step invoice fraud targets. That is why the manual version already needs a second person to confirm it through a separate channel.

The code

One call 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.

bash
pip install pushary
one call
import os
from pushary import PusharyServer

px = PusharyServer(api_key=os.environ["PUSHARY_API_KEY"])

def run_payments(batch, approver_id):
    total = sum(p.amount for p in batch.payments)

    decision = px.decisions.ask(
        external_id=approver_id,
        type="confirm",
        question=(
            f"Release {len(batch.payments)} payments totalling "
            f"{total:,.2f} {batch.currency}? Largest: {batch.largest.payee}."
        ),
    )

    if not decision["approved"]:
        return hold_batch(batch, reason="not approved")
    return execute_payment_run(batch.id)

Who answers

The approver is not at a desk

The approver is a controller, a finance director or the owner. Finance already expects a second person to confirm before money leaves, so nobody needs convincing. They push back on tools that make that person a bottleneck. Approvals in a portal get done once a day, in a batch. A payment run held for a day hurts the people waiting to be paid. Pushary reaches the approver's phone instead.

Finance already has approval workflows. Why would we add another?

You would be giving the agent a way to use the one you have. Your current approvals assume a person started the transaction and will come back to a screen to release it. An agent that builds the payment run itself has neither. It needs a call it can wait on, a timeout that means no, and a record that ties each release to a named person. Building that yourself means a poller, somewhere to keep pending requests across restarts, and an evidence store. Then you keep all three correct as finance changes who approves what. Pushary is that plumbing. Your existing approval matrix still decides who gets asked.

Worth reading: PCAOB auditing standards.

$99/ month, Partner plan

Add it to your product. Your users never make a Pushary account or pay us.

What the Partner plan covers

FAQ

Questions, answered

Can we require two different people to approve the same action?
Yes. Ask twice, with two different user ids, and act only when both come back approved. Each ask is its own request with its own saved record. So you get two approvals, each tied to one person, rather than one record with two names on it.
Does Pushary see our transaction data?
Only what you put in the question. We recommend a summary and a reference rather than the underlying records. A question like "Release 42 payments totalling 18,400.00 EUR?" gives the approver enough to decide. That keeps the saved record a log of answers instead of a copy of your finance system. Pushary stores the request and its answer.
What is the record we can hand to an auditor?
One saved row per request. It holds the question as the approver saw it, the answer, the person and the time, and you can export it. Pushary keeps it for your plan's history window: 90 days on Partner Launch, 365 on Partner Growth. Add a callback URL and each answer is also sent to your server as a signed webhook, so you can copy it into whatever your auditors already read. We are GDPR-aligned and hold no SOC 2 or ISO certification, and we will not claim one.
Can the amount that needs approval be different per entity?
Yes, because the threshold lives in your code, where your approval matrix already is. Anything under the limit runs untouched. Anything over it asks the person your matrix names for that level, by their user id.

Put a person on the step that needs one.

Connect a user once, ask with one call, and run the action only on a yes. Every answer is saved.

Start free