Reviews routes invoices, bills, payments, payroll, journals, and more through a multi-step approval chain you control. Smart mode catches only the entries that matter; strict mode catches everything. Reject an entry and the books auto-reverse — net-zero impact, full audit trail.
Submitters do not change a single keystroke when Reviews is on. The routing decision is invisible to them — they fill the form, click Save, and Reviews decides what to do.
Sales invoice, purchase bill, payment, receipt, journal voucher, payroll run, credit note, debit note, stock adjustment, vendor advance — Reviews is wired into 12 entry surfaces.
Nothing about creating the entry changes for the submitter. They fill the form, click Save, and the entry posts as normal.
In "Off" mode: no routing — everything posts immediately. Existing behaviour, no change.
In "Smart" mode: an entry routes only if its amount crosses a configured threshold, OR AI detects an anomaly (3× the baseline for this vendor, duplicate likely, first transaction with a new party), OR a strict chain is configured for that trigger.
In "Strict" mode: every entry from non-owner staff routes — regardless of amount.
The underlying journal entry stays in the books but is marked as "Awaiting review." List pages render a yellow pill so anyone looking at the invoice / bill / voucher knows it has not been blessed yet.
If the review is approved, the hold flag is cleared and the entry behaves like any other posted item. If rejected, a counter-JE is posted that nets the original to zero — your books stay balanced and both rows survive in the audit trail.
In-app bell — the OnGravy notification bell shows a high-priority entry with a tap-through to the audit detail.
Email — Resend-powered transactional email goes to every current-step approver (for amounts ≥ ₹50,000 by default, configurable).
WhatsApp — for businesses with Meta credentials configured, an interactive message with the link.
Mobile push — Expo app surfaces the entry in the Reviews queue with pull-to-refresh.
Every review can be approved, sent back for changes, or rejected outright. Each has a different downstream effect. Keyboard shortcuts (J/K to navigate, A to approve, R to request changes, X to reject) make a busy queue tractable.
One click (or one J/K/A keyboard tap from the queue). Approve advances the review to the next step in the chain. If there is no next step, the held flag is cleared and the entry posts to the GL.
For chains with `all_must_approve = true`, the review only advances when every required approver at the step has approved. Until then it stays at the current step.
A reviewer who needs the submitter to fix something clicks "Request changes." A required comment field opens — explain what needs to change, then submit.
The submitter gets a high-priority notification with the comment and the entry sits in "Changes requested" status. They edit the underlying entry on the original form, then come back to /dashboard/reviews/mine and click "Resubmit" — which sends the review back to step 1 for a fresh look.
Terminal NO. Reviewer clicks Reject, fills in the required comment, and submits. The review is closed.
The system automatically posts a counter-JE that reverses the original — net effect on books is zero. The original JE stays in the audit trail with the rejection reason; the parent entity (invoice / bill / etc.) flips to status = cancelled.
The submitter gets a high-priority "rejected" notification with the reviewer's reason.
Submitters are not locked out while a review runs. They can chase up stuck items, withdraw before approval, or respond to a changes-requested decision.
/dashboard/reviews/mine lists every entry you have submitted in the last 90 days. Each row shows the trigger type, amount, current status pill, and (for in-flight items) which approver is holding it up.
On mobile, the same view is at the "My submissions" Home shortcut.
Changed your mind before the reviewer got to it? Click "Withdraw." A confirm dialog asks for an optional reason; the review closes, the underlying entry is reversed, and your reviewers get a notification telling them the row is gone (so it does not just ghost-disappear from their queue).
Withdrawal works only while the review is still "Pending" or "Changes requested." Once a reviewer has decided, the audit log is final.
If a reviewer requested changes, edit the underlying entry (invoice / bill / voucher) on its original form. Then return to /dashboard/reviews/mine or the audit detail page and click "Resubmit."
You can attach a note explaining what you changed — it shows on the audit timeline so the reviewer sees your response. The review resets to step 1 and notifications re-fire to the original approvers.
Owners and admins configure modes, chains, and delegations per business. A CA firm running 30 clients can run different modes for different clients — no shared global config.
/dashboard/settings/reviews — three cards for Off / Smart / Strict. Toggle is owner/admin only and applies per-business (so a CA firm can run different modes for different clients).
/dashboard/settings/approval-chains — define one or more chains per trigger (invoice / bill / payment / journal / payroll) with a threshold amount and an ordered list of steps. Each step can target a specific user OR a role (e.g. "any user with accountant role"). Mark all_must_approve when you want every approver at the step to vote.
Chain edits never affect in-flight reviews. Each review snapshots the chain at the moment it was created, so a chain change today does not retroactively rewire reviews submitted yesterday.
Same screen, "Delegations" tab. An approver going on leave can route their approvals to a colleague for a date window. The delegate sees the original's queue items + can act on them; both get the bell when something arrives. The audit trail records "acting for X" on every delegated decision.
/dashboard/reviews/insights — overall approval rate, decision latency, oldest-pending age, and bucketed totals by business / submitter / trigger / status. Window picker (7 / 30 / 90 / 180 days).
For CA firms: the page calls out the highest-rejection-rate client when sample size ≥ 5, so you spot a bookkeeper-training problem before the next audit.
Insights → "↓ Export CSV" produces an RFC-4180 CSV with every decision in the selected window. One row per review, with the full actor::decision::comment trail in a single cell so the audit pack survives a CSV transport.
Indian Companies Act 2013 (post-2023 amendments) requires a tamper-evident audit trail of approvals. The CSV satisfies the "produce the trail on demand" obligation; the underlying append-only `approval_step_actions` table is what makes it tamper-evident.
Every state transition fires a notification to the right person. Both submitters and reviewers stay in the loop without anyone having to chase status manually.
Optimistic-lock token on every state transition. Two reviewers clicking Approve at the same instant — only one wins; the other sees "this review was updated by someone else, refresh."
Unique (instance, step, user) constraint on the audit log. A double-click is silently de-duplicated rather than producing two duplicate audit entries.
Each review snapshots its chain at submit time. A chain edit today never retroactively changes the reviewers for a review submitted yesterday.
Auto-reverse posts a counter-JE that nets the original to zero. Reports compute correctly with both rows present; the audit trail preserves the rejection reason.
When a review is approved / rejected / withdrawn, every unread "needs your review" notification pointing at it is marked read. The bell stops flagging items you no longer need to look at.
canActOnInstance re-checks the user's role at decision time. If you were demoted between getting the bell and clicking Approve, the action is rejected — you cannot approve as a role you no longer hold.
New businesses default to "Off" — Reviews is opt-in. Once enabled, the first review fires the moment an entry crosses your threshold.
Start free — set up Reviews in 2 minutes →