If payroll runs somewhere other than OnTime, this is the integration you need: a month of day records, per employee, in whatever shape your payroll system imports.
What you are pulling
GET /api/public/v1/attendance?date=YYYY-MM-DD returns one date, all employees:
There is no date-range endpoint. A month means 28–31 requests, one per date. At 600 requests per minute this is comfortable, but do it sequentially with a small delay rather than firing thirty concurrent requests.
Timing matters more than the code
Only export closed days. A day is finalized by the nightly close, which runs after the day is over. Crucially, Absent is never written to a day still in progress — so exporting a month that includes today under-counts absences silently.Export a completed month, and do it at least a day after the month ends.
Better still, export after the OnTime payroll cycle for that month has been frozen. A frozen day cannot re-derive, so your export is reproducible: re-running it produces the same numbers.
The script
Getting the paid-days rule right
The aggregation above treats everything except Absent as paid. That is the common case, but check it against your payroll rules:
The unpaid-leave gap is the one to design around. status: "Leave" covers both paid leave and Loss of Pay, and the public attendance endpoint does not expose the leave type.If unpaid leave types are in use, this export will over-count paid days. Either restrict LOP handling to OnTime’s own payroll, or reconcile against leave data pulled separately.
There is also a known boundary quirk in how the last calendar day of a month is captured by OnTime’s own attendance-window query. Spot-check month-end totals against a day report the first time you run this.
Making it repeatable
Export after the month is frozen
Reproducible numbers.
Store the raw daily responses, not just the summary
When payroll disputes a figure, you want the day it came from.
Re-export rather than accumulate
An approved regularization rewrites a past day. A monthly re-read picks that up; a running daily total does not.
Subscribe to regularization.approved
So you know a past day changed and can re-export that month. See Events.