Skip to content

Payslip data schemas

Set schema to au.payslip.v2 and send the payslip data in payslip_non_pii. The schema is closed to undocumented fields, but some defined fields accept printed strings. Closed does not mean free-text-free or guarantee that values contain no personal data. Your integration must keep employee PII out of every non-PII field; the API does not detect PII in accepted string values.

  • ✓ Send each field that your payslip shows.
  • ✓ Send each amount, rate and quantity as a decimal string. Refer to Amounts, rates and quantities.
  • ✓ Send currency on each payslip. Refer to Currency.
  • ✓ Keep personal data out of every field. Send the employee name, the address and the bank details in the encrypted PII.
  • ✓ Write each date as YYYY-MM-DD.

A payslip in New Zealand uses nz.payslip.v2, which has a different field list. Refer to the nz.payslip.v2 schema.

The code sets below use the ATO Single Touch Payroll Phase 2 categories.

Send each amount, rate and quantity as a JSON string that contains a plain decimal number.

An amount
"gross": "3600.00"
  • ✓ Use digits and a decimal point. Put a minus sign at the start of a negative value.
  • ✓ Do not send a thousands separator, currency symbol, bracket, unit, plus sign or exponent.
  • ✓ Send a string, not a JSON number.
  • ✓ Any number of decimal places is valid. The API stores the string as you send it. "1.50" and "1.5" are different values.
  • ✓ Every field accepts a negative value, hours and quantities included.

The SDKs check the format of each number before they send the request.

From the printed payslip to the string
printed send
$3,600.00 "3600.00"
3,600.00 "3600.00"
(123.45) "-123.45"
NIL "0.00"
- "0.00"
76.00 hrs "76"
12% "12"
47.3684 "47.3684"

Send a nil line as zero, for example "0.00".

A rate of four decimal places, and a nil line
{
"period_start": "2026-03-21",
"period_end": "2026-04-03",
"payment_date": "2026-04-04",
"currency": "AUD",
"gross": "3600.00",
"paygw": "752.00",
"net": "2848.00",
"hourly": {
"ordinary_rate": "47.3684",
"hours": "76",
"amount": "3600.00"
},
"earnings": [
{
"type": "ordinary",
"units": "76",
"rate": "47.3684",
"amount": "3600.00"
},
{
"type": "overtime",
"amount": "0.00"
}
]
}

Send currency on each payslip. Use the three-letter alphabetic code of the payslip currency, for example AUD or NZD. Write the code in capital letters.

The API accepts each current ISO 4217 currency code. It does not accept fund codes or codes that have no minor unit, for example XAU, XTS and XXX. SIX, the ISO 4217 maintenance agency, publishes the list on its data standards page.

The currency does not set the number of decimal places in an amount.

These mistakes put a correct figure in the wrong field.

Send PAYG withholding in paygw, also when the payslip prints it under “Deductions”. deductions[] is for post-tax deductions only.

A payslip that prints tax under Deductions
Gross 3,600.00
Deductions
PAYG withholding 752.00 -> paygw: "752.00"
Health fund 45.50 -> deductions: [{ type: "other_post_tax", amount: "45.50" }]
Net 2,802.50

gross is the gross before salary sacrifice. Send the gross after salary sacrifice as taxable_gross.

Which number goes where
Gross (before sacrifice) 3,600.00 -> gross: "3600.00"
Salary sacrifice to super 200.00 -> salary_sacrifice[].amount: "200.00"
Taxable gross (printed) 3,400.00 -> taxable_gross: "3400.00"

Send the number only. Remove the currency symbol, the separators and the unit.

Send a plain decimal string
"gross": "3600.00" valid
"gross": "$3,600.00" rejected: no currency symbol
"gross": "3,600.00" rejected: no thousands separator
"gross": 3600.00 rejected: send a string

