Product8 min

Designing an approval UI you can decide in under five seconds

Most approval tools optimise for filling in a form. Ours optimise for someone who got pinged, opened the page, and needs to answer 'approve or deny' without reading a manual.

Patrick McCurley
ApproveDeny

The approver is almost never the developer. It is a finance lead, an ops manager, a marketing director, a legal reviewer — someone who got pinged, opened the page mid-interruption, and has maybe twelve seconds of patience before context-switching costs more than the decision itself.

Most approval tools solve the developer's problem and leave the reviewer with whatever falls out. You can see that tradeoff in the two things teams reach for today.

A no-code form builder is not the play

Refund approval request AMOUNT 240.00 CURRENCY USD CUSTOMER ID cus_8821 REASON item_damaged Submit
A no-code form builder gets you this. Same layout for a $5 refund and a $50,000 one.

Drag a few fields onto a canvas, publish, send a link to finance. The reviewer sees a grid of labeled inputs — amount, customer id, reason — and the grid looks identical whether the customer is a first-timer with one complaint or a six-year regular who has never asked for a refund before.

The reviewer can technically decide from this. They also can't, really. No history, no evidence, no shape. Finance shrugs and approves, because denying without context feels worse than approving without it. The form produces decisions, not reviews.

A Slack message is not the play either

# approvals BA billing-agent APP · 2:47 PM Refund request · cus_8821 · $240.00 USD · reason: item_damaged Agent would like a human to approve. Approve Deny
Fast to wire up. Scrolls off in a busy channel. Useless when the reviewer does not live in Slack.

An agent posts to a channel, two buttons appear inline. It works when the approver is an engineer reviewing an engineering action — same medium, shared vocabulary, already in the tool.

It falls apart the moment the approver is not an engineer. A finance lead is not on Slack between meetings. The message arrives, gets pushed up by forty others, and the agent is still waiting three hours later. Slack approvals look free until you look at the pattern of which ones never get decided.

A rich UI is the play

BILLING AGENT · 2.4.1 AWAITING REVIEW Refund $240 to Lila Chen Order #8821 · package arrived damaged · support ticket #4412 LC Lila Chen lila.chen@example.com Member since Feb 2024 Lifetime orders 6 · $1,847 spent Prior refunds 0 requested Woven rattan table lamp SKU LMP-3120 · $199.00 DELIVERED APR 6 EVIDENCE LOG 2 photos + shipping log TIMELINE Apr 1 ordered Apr 4 shipped Apr 6 damage reported Apr 7 ticket opened Apr 8 this approval REFUND BREAKDOWN Item $199.00 Shipping $18.00 Tax $23.00 Total refund $240.00 RECENT SIMILAR DECISIONS Last 8 damage refunds 7 approved · 1 denied Median decision time · 22s Fraud signals · none detected Approve Deny a · d
Same refund. Rendered so the person deciding has everything they need and nothing they don't.

The title says, in plain terms, what is about to happen. Below it, the surfaces the decision actually turns on — who the customer is, what they bought, what went wrong, what the agent has already checked, how similar requests resolved recently, what the money breaks down into. The reviewer reads once and decides.

A form asks the reviewer to assemble a decision from parts. A rich UI assembles the decision for them and asks only yes or no. The shape changes per use case — refund approvals look like refund approvals, deploy approvals look like deploy approvals — because the review surface is generated from a skill integration, not dragged onto a canvas.

Approve and Deny

Two buttons, bottom-right of the card, same place every time. Approve is filled orange. Deny is outlined. No confirmation modal on Approve — the click was the confirmation. A second modal is a tax on a decision the approver already made.

Denial is a sentence, not a dropdown

Click Deny, a one-line input appears, you type the reason in your own words, enter sends it.

Dropdowns give clean analytics. Real denial reasons are almost never one of five things. They are "refund as store credit instead", or "customer already replied, skip this one", or "check with finance before pushing again". The agent's logs should carry those sentences back, not labels borrowed from someone else's taxonomy.

Keyboard

a approves. d denies. j and k move through the queue. The shortcuts match what people guess from Gmail and Vim, which is why we do not ship a cheat sheet.

What we left out

No filters. No bulk select. No tags or custom card fields. Each has been requested. Each would slow the loop.

Bulk approve is the one I think about most. The moment bulk exists, bulk becomes the default, and the gate turns into a rubber stamp. If forty requests really should share one decision, that is a batching call at the submission layer — send one approval for the batch, with a preview that summarizes it.

The tradeoff

Optimizing for speed means the review surface is shallow. Long-term success rates, comment threads, cross-approval comparisons live in the audit log. The audit log is where you investigate. The review surface is where you decide.

Five seconds is not a marketing number. It is what the interruption gives you before the cost of the decision passes the value of the decision itself. The card fits inside that budget, or the gate collapses into a rubber stamp.

Keep reading