@lap v0.3
# Machine-readable API spec. Each @endpoint block is one API call.
@api Xero Payroll AU API
@base https://api.xero.com/payroll.xro/1.0
@version 12.0.0
@auth OAuth2
@endpoints 32
@hint download_for_search
@toc Employees(4), LeaveApplications(7), PayItems(2), PayrollCalendars(3), PayRuns(4), Payslip(2), Settings(1), Superfunds(4), SuperfundProducts(1), Timesheets(4)

@group Employees
@endpoint GET /Employees
@desc Searches payroll employees
@optional {If-Modified-Since: str(date-time) # Only records created or modified since this timestamp will be returned, where: str # Filter by an any element, order: str # Order by an any element, page: int # e.g. page=1 – Up to 100 employees will be returned in a single API call}
@returns(200) {Employees: [map]} # search results matching criteria
@errors {400: validation error for a bad request}

@endpoint POST /Employees
@desc Creates a payroll employee
@optional {Idempotency-Key: str # This allows you to safely retry requests without the risk of duplicate processing. 128 character max.}
@returns(200) {Employees: [map]} # A successful request
@errors {400: invalid input, object invalid - TODO}
@example_request "[ { \"FirstName\": \"Albus\", \"LastName\": \"Dumbledore\", \"DateOfBirth\": \"/Date(321523200000+0000)/\", \"HomeAddress\": { \"AddressLine1\": \"101 Green St\", \"City\": \"Island Bay\", \"Region\": \"NSW\", \"PostalCode\": \"6023\", \"Country\": \"AUSTRALIA\" }, \"StartDate\": \"/Date(321523200000+0000)/\", \"MiddleNames\": \"Percival\", \"Email\": \"albus39608@hogwarts.edu\", \"Gender\": \"M\", \"Phone\": \"444-2323\", \"Mobile\": \"555-1212\", \"IsAuthorisedToApproveLeave\": true, \"IsAuthorisedToApproveTimesheets\": true, \"JobTitle\": \"Regional Manager\", \"Classification\": \"corporate\", \"OrdinaryEarningsRateID\": \"ab874dfb-ab09-4c91-954e-43acf6fc23b4\", \"Status\": \"ACTIVE\" } ]"

@endpoint GET /Employees/{EmployeeID}
@desc Retrieves an employee's detail by unique employee id
@required {EmployeeID: str(uuid) # Employee id for single object}
@returns(200) {Employees: [map]} # search results matching criteria

@endpoint POST /Employees/{EmployeeID}
@desc Updates an employee's detail
@required {EmployeeID: str(uuid) # Employee id for single object}
@optional {Idempotency-Key: str # This allows you to safely retry requests without the risk of duplicate processing. 128 character max.}
@returns(200) {Employees: [map]} # A successful request
@example_request "[ { \"MiddleNames\": \"Frank\" } ]"

@endgroup

@group LeaveApplications
@endpoint GET /LeaveApplications
@desc Retrieves leave applications
@optional {If-Modified-Since: str(date-time) # Only records created or modified since this timestamp will be returned, where: str # Filter by an any element, order: str # Order by an any element, page: int # e.g. page=1 – Up to 100 objects will be returned in a single API call}
@returns(200) {LeaveApplications: [map]} # search results matching criteria
@errors {400: validation error for a bad request}

@endpoint POST /LeaveApplications
@desc Creates a leave application
@optional {Idempotency-Key: str # This allows you to safely retry requests without the risk of duplicate processing. 128 character max.}
@returns(200) {LeaveApplications: [map]} # A successful request
@errors {400: invalid input, object invalid - TODO}
@example_request "[ { \"EmployeeID\": \"cdfb8371-0b21-4b8a-8903-1024df6c391e\", \"LeaveTypeID\": \"184ea8f7-d143-46dd-bef3-0c60e1aa6fca\", \"Title\": \"Hello World\", \"StartDate\": \"/Date(1572559200000+0000)/\", \"EndDate\": \"/Date(1572645600000+0000)/\" } ]"

@endpoint GET /LeaveApplications/v2
@desc Retrieves leave applications including leave requests
@optional {If-Modified-Since: str(date-time) # Only records created or modified since this timestamp will be returned, where: str # Filter by an any element, order: str # Order by an any element, page: int # e.g. page=1 – Up to 100 objects will be returned in a single API call}
@returns(200) {LeaveApplications: [map]} # search results matching criteria
@errors {400: validation error for a bad request}

@endpoint GET /LeaveApplications/{LeaveApplicationID}
@desc Retrieves a leave application by a unique leave application id
@required {LeaveApplicationID: str(uuid) # Leave Application id for single object}
@returns(200) {LeaveApplications: [map]} # search results matching criteria

@endpoint POST /LeaveApplications/{LeaveApplicationID}
@desc Updates a specific leave application
@required {LeaveApplicationID: str(uuid) # Leave Application id for single object}
@optional {Idempotency-Key: str # This allows you to safely retry requests without the risk of duplicate processing. 128 character max.}
@returns(200) {LeaveApplications: [map]} # A successful request
@errors {400: invalid input, object invalid - TODO}
@example_request "[ { \"EmployeeID\": \"cdfb8371-0b21-4b8a-8903-1024df6c391e\", \"LeaveApplicationID\": \"1d4cd583-0107-4386-936b-672eb3d1f624\", \"LeaveTypeID\": \"184ea8f7-d143-46dd-bef3-0c60e1aa6fca\", \"LeavePeriods\": [ { \"PayPeriodStartDate\": \"/Date(1572566400000+0000)/\", \"PayPeriodEndDate\": \"/Date(1573084800000+0000)/\", \"LeavePeriodStatus\": \"SCHEDULED\", \"NumberOfUnits\": 7.6 } ], \"Title\": \"vacation\", \"Description\": \"My updated Description\", \"StartDate\": \"/Date(1572559200000+0000)/\", \"EndDate\": \"/Date(1572645600000+0000)/\", \"PayOutType\": \"DEFAULT\" } ]"

@endpoint POST /LeaveApplications/{LeaveApplicationID}/approve
@desc Approve a requested leave application by a unique leave application id
@required {LeaveApplicationID: str(uuid) # Leave Application id for single object}
@optional {Idempotency-Key: str # This allows you to safely retry requests without the risk of duplicate processing. 128 character max.}
@returns(200) {LeaveApplications: [map]} # Application successfully approved
@errors {400: validation error for a bad request}

@endpoint POST /LeaveApplications/{LeaveApplicationID}/reject
@desc Reject a leave application by a unique leave application id
@required {LeaveApplicationID: str(uuid) # Leave Application id for single object}
@optional {Idempotency-Key: str # This allows you to safely retry requests without the risk of duplicate processing. 128 character max.}
@returns(200) {LeaveApplications: [map]} # Application successfully rejected
@errors {400: validation error for a bad request}

@endgroup

@group PayItems
@endpoint GET /PayItems
@desc Retrieves pay items
@optional {If-Modified-Since: str(date-time) # Only records created or modified since this timestamp will be returned, where: str # Filter by an any element, order: str # Order by an any element, page: int # e.g. page=1 – Up to 100 objects will be returned in a single API call}
@returns(200) {PayItems: map{EarningsRates: [map], DeductionTypes: [map], LeaveTypes: [map], ReimbursementTypes: [map]}} # search results matching criteria
@errors {400: validation error for a bad request}

@endpoint POST /PayItems
@desc Creates a pay item
@optional {Idempotency-Key: str # This allows you to safely retry requests without the risk of duplicate processing. 128 character max., EarningsRates: [map{Name: str, AccountCode: str, TypeOfUnits: str, IsExemptFromTax: bool, IsExemptFromSuper: bool, IsReportableAsW1: bool, IsQualifyingEarnings: bool, AllowanceContributesToAnnualLeaveRate: bool, AllowanceContributesToOvertimeRate: bool, EarningsType: str, EarningsRateID: str(uuid), RateType: str, RatePerUnit: str, Multiplier: num(double), AccrueLeave: bool, Amount: num(double), EmploymentTerminationPaymentType: str, UpdatedDateUTC: str, CurrentRecord: bool, AllowanceType: str, AllowanceCategory: str}], DeductionTypes: [map{Name: str, AccountCode: str, ReducesTax: bool, ReducesSuper: bool, IsExemptFromW1: bool, DeductionTypeID: str(uuid), UpdatedDateUTC: str, DeductionCategory: str, CurrentRecord: bool}], LeaveTypes: [map{Name: str, TypeOfUnits: str, LeaveTypeID: str(uuid), NormalEntitlement: num(double), LeaveLoadingRate: num(double), UpdatedDateUTC: str, IsPaidLeave: bool, ShowOnPayslip: bool, CurrentRecord: bool, LeaveCategoryCode: str, SGCExempt: bool, IsQualifyingEarnings: bool}], ReimbursementTypes: [map{Name: str, AccountCode: str, ReimbursementTypeID: str(uuid), UpdatedDateUTC: str, CurrentRecord: bool}]}
@returns(200) {PayItems: map{EarningsRates: [map], DeductionTypes: [map], LeaveTypes: [map], ReimbursementTypes: [map]}} # A successful request - currently returns empty array for JSON
@errors {400: invalid input, object invalid - When IsQualifyingEarnings supplied it will be validated against the IsExemptFromSuper and other fields.}
@example_request {"EarningsRates":[{"Name":"MyRate","AccountCode":"400","TypeOfUnits":"4.00","IsExemptFromTax":false,"IsExemptFromSuper":true,"IsReportableAsW1":false,"IsQualifyingEarnings":true,"AllowanceContributesToAnnualLeaveRate":false,"AllowanceContributesToOvertimeRate":false,"EarningsType":"ORDINARYTIMEEARNINGS","EarningsRateID":"1fa4e226-b711-46ba-a8a7-4344c9c5fb87","RateType":"MULTIPLE","RatePerUnit":"10.0","Multiplier":1.5,"Amount":5,"EmploymentTerminationPaymentType":"O"}]}

@endgroup

@group PayrollCalendars
@endpoint GET /PayrollCalendars
@desc Retrieves payroll calendars
@optional {If-Modified-Since: str(date-time) # Only records created or modified since this timestamp will be returned, where: str # Filter by an any element, order: str # Order by an any element, page: int # e.g. page=1 – Up to 100 objects will be returned in a single API call}
@returns(200) {PayrollCalendars: [map]} # search results matching criteria
@errors {400: validation error for a bad request}

@endpoint POST /PayrollCalendars
@desc Creates a Payroll Calendar
@optional {Idempotency-Key: str # This allows you to safely retry requests without the risk of duplicate processing. 128 character max.}
@returns(200) {PayrollCalendars: [map]} # A successful request
@errors {400: invalid input, object invalid - TODO}
@example_request "[ { \"PayrollCalendarID\":\"78bb86b9-e1ea-47ac-b75d-f087a81931de\", \"PayRunPeriodStartDate\":\"/Date(1572566400000+0000)/\", \"PayRunPeriodEndDate\":\"/Date(1573084800000+0000)/\", \"PayRunStatus\":\"DRAFT\", \"PaymentDate\":\"/Date(1573171200000+0000)/\" } ]"

@endpoint GET /PayrollCalendars/{PayrollCalendarID}
@desc Retrieves payroll calendar by using a unique payroll calendar ID
@required {PayrollCalendarID: str(uuid) # Payroll Calendar id for single object}
@returns(200) {PayrollCalendars: [map]} # search results matching criteria
@errors {400: validation error for a bad request}

@endgroup

@group PayRuns
@endpoint GET /PayRuns
@desc Retrieves pay runs
@optional {If-Modified-Since: str(date-time) # Only records created or modified since this timestamp will be returned, where: str # Filter by an any element, order: str # Order by an any element, page: int # e.g. page=1 – Up to 100 PayRuns will be returned in a single API call}
@returns(200) {PayRuns: [map]} # search results matching criteria
@errors {400: validation error for a bad request}

@endpoint POST /PayRuns
@desc Creates a pay run
@optional {Idempotency-Key: str # This allows you to safely retry requests without the risk of duplicate processing. 128 character max.}
@returns(200) {PayRuns: [map]} # A successful request
@errors {400: invalid input, object invalid - TODO}
@example_request "[ { \"PayrollCalendarID\": \"78bb86b9-e1ea-47ac-b75d-f087a81931de\", \"PayRunPeriodStartDate\": \"/Date(1572566400000+0000)/\", \"PayRunPeriodEndDate\": \"/Date(1573084800000+0000)/\", \"PayRunStatus\": \"DRAFT\", \"PaymentDate\": \"/Date(1573171200000+0000)/\" } ]"

@endpoint GET /PayRuns/{PayRunID}
@desc Retrieves a pay run by using a unique pay run id
@required {PayRunID: str(uuid) # PayRun id for single object}
@returns(200) {PayRuns: [map]} # search results matching criteria

@endpoint POST /PayRuns/{PayRunID}
@desc Updates a pay run
@required {PayRunID: str(uuid) # PayRun id for single object}
@optional {Idempotency-Key: str # This allows you to safely retry requests without the risk of duplicate processing. 128 character max.}
@returns(200) {PayRuns: [map]} # A successful request

@endgroup

@group Payslip
@endpoint GET /Payslip/{PayslipID}
@desc Retrieves for a payslip by a unique payslip id
@required {PayslipID: str(uuid) # Payslip id for single object}
@returns(200) {Payslip: map{EmployeeID: str(uuid), PayslipID: str(uuid), FirstName: str, LastName: str, Wages: num(double), Deductions: num(double), Tax: num(double), Super: num(double), Reimbursements: num(double), NetPay: num(double), EarningsLines: [map], LeaveEarningsLines: [map], TimesheetEarningsLines: [map], DeductionLines: [map], LeaveAccrualLines: [map], ReimbursementLines: [map], SuperannuationLines: [map], TaxLines: [map], UpdatedDateUTC: str}} # search results matching criteria

@endpoint POST /Payslip/{PayslipID}
@desc Updates a payslip
@required {PayslipID: str(uuid) # Payslip id for single object}
@optional {Idempotency-Key: str # This allows you to safely retry requests without the risk of duplicate processing. 128 character max.}
@returns(200) {Payslips: [map]} # A successful request - currently returns empty array for JSON
@example_request {"Payslip":{"EmployeeID":"cdfb8371-0b21-4b8a-8903-1024df6c391e","DeductionLines":[{"DeductionTypeID":"727af5e8-b347-4ae7-85fc-9b82266d0aec","CalculationType":"FIXEDAMOUNT","NumberOfUnits":10}]}}

@endgroup

@group Settings
@endpoint GET /Settings
@desc Retrieves payroll settings
@returns(200) {Settings: map{Accounts: [map], TrackingCategories: map{EmployeeGroups: map{TrackingCategoryID: str(uuid), TrackingCategoryName: str}, TimesheetCategories: map{TrackingCategoryID: str(uuid), TrackingCategoryName: str}}, DaysInPayrollYear: int(int32), EmployeesAreSTP2: bool}} # payroll settings

@endgroup

@group Superfunds
@endpoint GET /Superfunds
@desc Retrieves superfunds
@optional {If-Modified-Since: str(date-time) # Only records created or modified since this timestamp will be returned, where: str # Filter by an any element, order: str # Order by an any element, page: int # e.g. page=1 – Up to 100 SuperFunds will be returned in a single API call}
@returns(200) {SuperFunds: [map]} # search results matching criteria
@errors {400: validation error for a bad request}

@endpoint POST /Superfunds
@desc Creates a superfund
@optional {Idempotency-Key: str # This allows you to safely retry requests without the risk of duplicate processing. 128 character max.}
@returns(200) {SuperFunds: [map]} # A successful request
@errors {400: invalid input, object invalid - TODO}
@example_request "[ { \"usi\":\"PTC0133AU\", \"Type\":\"REGULATED\", \"Name\":\"Bar99359\", \"AccountNumber\":\"FB36350\", \"AccountName\":\"Foo38428\", \"USI\":\"PTC0133AU\" } ]"

@endpoint GET /Superfunds/{SuperFundID}
@desc Retrieves a superfund by using a unique superfund ID
@required {SuperFundID: str(uuid) # Superfund id for single object}
@returns(200) {SuperFunds: [map]} # search results matching criteria

@endpoint POST /Superfunds/{SuperFundID}
@desc Updates a superfund
@required {SuperFundID: str(uuid) # Superfund id for single object}
@optional {Idempotency-Key: str # This allows you to safely retry requests without the risk of duplicate processing. 128 character max.}
@returns(200) {SuperFunds: [map]} # A successful request
@example_request " [ { \"Type\":\"REGULATED\", \"Name\":\"Nice23534\" } ]"

@endgroup

@group SuperfundProducts
@endpoint GET /SuperfundProducts
@desc Retrieves superfund products
@optional {ABN: str # The ABN of the Regulated SuperFund, USI: str # The USI of the Regulated SuperFund}
@returns(200) {SuperFundProducts: [map]} # search results matching criteria
@errors {400: validation error for a bad request}

@endgroup

@group Timesheets
@endpoint GET /Timesheets
@desc Retrieves timesheets
@optional {If-Modified-Since: str(date-time) # Only records created or modified since this timestamp will be returned, where: str # Filter by an any element, order: str # Order by an any element, page: int # e.g. page=1 – Up to 100 timesheets will be returned in a single API call}
@returns(200) {Timesheets: [map]} # search results matching criteria
@errors {400: validation error for a bad request}

@endpoint POST /Timesheets
@desc Creates a timesheet
@optional {Idempotency-Key: str # This allows you to safely retry requests without the risk of duplicate processing. 128 character max.}
@returns(200) {Timesheets: [map]} # A successful request
@errors {400: invalid input, object invalid - TODO}
@example_request "[ { \"EmployeeID\":\"b34e89ff-770d-4099-b7e5-f968767118bc\", \"StartDate\":\"/Date(1573171200000+0000)/\", \"EndDate\":\"/Date(1573689600000+0000)/\", \"Status\":\"DRAFT\", \"TimesheetLines\":[ { \"EarningsRateID\":\"ab874dfb-ab09-4c91-954e-43acf6fc23b4\", \"TrackingItemID\":\"af5e9ce2-2349-4136-be99-3561b189f473\", \"NumberOfUnits\":[ 2.0, 10.0, 0.0, 0.0, 5.0, 0.0, 5.0 ] } ] } ]"

@endpoint GET /Timesheets/{TimesheetID}
@desc Retrieves a timesheet by using a unique timesheet id
@required {TimesheetID: str(uuid) # Timesheet id for single object}
@returns(200) {Timesheet: map{EmployeeID: str(uuid), StartDate: str, EndDate: str, Status: str, Hours: num(double), TimesheetID: str(uuid), TimesheetLines: [map], UpdatedDateUTC: str, ValidationErrors: [map]}} # search results matching criteria

@endpoint POST /Timesheets/{TimesheetID}
@desc Updates a timesheet
@required {TimesheetID: str(uuid) # Timesheet id for single object}
@optional {Idempotency-Key: str # This allows you to safely retry requests without the risk of duplicate processing. 128 character max.}
@returns(200) {Timesheets: [map]} # A successful request
@example_request "[ { \"EmployeeID\":\"b34e89ff-770d-4099-b7e5-f968767118bc\", \"StartDate\":\"/Date(1573171200000+0000)/\", \"EndDate\":\"/Date(1573689600000+0000)/\", \"Status\":\"APPROVED\", \"Hours\":22.0, \"TimesheetID\":\"a7eb0a79-8511-4ee7-b473-3a25f28abcb9\", \"TimesheetLines\":[ { \"EarningsRateID\":\"ab874dfb-ab09-4c91-954e-43acf6fc23b4\", \"TrackingItemID\":\"af5e9ce2-2349-4136-be99-3561b189f473\", \"NumberOfUnits\":[ 2.0, 10.0, 0.0, 0.0, 5.0, 0.0, 5.0 ], \"UpdatedDateUTC\":\"/Date(1573516185127+0000)/\" } ] } ]"

@endgroup

@end