The schema has no field for a pay-code name. Map each pay code to its STP category, for example “Salary” to ordinary. If a pay code has no category, refer to Itemising earnings.

The record contains no pay-code names
"Salary" -> { type: "ordinary", amount: "3040.00" }
"Time and a half" -> { type: "overtime", amount: "240.00" }
"Tool allowance" -> { type: "allowance", allowance_type: "tools", amount: "40.00" }
"Annual Leave Taken" -> { type: "paid_leave", leave_type: "other_paid_leave", amount: "280.00" }

If the API rejects a payload, it returns VALIDATION_FAILED and lists the applicable fields in field_errors. The table shows each message from the payslip schema and the usual cause of that message.

MessageUsual cause
Unrecognized key: “…”The payload contains a field that is not in the schema. The schema is closed. Remove the field. A leave balance, a fund name and an award code each cause this message.
Invalid discriminator value. Expected ‘paid_leave’ | ‘allowance’ | …The payload contains a pay-code name in the earnings type field. Map the pay code to one of the nine types.
must be a decimal number, for example 1234.56An amount, rate or quantity is empty, or it contains a separator, a currency symbol, a bracket, a unit or a word. Send a plain decimal string.
Invalid input: expected string, received numberAn amount, rate or quantity is a JSON number. Send it as a string.
Invalid input: expected string, received objectAn amount, rate or quantity is an object. Send it as a string.
Invalid input: expected string, received undefinedA required amount is missing, for example net. Add it.
Too small: expected string to have >=1 charactersA text field, for example award, is an empty string. Send the printed text, or remove the field.
currency must be an ISO 4217 currency codeThe currency field is missing, or it does not contain an accepted ISO 4217 code. Send a code such as AUD or NZD.
USI must be a fund ABN plus 3-digit product suffix (14 digits) or a SPINThe usi field contains an 11-digit ABN. Send contributions to a self-managed fund with no fund identifier.
period_end must not be before period_startperiod_end is before period_start. Examine the two dates.
other_category is required on an ‘other’ allowanceAn allowance of the type other has no descriptor. Select one of the six other_category values.
other_category applies only to allowance_type ‘other’The payload contains a descriptor on an allowance that is not of the type other.
<field> must be YYYY-MM-DDThe date is not in ISO format, or the date does not exist. The API rejects 2026-02-31 and 31/03/2026.

Each payslip requires these fields.

FieldTypeMeaning
period_enddateLast day of the pay period (YYYY-MM-DD). Must not be before period_start when you send it.
payment_datedateThe day the employee is paid.
currencystringThe ISO 4217 code of the payslip currency, for example AUD. Refer to Currency.
grossdecimal stringTotal gross before salary sacrifice, as Single Touch Payroll Phase 2 reports it.
paygwdecimal stringPAYG withholding. Its own field, never also a deductions line.
netdecimal stringNet pay, as shown on the payslip.

A payload that contains only the core fields is valid. Use it only for a payslip that shows no other data.

A minimal payslip_non_pii
{
"period_end": "2026-04-03",
"payment_date": "2026-04-04",
"currency": "AUD",
"gross": "3600.00",
"paygw": "752.00",
"net": "2848.00"
}

Send each of these fields that your payslip shows.

