Overview

Year-to-date (YTD) amounts are running totals per employee, per financial year, accumulated automatically as pay events are accepted by the ATO. The YTD resource lets you pull current totals for any employer + financial year combination without having to sum pay events yourself.

YTD is read-only via the API. Totals are updated automatically when a submission reaches accepted status.

Endpoint

Get YTD for an employer

GET /api/v1/ytd?employer_id=12&financial_year=2026-27

Scopes: ytd:read

Query parameters:

Param Required? Notes
employer_id yes Which employer to fetch YTD for
financial_year no Defaults to the current AU financial year (e.g. 2026-27)

Response: 200 OK

{
  "employer_id": 12,
  "employer_name": "Acme",
  "financial_year": "2026-27",
  "totals": {
    "gross_payment": 284500.00,
    "payg_withholding": 68320.00,
    "super_guarantee": 32717.50,
    "total_hours": 4712.00,
    "employee_count": 4,
    "finalised_count": 0
  },
  "employees": [
    {
      "employee_id": 88,
      "employee_name": "Aria Patel",
      "employee_payroll_id": "EMP-001",
      "financial_year": "2026-27",
      "finalised": false,
      "finalised_at": null,
      "gross_payment": 125320.00,
      "ordinary_time_earnings": 125320.00,
      "overtime": 0.00,
      "bonuses_commissions": 0.00,
      "payg_withholding": 30080.00,
      "super_guarantee": 14411.80,
      "super_salary_sacrifice": 0.00,
      "employer_additional_super": 0.00,
      "reportable_super": 0.00,
      "total_hours": 2080.00,
      "total_super": 14411.80,
      "net_payment": 95240.00
    },
    {
      "employee_id": 89,
      "employee_name": "Marcus Chen",
      ...
    }
  ]
}

Financial year format

Australian financial years run July 1 to June 30. Beeswax STP formats them as YYYY-YY:

Period String
1 Jul 2025 – 30 Jun 2026 2025-26
1 Jul 2026 – 30 Jun 2027 2026-27
1 Jul 2027 – 30 Jun 2028 2027-28

If you don't pass financial_year, we default to the current year based on today's date in the server's timezone (Australia/Sydney).

Per-employee fields

Field Type Notes
employee_id integer
employee_name string Computed
employee_payroll_id string
financial_year string
finalised boolean True if this employee's YTD has been EOFY-finalised
finalised_at string (ISO 8601, nullable) When finalised
gross_payment number
ordinary_time_earnings number
overtime number
bonuses_commissions number
payg_withholding number
super_guarantee number
super_salary_sacrifice number
employer_additional_super number
reportable_super number
qualifying_earnings number Payday Super (from 1 Jul 2026). Running FY total of Qualifying Earnings used as the SG contribution base.
total_hours number
total_super number Computed. Sum of all super components
net_payment number Computed. gross - payg - total sacrifice

Totals block

The totals object aggregates across all employees on the employer for that financial year:

Field Meaning
gross_payment Total gross paid
payg_withholding Total PAYG withheld
super_guarantee Total employer SG contributions
total_hours Total hours paid
employee_count Employees with any YTD rows for this FY
finalised_count Employees whose YTD has been EOFY-finalised

When YTD is updated

YTD amounts are accumulated automatically whenever a submission transitions to accepted status. Specifically, the LodgementService picks up the pay event's items and adds their values to each employee's YTD row for the appropriate financial year. The YTD row is created on the first accepted pay event of the year.

If a submission is rejected or errors, no YTD changes happen — which is correct, because the pay event was never actually lodged with the ATO.

EOFY finalisation

Finalisation is a special kind of pay event that tells the ATO "this employee's YTD for this financial year is final — you can now show it on their myGov". Create a pay event with is_finalisation: true and event_type: "pay_event", lodge it, and the employees in the pay event will have finalised: true set on their YTD row.

Details: Finalisations.

Use cases

End-of-financial-year summary for an employer

curl "https://stp.beeswaxapp.com/api/v1/ytd?employer_id=12&financial_year=2026-27" \
  -H "Authorization: Bearer stp_live_..."

Use the totals object for a 1-line summary, or iterate employees to build an individual payment summary.

Reconciliation against your own payroll ledger

my_ytd = MyPayroll.ytd_total_for(employer_id: 12, financial_year: "2026-27")
ato_ytd = api_get("/ytd?employer_id=12&financial_year=2026-27")[:totals][:gross_payment]

if (my_ytd - ato_ytd).abs > 0.01
  alert("YTD mismatch: mine=#{my_ytd} ATO=#{ato_ytd}")
end

This is the safest way to catch bugs where a pay event succeeded locally but failed to lodge, or vice versa.

Multiple financial years

To get YTD for a previous financial year, just pass the string:

curl "https://stp.beeswaxapp.com/api/v1/ytd?employer_id=12&financial_year=2025-26" \
  -H "Authorization: Bearer stp_live_..."

There's no bulk "give me all years" endpoint. If you need it, iterate: get the current FY, then decrement by 1 year in a loop until you get an empty response.

Caveats

  • YTD is only updated from accepted submissions. Draft and rejected pay events don't contribute.
  • Manual YTD edits aren't possible via the API. For corrections, submit an update_event pay event with the corrected amounts.
  • There's no endpoint to zero out a YTD row. Zeroing YTD is dangerous from a compliance perspective; contact support if you genuinely need it.
  • Financial year strings are case-sensitive. Use 2026-27, not 2026-2027 or FY2627.