Human-in-the-loop for travel and expense agents
Most trips are in policy. Exceptions need a person.
Your agent books what fits policy on its own and sends each exception to the budget owner's phone.
How do I let an AI travel agent auto approve inside policy and ask a human for exceptions?
Pushary lets an AI travel agent auto approve trips inside policy and ask a human about the exceptions. Your code books the in-policy fare on its own. For an out-of-policy fare, a cabin upgrade or an over-limit claim, the agent asks first. The budget owner gets a notification on their phone. They tap Approve or Deny. You can also ask them to type an instruction instead, like "find a cheaper fare". If nobody answers before the fare expires, the booking does not run and no card is charged.
What needs a yes
The calls that should not be automatic
- bookFlight(itinerary, fareClass)
- A fare above the policy ceiling is the classic exception, and the price may only hold for a few minutes. An approval email sitting in an inbox costs real money here. The fare is gone before anyone reads it.
- upgradeCabin(bookingRef, cabin)
- Cabin rules often turn on facts the agent does not have: how long the flight is, who is flying, whether a client is paying. The rule is often unwritten too. A person settles it in one tap.
- approveExpense(reportId, amount)
- Paying back an over-limit claim is money leaving the company, with no clean undo. It is also the line an auditor asks about later. The record of who approved it matters as much as the answer.
- rebookDisruption(bookingRef, newItinerary)
- A cancelled flight at 6am is when the agent helps most and is watched least. Rebooking into a higher fare to get someone home is usually right. It should still be a person's call rather than a default.
- issueTravelAdvance(employeeId, amount)
- An advance moves cash before any receipt exists, so the usual expense checks after the trip do not apply. The approval is the only check you have.
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.
npm i @pushary/serverimport { createPusharyServer } from "@pushary/server"
const px = createPusharyServer({ apiKey: process.env.PUSHARY_API_KEY! })
async function book(trip: TripRequest, fare: Fare) {
// In policy and under the ceiling: the agent just books it.
if (fare.total <= POLICY.ceilingFor(trip.route) && fare.cabin === "economy") {
return bookFlight(trip.itinerary, fare.cabin)
}
const decision = await px.decisions.ask({
externalId: trip.budgetOwnerId,
type: "confirm",
question: `Approve ${fare.currency}${fare.total} for ${trip.traveller}? Policy ceiling is ${POLICY.ceilingFor(trip.route)}.`,
timeoutMs: 9 * 60 * 1000,
})
if (!decision.approved) return holdForCheaperFare(trip)
return bookFlight(trip.itinerary, fare.cabin)
}Who answers
The approver is not at a desk
The approver is the person whose budget the trip lands on. That is usually a line manager or a cost center owner, not travel operations. Travel teams run the policy, but they do not own the money. Send every exception to a shared travel inbox and it reaches people who cannot say yes. Pushary sends it to the budget owner's phone, and the answer comes back under their name.
We already have an approval step in our booking tool. Why add another one?
Most booking tools do have an approval step. It is usually an email with a link to a portal the approver last opened a month ago. That works for a trip planned three weeks out. It fails for a fare that expires in nine minutes, or a cancelled flight at six in the morning. The trouble is where the approval lands: on a channel nobody is watching when the decision matters. Pushary does not replace your travel policy or your booking tool. It puts the exception on the phone already in the approver's hand, with a deadline. If the deadline passes, the booking does not run. Every answer is saved with who decided and when, and you can export it. If your current step already gets answered inside the fare window, you do not need this.
Worth reading: IRS Publication 463 on travel expense substantiation, GSA per diem rates, the ceiling most US travel policies inherit.
Add it to your product. Your users never make a Pushary account or pay us.
FAQ
Questions, answered
Can an AI travel agent auto approve inside policy and only ask about exceptions?
What happens if the approver does not answer before the fare expires?
Who should approve an out-of-policy trip, travel operations or the manager?
Does this work for expense reports as well as bookings?
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