FieldTypeMeaning
period_startdateFirst day of the pay period (YYYY-MM-DD).
ytd_grossdecimal stringYear-to-date gross across the financial year, including this pay run.
ytd_paygwdecimal stringYear-to-date PAYG withholding, including this pay run.
pay_frequencyenumOne of weekly, fortnightly, monthly or quarterly.
employment_basisenumSTP2 employment basis. Independent of engagement_type.
engagement_typeenumOne of permanent or fixed_term. A Fair Work notion with no STP2 counterpart.
awardstringThe award or agreement line as your payslip prints it.
hourlyobjectThe ordinary rate, hours and amount. Send this object when the employee is paid hourly.
annual_ratedecimal stringThe annual rate, when the employee is paid one.
taxable_grossdecimal stringThe post-sacrifice taxable gross.
stsl_withholdingdecimal stringThe HELP/STSL component printed on the payslip. Already inside paygw.
earningsarrayItemisation of gross.
salary_sacrificearraySalary sacrifice lines. Each line has a type and an amount, and can have a year-to-date amount.
deductionsarrayPost-tax deduction lines. Each line has a type and an amount, and can have a year-to-date amount.
superannuationarraySuperannuation contribution lines. Each line has a contribution type and amount. It can also have a rate, year-to-date amount and USI.
reimbursementsdecimal stringNon-taxable reimbursements. Not part of gross.
ytdobjectFurther year-to-date totals: taxable, super, non_taxable, post_tax_deductions, reimbursements.

Send the award or agreement line as the payslip prints it, with the classification, as one string.

Examples of a printed award line
"Clerks - Private Sector Award 2020 Level 3"
"Manufacturing and Associated Industries Award 2020 C10"
"Acme Pty Ltd Enterprise Agreement 2024"
"Award free"

Keep personal data out of this field. An agreement title contains the name of the employer. It must not contain the name of the employee.

Map your existing Single Touch Payroll Phase 2 categories to the accepted values below. PAYG withholding has its own field. deductions[] contains post-tax deductions only.

Each earnings[] line has a type and an amount. A line can also contain units, rate and ytd_amount. Two types have an additional code. A line cannot contain the additional code of the other type.

Send the number without the unit, for example "76" for 76.00 hrs. The schema has no unit field.

typeMeaning
ordinaryOrdinary hours.
overtimeOvertime.
bonus_commissionBonuses and commissions.
directors_feesDirectors’ fees.
lump_sumLump sums, including termination pay.
return_to_workReturn-to-work payments.
otherA pay code that has no other type. Use it only when no other type is correct.
paid_leavePaid absence. Carries a leave_type from the leave set below.
allowanceAllowance. Carries an allowance_type from the allowance set below.

Use these values in leave_type on a paid_leave line.

leave_typeSTP2 codeMeaning
cash_out_in_serviceCLeave cashed out while still employed.
unused_on_terminationUUnused leave paid out on termination.
paid_parentalPPaid parental leave.
workers_compensationWAbsence paid under workers compensation.
ancillary_defenceAAncillary and defence leave.
other_paid_leaveOThe ATO general code: annual, personal, long service, RDO, TOIL, and each other paid absence.

ATO reference: STP Phase 2 reporting quick reference guide

Use these values in allowance_type on an allowance line.

allowance_typeSTP2 codeMeaning
cents_per_kmCDCents-per-kilometre allowance.
award_transportADAward transport payments.
laundryLDLaundry allowance.
overtime_mealMDOvertime meal allowance.
travelRDTravel allowance.
toolsTDTools allowance.
tasksKNTask allowance.
qualificationsQNQualification allowance.
otherODThis type requires other_category. No other type accepts other_category.

Send other_category on each allowance of the type other. Use a value below. The API rejects other_category on other allowance types.

other_categorySTP2 codeMeaning
home_officeH1Home office costs.
non_deductibleNDNon-deductible amounts.
transport_faresT1Transport fares.
uniformU1Uniform costs.
private_vehicleV1Private vehicle use.
generalG1The general descriptor.

ATO reference: Allowances

An 'other' allowance line
{
"type": "allowance",
"allowance_type": "other",
"other_category": "home_office",
"amount": "80.00"
}

These types are for post-tax deductions only. PAYG withholding is not a deduction.

typeSTP2 codeMeaning
union_professional_feesFUnion and professional association fees.
workplace_givingWWorkplace giving.
child_support_deductionDChild support deduction.
child_support_garnisheeGChild support garnishee.
other_post_taxAny other post-tax deduction, for example a health fund or a social club.

ATO reference: Other components of your STP reporting

