Metrics reference
Every figure on the reports page is defined once, here, in the sentence the API sends with the number itself. That is deliberate. A definition retyped on a second page is a second source of truth, and two pages disagreeing about what an exception is costs more trust than not shipping the number at all. Each quoted line below is the exact string the server puts in the payload, and the reports page prints the same string beside the chart.
Read this before you compare two figures, and especially before you assume one of them is the opposite of another.
How to read any rate on this page
A rate is missing rather than zero when there is nothing to divide. If no invoice was decided in a range, there is no compliance percentage — "nothing was due" and "we were late for everything" are different sentences, and the second one is a lie about a quiet week.
Counts always, percentages only when a percentage means something. Below twenty documents the words too few to rate yet stand where the percentage would be, and the counts are shown either way. Three of five is true at any sample. Sixty percent is not, because one more document moves it twenty points.
Every rate is counted over a window you choose, in your own time zone. Buckets are calendar days or weeks cut in your zone, not in the server's.
The invoices that arrived: throughput
Documents received in each bucket, whatever became of them afterwards, and how many of them ever needed a person.
Exceptions
An exception is:
a document that ever entered needs_review or quarantined, from the pipeline verdict or a human status change
Two branches, because the pipeline and a person write different rows. Our rules engine records its own verdict when it routes an invoice, and a person changing a status records another kind of row. Reading only one of the two returns a number that is small, plausible and wrong.
The denominator is:
every document the workspace received in the window, whatever status it holds now and whether or not it turned out to be an invoice — the same population /metrics/throughput divides by, so the two rates cannot disagree
This is a cohort rate, not a queue. It answers "of the invoices that arrived in this range, how many ever needed a person", and it does not move once the range has passed. The older figure on the dashboard is a snapshot of who is waiting right now, which falls as the team works through the backlog — a fast team scores better than a slow team with the same invoices, which makes it a workload gauge rather than a quality one.
By vendor, and the row that must never be deleted
The breakdown includes a Vendor not identified row. It is not a gap in the data waiting to be tidied away: an invoice often lands in review precisely because nobody could tell whose invoice it was. Dropping that row would delete the worst-performing population and shrink the denominator at the same time, so the rate would improve on exactly the workspaces where it should not.
A vendor near the top of that list is not a bad vendor. They are a vendor whose layout our extractor has not learned, or one nobody has written a mapping rule for yet. The list is a work list, not a verdict on somebody else's business.
By reason, and why the blank row is large
review_reason is the reason recorded on the document now, not the reason it was routed at the time; it is written only by the parser, the extractor and the property rules, a quarantine writes none, and the unlabelled bucket therefore mixes documents that never needed a reason with exceptions whose reason was never recorded
Auto-processing rate
of the documents that reached approved or exported in the window, the share carrying no fields_updated audit row that named a material field and no allocation.* audit row by an actor of type user, ever; pressing Approve is a decision rather than an edit and is not a touch, and assigning an invoice to a colleague is routing rather than an edit and is not a touch either
Pressing Approve is a decision, not an edit. A controller who reads an invoice, agrees with every character of it and signs has not corrected the machine, and counting that as a touch would report your approval policy instead of our extraction.
It is not the opposite of the exception rate
this is not one minus the exception rate: an exception is a document the system routed to a person, a touch is a document a person changed, and an invoice reviewed and approved unchanged is both an exception and touchless; the two also count different populations, documents received against documents finished
The two numbers sit on the same screen and they do not add up to one. That is not a defect in either of them. An exception is a document the system routed to a person; a touch is a document a person changed; and they are cut over different populations — one by arrival, the other by arrival at approval or export.
Extraction edit rate
of the documents received in the window that the extractor actually read, the share a person then changed at least once — one or more fields_updated audit rows by an actor of type user that named a material field, so assigning an invoice to a colleague is routing rather than an edit and does not count; the raw edit count ships alongside so an invoice edited nine times is visible rather than counted once
This measures our reading of the invoice, not the invoice. The number that sounds like it in the trade — the share of invoices that contain wrong data — is a statement about your vendor's document. This one is the share where somebody changed what inletAP proposed. Same shape, opposite subject, so we do not borrow the name.
It is also not an accuracy figure, and not only for the naming reason. The audit log stores the value as it stood immediately before each edit, so on a second edit of the same field it holds the previous editor's value rather than the machine's. A field-by-field figure would need the earliest edit per field and is deliberately not reported.
The raw count of field changes travels beside the rate, because a rate counts an invoice fixed nine times exactly once.
Time to approval
ingest (created_at) to the earliest evidence the document reached approved: a status_changed audit row, a satisfied approved audit row, or the last approval decision on a fully decided document
Reported as a median and a p90, in days as well as minutes: every published benchmark in this industry is quoted in days, and a figure in minutes alone cannot be compared with anything you have already read. The clock starts when the invoice arrives at inletAP, which is later than the vendor sent it.
Approval SLA compliance
an approval decision is on time when approvals.decided_at is at or before the document sla_deadline; decisions on documents with no deadline are reported as noDeadline and are excluded from the rate; a split invoice is filed under the property its own approver signed for (approvals.scope_property_id)
This measures our own approval deadline, the one your tiers set. It is not the vendor's payment terms and it is not a statement about anybody being paid on time: inletAP does not move money. A portfolio could sign every approval inside its window and still pay every vendor late.
Decisions on invoices that never carried a deadline are counted separately and are in no rate. They were never late, and folding them in either direction would invent a fact.
The breach ledger is a floor
a lower bound, not a census: the SLA sweep runs every 15 minutes and only sees documents still in needs_review or ready_for_approval, so an invoice that passed its deadline and was approved before the next tick never got a row; the bucket is the day the sweep NOTICED, up to 15 minutes after the deadline actually passed
So the total is written as "at least". It is a lower bound and it is never a census.
Both SLA series also start on the day the product began stamping deadlines and writing breaches down. Earlier days are blank on purpose: they are unmeasured, not perfect.
Outstanding, and the open backlog
Outstanding is what each building owes right now, across every open status, counted over the whole workspace rather than a page of it. A split invoice contributes its own slice to each building and is never counted twice.
The backlog bands the same open queue by age:
open documents (needs_review, ready_for_approval, held_quota) aged in whole calendar days in tz from created_at, which is arrival rather than the start of any approval clock
Ageing is a snapshot, so it ignores the date range above it.
What inletAP does not report, and why
- How long a person spent on an invoice. Nothing in the product records how long anybody had a document open — there is no view event and no timer — so any figure of that kind would be invented rather than measured.
- Throughput per person. The only per-person denominator available is a count of seats, which includes owners, approvers and viewers who process nothing.
- Which individual field we got wrong. See the extraction edit rate above.
- A score for how many duplicates we stopped. Marking an invoice as a duplicate is something a person does, so a count of those marks would be a count of clerical actions rather than of anything the software found.
If you want the underlying rows rather than the summary, the audit log holds every edit with the value before and after it, and exports as CSV.