The type field accepts super or other.

These types are for employer contributions only. Send a post-tax contribution from the employee as a deduction (other_post_tax), and not as a superannuation line.

contribution_typeMeaning
superannuation_guaranteeSuperannuation guarantee contributions.
rescReportable employer superannuation contributions.
salary_sacrificeSacrificed superannuation contributions.

Send engagement_type (permanent or fixed_term) in its own field.

employment_basisSTP2 code
full_timeF
part_timeP
casualC
labour_hireL
voluntary_agreementV
death_beneficiaryD
non_employeeN

ATO reference: How to report employment and tax information

The pay_frequency field accepts weekly, fortnightly, monthly or quarterly.

Send an earnings line for each pay code on the payslip. The lines itemise gross. They do not add to it.

Send all of the earnings lines, or none of them. The record cannot show that a line is missing.

If a pay code has no category, send it as a line of the type other. Use other only when no other type is correct.

Use the standard code sets for termination pay. There are no ETP or lump-sum sub-codes:

The earnings on a termination payslip
[
{
"type": "ordinary",
"amount": "3000.00"
},
{
"type": "paid_leave",
"leave_type": "unused_on_termination",
"amount": "4000.00"
},
{
"type": "lump_sum",
"amount": "5000.00"
}
]

A superannuation line can contain usi, or no identifier. The schema has no field for a fund ABN and no field for a fund name.

  • ✓ usi is an APRA-product Unique Superannuation Identifier: the fund ABN with a 3-digit product suffix (14 digits), or a SPIN such as STA0100AU. It does not accept an 11-digit ABN.
  • ✓ A 14-digit usi starts with the fund ABN, so the schema has no separate fund_abn field. A record that contains one is rejected.
  • ✓ A self-managed fund has no USI. Send its contributions with no fund identifier.

Send each year-to-date figure that your payslip shows. There are three places for a year-to-date figure:

  • ✓ ytd_gross and ytd_paygw hold the two principal totals.
  • ✓ ytd_amount on an earnings, salary_sacrifice, deductions or superannuation line holds the figure for that line.
  • ✓ The ytd object holds the further totals: taxable, super, non_taxable, post_tax_deductions and reimbursements.

Each year-to-date figure includes the pay run that you register.

The schema does not contain these fields. The API rejects them. Remove them from your payload.

Not in the schemaWhy
Leave balancesThe schema has no leave-balance field.
Super fund namesIdentify a fund with a usi, or send no identifier.
Employee names, addresses and bank detailsSend personal data in the encrypted PII payload.
Award codes and classification levelsSend the printed line as award.
Income stream types, tax treatment codesThe schema has no field for these.
ETP and lump-sum sub-codesSend termination pay as a lump_sum line.

This fortnightly payslip shows hourly pay, an allowance, paid leave, salary sacrifice to superannuation, a post-tax deduction and a reimbursement.

payslip_non_pii
{
"period_start": "2026-03-21",
"period_end": "2026-04-03",
"payment_date": "2026-04-04",
"currency": "AUD",
"pay_frequency": "fortnightly",
"gross": "3600.00",
"taxable_gross": "3400.00",
"paygw": "752.00",
"net": "2682.50",
"ytd_gross": "43200.00",
"ytd_paygw": "9024.00",
"earnings": [
{
"type": "ordinary",
"units": "76",
"rate": "40.00",
"amount": "3040.00",
"ytd_amount": "36480.00"
},
{
"type": "overtime",
"units": "4",
"rate": "60.00",
"amount": "240.00"
},
{
"type": "allowance",
"allowance_type": "tools",
"amount": "40.00"
},
{
"type": "paid_leave",
"leave_type": "other_paid_leave",
"amount": "280.00"
}
],
"salary_sacrifice": [
{
"type": "super",
"amount": "200.00"
}
],
"deductions": [
{
"type": "other_post_tax",
"amount": "45.50"
}
],
"superannuation": [
{
"contribution_type": "superannuation_guarantee",
"amount": "398.40",
"rate": "12",
"usi": "STA0100AU"
},
{
"contribution_type": "salary_sacrifice",
"amount": "200.00"
}
],
"reimbursements": "80.00",
"employment_basis": "full_time",
"engagement_type": "permanent",
"award": "Clerks - Private Sector Award 2020 Level 3",
"stsl_withholding": "120.00",
"hourly": {
"ordinary_rate": "40.00",
"hours": "76",
"amount": "3040.00"
},
"annual_rate": "93600.00",
"ytd": {
"taxable": "40800.00",
"super": "4780.80",
"non_taxable": "960.00",
"post_tax_deductions": "546.00",
"reimbursements": "960.00"
}
}

au.payslip.v2 will not change. A new field or a changed field gives a new schema id, au.payslip.v3. Records that you register with v2 stay valid, and a lender can still verify them.

The API also accepts au.payslip.v1 and nz.payslip.v1. v1 uses integer minor units and a different field list. If you send v1 today, refer to Migrate to the v2 payslip schemas.

The single registration endpoints accept each supported schema id. The schema field selects which schema applies to your payload. Batch registration examines the schema id of each record. An unsupported version fails that record only, and not the full batch.

Set schema to nz.payslip.v2 and send the payslip data in payslip_non_pii. The schema is closed to undocumented fields, but accepts printed strings. Your integration must keep employee PII out of every non-PII field; the API does not detect PII in accepted string values. Put identifying information in the encrypted PII payload instead.

  • ✓ Send each field that your payslip shows.
  • ✓ Send each amount, rate and quantity as a decimal string. Refer to Amounts, rates and quantities.
  • ✓ Send currency on each payslip. Refer to Currency.
  • ✓ Send tax_code, pay_cycle and employment_type as printed text. Send what the payslip shows. Do not map these values to a code set.
  • ✓ Write each date as YYYY-MM-DD.

The earnings, allowance and deduction code sets below use the Inland Revenue Employment Information categories.

Source: Inland Revenue, Payday filing

These mistakes put a correct figure in the wrong field.

Do not map paid family violence leave to a leave type. The schema has no code for it, and you must not put it in other_paid_leave. Include the amount in ordinary pay.

A payslip with paid family violence leave
Ordinary hours 2,400.00
Family violence 600.00 -> earnings: [{ type: "ordinary", amount: "3000.00" }]
Gross 3,000.00 (one ordinary line of 3,000.00, with no leave line)

2. Each statutory deduction has its own field

Section titled “2. Each statutory deduction has its own field”

PAYE, student loan, child support, KiwiSaver and ESCT each have their own field. deductions[] holds the other post-tax deductions.

A payslip that prints everything under Deductions
Gross 3,000.00
Deductions
PAYE 660.00 -> paye: "660.00"
Student loan 100.00 -> student_loan: "100.00"
KiwiSaver 3.5% 105.00 -> kiwisaver_employee_deduction: "105.00"
Child support 50.00 -> child_support: "50.00"
Health fund 35.00 -> deductions: [{ type: "other_post_tax", amount: "35.00" }]
Net 2,050.00

Send paye on every payslip. Send "0.00" when the pay has no PAYE.

3. An employee share scheme benefit has its own field

Section titled “3. An employee share scheme benefit has its own field”

Send it as employee_share_scheme, and not in gross or an earnings line.

Send the rate as a decimal string without the percent sign, for example "3.5" for 3.5%.

Source: Inland Revenue, KiwiSaver for employers

Each registration must contain these six fields.

FieldTypeMeaning
period_enddateLast day of the pay period (YYYY-MM-DD). Must not be before period_start when you send it.
payment_datedateThe day that you pay the employee.
currencystringThe ISO 4217 code of the payslip currency, for example NZD. Refer to Currency.
grossdecimal stringTaxable gross earnings and schedular payments. Does not include an employee share scheme benefit.
payedecimal stringPAYE, or tax on schedular payments. Its own field, never also a deductions line.
netdecimal stringNet pay, as shown on the payslip.
The minimum payload
{
"period_end": "2026-04-19",
"payment_date": "2026-04-22",
"currency": "NZD",
"gross": "3000.00",
"paye": "660.00",
"net": "2135.00"
}

Send each of these fields that your payslip shows.

FieldTypeMeaning
period_startdateFirst day of the pay period (YYYY-MM-DD).
ytd_grossdecimal stringYear-to-date gross, including this pay run.
ytd_payedecimal stringYear-to-date PAYE, including this pay run.
pay_cyclestringThe pay cycle as your payslip prints it.
tax_codestringThe tax code as your payslip prints it.
employment_typestringThe employment type as your payslip prints it.
hours_paiddecimal stringThe hours that you paid the employee for this paydate.
hourlyobjectThe ordinary rate, hours and amount. Send this object when you pay an hourly rate.
annual_ratedecimal stringThe annual rate, when you pay a salary.
earnings_not_liable_for_accdecimal stringEarnings that the ACC earners’ levy does not apply to.
earningsarrayItemisation of gross. See the code sets below.
employee_share_schemedecimal stringAn employee share scheme benefit. Not part of gross.
prior_period_gross_adjustmentdecimal stringA correction to the gross of a prior period.
prior_period_paye_adjustmentdecimal stringA correction to the PAYE of a prior period.
payroll_donation_tax_creditdecimal stringThe payroll donation tax credit.
student_loandecimal stringStandard student loan repayment.
slcirdecimal stringStudent loan deduction that the Commissioner directs.
slbordecimal stringExtra student loan deduction that the borrower asks for.
child_supportdecimal stringChild support deduction.
kiwisaver_employee_deductiondecimal stringThe KiwiSaver deduction from the employee.
kiwisaver_employee_ratedecimal stringThe employee contribution rate, as the payslip prints it.
kiwisaver_employer_contributiondecimal stringThe net employer contribution, exclusive of ESCT.
esctdecimal stringEmployer superannuation contribution tax.
deductionsarrayPost-tax deduction lines. Each line has a type and an amount, and can have a year-to-date amount.
reimbursementsdecimal stringNon-taxable reimbursing payments. Not part of gross.
leave_balancesobjectThe leave entitlement of the employee. Each balance has an amount and a unit.
ytdobjectOther year-to-date totals. See the field list below.

tax_code, pay_cycle and employment_type have no code set. Send the text that your payslip prints.

ValueMeaning
ordinaryOrdinary pay.
overtime
penal_rate
piece_work
bonus_commission
extra_payAn Inland Revenue lump sum (extra pay).
schedular_paymentA schedular payment.
directors_fees
pay_as_you_go_holiday_payThe 8% holiday pay that you pay with each pay. Not leave that the employee takes.
leave_compensation_paymentThe Employment Leave Act 2026 replacement for the 8%.
annual_holiday_cash_outAnnual holiday that the employee cashes up.
alternative_holiday_cash_out
holiday_pay_on_terminationHoliday pay that you pay when employment ends.
otherA pay code that has no other type. Use it only when no other type is correct.
paid_leaveLeave that the employee takes. Carries a leave_type.
allowanceA taxable allowance. Carries an allowance_type.

Send the number without the unit, for example "76" for 76.00 hrs. The schema has no unit field.

For leave that the employee takes. There is no family violence code. See the mapping mistakes above. A public holiday uses public_holiday, whether or not the employee worked it. A day in lieu shows in leave_balances.alternative.

ValueMeaning
annual_holidayAnnual holiday that the employee takes.
public_holiday
alternative_holiday
sick_leave
bereavement_leave
other_paid_leaveEach other kind of paid leave that the employee takes.

For a taxable allowance. A non-taxable reimbursing payment goes in reimbursements.

ValueMeaning
meal
travel
accommodation
vehicle
phone
tools
uniform
on_call
shift
first_aid
higher_duties
qualification
otherEach other taxable allowance.
ValueMeaning
union_fees
payroll_donationThe donation. The tax credit has its own field.
attachment_orderA District Court attachment order.
ir_arrearsAn Inland Revenue arrears deduction notice.
other_post_taxEach other post-tax deduction, for example a health fund.

leave_balances holds leave entitlement, and not pay. Each balance has an amount and a unit. Send the unit that the payslip prints.

leave_balances
{
"annual": { "amount": "4", "unit": "weeks" },
"annual_accrued_this_period": { "amount": "6.15", "unit": "hours" },
"sick": { "amount": "10", "unit": "days" },
"alternative": { "amount": "8", "unit": "hours" }
}

The unit can be hours, days or weeks. There is no family violence balance.

Send each year-to-date total that your payslip shows. ytd_gross and ytd_paye hold the principal totals. The ytd object holds the totals below. ytd_amount on a deductions line holds the total for that line.

FieldTypeMeaning
student_loandecimal stringYear-to-date student loan repayments.
kiwisaver_employeedecimal stringYear-to-date KiwiSaver employee deductions.
kiwisaver_employerdecimal stringYear-to-date net KiwiSaver employer contributions, exclusive of ESCT.
child_supportdecimal stringYear-to-date child support deductions.
non_taxabledecimal stringYear-to-date non-taxable payments.
post_tax_deductionsdecimal stringYear-to-date post-tax deductions.
reimbursementsdecimal stringYear-to-date reimbursing payments.

Each total includes the pay run that you register.

  • Personal data. Send the name, the IRD number, the address and the bank details in the encrypted PII.
  • Paid family violence leave, in each form. There is no leave code, and no balance.
  • A KiwiSaver scheme identifier. There is no field for one.
  • The child support variation code. The deduction carries its amount only.

A salaried employee who is paid each two weeks, with KiwiSaver and a student loan.

Salaried, fortnightly
{
"period_start": "2026-04-06",
"period_end": "2026-04-19",
"payment_date": "2026-04-22",
"currency": "NZD",
"pay_cycle": "Fortnightly",
"tax_code": "M SL",
"employment_type": "Permanent",
"hours_paid": "80",
"gross": "3000.00",
"paye": "660.00",
"net": "2135.00",
"ytd_gross": "3000.00",
"ytd_paye": "660.00",
"earnings": [
{
"type": "ordinary",
"units": "76",
"rate": "37.50",
"amount": "2850.00"
},
{
"type": "overtime",
"units": "4",
"rate": "37.50",
"amount": "150.00"
}
],
"student_loan": "100.00",
"kiwisaver_employee_deduction": "105.00",
"kiwisaver_employee_rate": "3.5",
"kiwisaver_employer_contribution": "105.00",
"esct": "18.37",
"leave_balances": {
"annual": {
"amount": "4",
"unit": "weeks"
},
"sick": {
"amount": "10",
"unit": "days"
}
}
}

A casual employee who gets 8% holiday pay with each pay. The 8% is an earnings line, and not leave.

Casual, with pay-as-you-go holiday pay
{
"period_start": "2026-04-06",
"period_end": "2026-04-19",
"payment_date": "2026-04-22",
"currency": "NZD",
"pay_cycle": "Ad hoc",
"tax_code": "M",
"employment_type": "Casual",
"hours_paid": "32",
"gross": "1036.80",
"paye": "186.62",
"net": "850.18",
"earnings": [
{
"type": "ordinary",
"units": "32",
"rate": "30.00",
"amount": "960.00"
},
{
"type": "pay_as_you_go_holiday_pay",
"amount": "76.80"
}
]
}