Upsert and get employee via developer API
This guide explains how to upsert (insert-or-update) and get employee data via the Microkeeper developer API.
add_employeesandupdate_employeesare deprecated and replaced byupsert_employees.- auto_username is now always enforced for inserts in
upsert_employees. - Manual eusername selection is no longer supported when creating new employees. Usernames are generated as
firstname_lastnameXwithXincremented until unique. get_employeesnow returns additional data (see the "New in 2025 for get_employees" callout below).
Upserting Employees via API
Step 1
Before starting this tutorial make sure you have completed the Hello World tutorial.
Complete the hello_world tutorial Hello World
Step 2
Set the mk_action variable and mk_data variable.
| Variable name | Value - Minimum requirement |
|---|---|
| mk_action | upsert_employees |
| mk_data | { "Employees": [ { "EmployeeID":"emp_001", "firstname":"John", "lastname":"Smith", "email":"john@example.com", "phoneno":"0400123456", "super_fund":"RES0103AU", "welcome":"email" } ] }Notes:
|
Step 3
List of available fields (upsert)
The minimum fields required are firstname and lastname. For updates, include an identifier (EmployeeID, EID or eusername).
If a field is missing a default or blank value may be set. If an unknown format is supplied, the profile is still processed but that field may be skipped without error. Verify the data in the Microkeeper UI after upsert.
| Variable Name | Description | Format | Example | Updatable | Gettable |
|---|---|---|---|---|---|
| EID | Employee ID in Microkeeper (unique) | Integer | 12345 | Yes (update match only) | Yes |
| eusername | Employee username (unique). auto_username enforced | Standardised "firstname_lastnameX" | john_smith | Yes (update match only). New inserts auto-generate | Yes |
| EmployeeID | Employee ID in 3rd party system (unique) | Alphanumeric | emp_001 | Yes (update match or insert if not found) | Yes |
| Unique identifier rules: Any of EID, eusername, EmployeeID can be used to update. If only EmployeeID is supplied and not found, a new record is inserted. If EID or eusername is supplied but does not exist, an error is returned. | |||||
| firstname | Given name | Alpha | John | Yes (required) | Yes |
| lastname | Surname | Alpha | Smith | Yes (required) | Yes |
| Email (re-verification required on change) | john@example.com | Yes | Yes | ||
| phoneno | Mobile number (re-verification required on change) | Numeric | 0400123456 | Yes | Yes |
| home_no | Home number | Numeric | 03 5211 2233 | Yes | Yes |
| address | Address line 1 | Alphanumeric | 1 Smith St | Yes | Yes |
| city | Suburb | Alpha | Belmont | Yes | Yes |
| state | State (OTH for overseas) | VIC,NSW,NT,QLD,SA,TAS,WA,OTH | VIC | Yes | Yes |
| postcode | Postcode | Numeric | 3216 | Yes | Yes |
| country | Country | Alpha | Australia | Yes | Yes |
| timezone | Time zone (defaults from state if missing) | IANA TZ (e.g., Australia/Victoria) | Australia/Victoria | Yes | Yes |
| dob2 | Date of birth | dd/mm/yyyy or yyyy-mm-dd | 1970-11-23 | Yes | Yes |
| startdate2 | Start date | dd/mm/yyyy or yyyy-mm-dd | 2014-10-20 | Yes | Yes |
| terdate2 | Termination date | dd/mm/yyyy or yyyy-mm-dd | 2014-10-20 | Yes | Yes |
| cessation_type | Cessation Type | String (V,I,D,R,F,C,T) | V | Yes | Yes |
| last_modified | Date record last modified | yyyy-mm-dd | 2025-10-31 | No (set by system) | Yes |
| sex | Gender | F/M/I/O (and variants) | M | Yes | Yes |
| rate | Pay rate | Decimal ($) | 16.1943 | Yes | Yes |
| RRNID | Rate Rule Name ID | Integer | 1234 | Yes | Yes |
| tax | Tax scale | Integer (1,5,8,4) | 1 | Yes | Yes |
| employment_override | Status Override | String: "", D, L, N, V | D | Yes | Yes |
| income_type | STP Income Stream Type | String (SAW/WHM/etc.) | WHM | Yes | Yes |
| tax_free | Tax Free Threshold | Boolean | 1 | Yes | Yes |
| help | HELP PAYG | Boolean | 0 | Yes | Yes |
| tsl | Trade Support Loan | Boolean | 0 | Yes | Yes |
| sfss | Student Financial Supplement Scheme | Boolean | 0 | Yes | Yes |
| senior_tax | Seniors and Pensioners Tax Offset | Boolean | 0 | Yes | Yes |
| tax_per | Fixed Tax percentage | Integer (%) | 20 | Yes | Yes |
| tax_add | Tax offset | -1000 to +1000 ($) | 50 | Yes | Yes |
| etfn | Tax File Number | Numeric | 321 321 321 | Yes | No (exported as "set/not_set") |
| super_fund | Super Fund (accepts USI) | USI / SPIN / Name | RES0103AU | Yes (USI mapped to fund) | Yes (as object) |
| super_no | Super Member Number | Alphanumeric | 655655655 | Yes | Yes |
| open_balance | Opening balance by year | Object | "open_balance": { "2024": { "al": 80, "sick": 16 }, "2025": { "al": 40 } } | Yes | Yes |
| leave_quota | Leave quotas by key | Object | "leave_quota": { "toil": { "accrual_amount": 2.923, "payslip_hide": 0 } } | Yes | Yes |
| kin_name | Next of kin name | Alpha | Roger | Yes | Yes |
| kin_no | Next of kin phone number | Numeric | 03 5244 0011 | Yes | Yes |
| eTitle | Bank title account 1 | String | Mr John Smith | Yes | Yes |
| eBSB_A | Bank BSB account 1 | xxx-xxx / xxxxxx / xxxxx | 011-222 | Yes | Yes |
| eAccountNo | Bank account number account 1 | Numeric | 123123123 | Yes | Yes |
| split_pay | Split pay to account 2 | String: "", fix, per | fix | Yes | No |
| split_amount | Split amount to account 2 | Decimal (amount or %) | 200 | Yes | No |
| eTitle2 | Bank title account 2 | String | Mr John Smith | Yes | No |
| eBSB_B | Bank BSB account 2 | xxx-xxx / xxxxxx / xxxxx | 011-222 | Yes | No |
| eAccountNo2 | Bank account number account 2 | Numeric | 111222333 | Yes | No |
| split_pay3 | Split pay to account 3 | String: "", fix, per | nul | Yes | No |
| split_amount3 | Split amount to account 3 | Decimal (amount or %) | 0 | Yes | No |
| eTitle3 | Bank title account 3 | String | Yes | No | |
| eBSB_C | Bank BSB account 3 | xxx-xxx / xxxxxx / xxxxx | 011-222 | Yes | No |
| eAccountNo3 | Bank account number account 3 | Numeric | Yes | No | |
| default_LID | Default Location | Integer | 7656 | Yes | Yes |
| default_ROID | Default Role | Integer | 2343 | Yes | Yes |
| default_job | Default Job (ID from Job list) | Integer | 1234 | Yes | No |
| primary_manager | Username of primary manager | String | john_smith | Yes | No |
| position | Position of employee | String | CFO | Yes | No |
| show_sick | Show PL on payslip | Boolean | 1 | Yes | Yes |
| show_annu | Show Annual Leave on payslip | Boolean | 1 | Yes | Yes |
| show_long | Show LSL on payslip | Boolean | 1 | Yes | Yes |
| show_rdo | Show RDO/TIL on payslip | Boolean | 1 | Yes | Yes |
| super_on_loading | Should super be applied to Leave Loading | Boolean | 1 | Yes | Yes |
| abn | Sub-Contractor ABN (if status = Sub-Contractor) | Integer | 82004832237 | Yes | Yes |
| businessname | Sub-Contractor Business Name (if status = Sub-Contractor) | String | ABC Contractor Pty Ltd | Yes | Yes |
| active | Active or Terminated | String: TRUE/FALSE | TRUE | No (defaults active on add) | Yes |
| entitledal | Entitled annual leave weeks | Decimal (weeks) | 4 | Yes | Yes |
| entitledsickleave | Entitled personal leave | Decimal (weeks) | 2 | Yes | Yes |
| leaveloading | Annual leave loading | Decimal (%) | 17.5 | Yes | Yes |
| rdo | Rostered day off hours deducted | Integer (hours) | 2 | Yes | Yes |
| entitled_long | Entitled long service leave | Decimal (1 week in x) | 60 | Yes | No |
| preyear | Year pre-accumulated data is applied to (Deprecated use open_balance) | Year (e.g., 2020 = 2020/21) | 2020 | Yes | No |
| preacal | Pre-accumulated annual leave (Deprecated) | Decimal (hours) | 123.32 | Yes | No |
| pre_long | Pre-accumulated long service leave (Deprecated) | Decimal (hours) | 123.32 | Yes | No |
| pre_sick | Pre-accumulated personal leave (Deprecated) | Decimal (hours) | 123.32 | Yes | No |
| prerdo | Pre-accumulated RDO (Deprecated) | Decimal (hours) | 123.32 | Yes | No |
| pregross | Pre-accumulated gross (Deprecated) | Decimal ($) | 10000.22 | Yes | No |
| presuper | Pre-accumulated super above statutory (Deprecated) | Decimal ($) | 10000.22 | Yes | No |
| pretax | Pre-accumulated tax (Deprecated) | Decimal ($) | 10000.22 | Yes | No |
| prenet | Pre-accumulated net (Deprecated) | Decimal ($) | 10000.22 | Yes | No |
| basichours | Basic hours | Decimal (hours) | 38 | Yes | No |
| salary | Salary flag | String: T/F | T | Yes | No |
| status | Employment status | Full Time / Casual / Part Time / Sub-Contractor / Subby-Super | Full Time | Yes | No |
| superbasic | Super on basic-only vs incl. OT | TRUE = OTE only; FALSE = OTE+OT | 0 = default | Yes | No |
| super_fix_type | Fixed/Min/Max super override | Integer: 0 Fixed, 1 Min, 2 Max | 0 (disabled) | Yes | No |
| super_fixed | Amount for super_fix_type | Decimal ($) | 155.55 | Yes | No |
| duplicate_check | Checks if a user already exists via email | String=email | Yes | NA | |
| auto_username | Force username format firstname_lastnameX | Boolean (1/0) | 1 | Yes | NA |
| welcome | Send welcome message (on insert) | sms | email | both | Yes (insert only) | NA | |
| custom_{field} | Active custom fields (e.g., custom_favourite_pizza) | String / Date (yyyy-mm-dd) | custom_favourite_pizza | Yes | Yes |
Many other fields remain supported as in the legacy table (banking accounts 2 & 3, super_fund_2..4, pre-accumulated fields, status, salary, etc.). Behaviour and formats are unchanged unless noted above.
Open Balance
These objects can be included per employee in upsert_employees to insert/update opening balances.
| Object | Description | Example |
|---|---|---|
| open_balance | Map of year { open_key: amount }. If present, upserted per (eusername,year,open_key). | "open_balance": { "2024": { "al": 80, "sick": 16 }, "2025": { "al": 40 } } |
Supported open_key keys are:
| Key | Description | Unit | Example |
|---|---|---|---|
al | Annual Leave | Hours | 500 |
sick | Personal/Carer's (Sick) Leave | Hours | 400 |
lsl | Long Service Leave | Hours | 300 |
rdo | Rostered Day Off | Hours | 200 |
toil | Time Off in Lieu (TIL) | Hours | 100 |
off | Unpaid Leave | Hours | 0 |
com | Compassionate Leave | Hours | 0 |
pregross | Gross | Currency | 50,000 |
presuper | Super | Currency | 40,000 |
pretax | PAYG tax | Currency | 30,000 |
prenet | Net | Currency | 20,000 |
Leave Quota
This tool is to be used along side custom leave type, where the employer add new leave types outside of the supplied standard list so:
- Annual Leave "al"
- Personal Leave "sick"
- Long Service Leave "lsl"
- Rostered Day Off "rdo"
- Time Off In Lieu "toil"
TOIL does not have a fixed accrual amount.
| Object | Description | Example |
|---|---|---|
| leave_quota | Map of leave_key { accrual_amount, payslip_hide }. Upserted per (eusername,leave_key). | "leave_quota": { "toil": { "accrual_amount": 2.923, "payslip_hide": 0 }, "rdo": { "accrual_amount": 1.462 } } |
Custom Fields
Custom fields are sent/returned as custom_{field}, e.g. custom_favourite_pizza.
- Only active custom fields are processed.
- Date-validated custom fields are exported as
yyyy-mm-dd. - Unlimited fields supported.
Step 4
Response
The response will be JSON.
When employees are added or updated, the response includes the list of EID for affected records. If you passed your EmployeeID, it will be echoed with its EID.
Successful example
{ "success":"1", "authenticated":"1", "message":"User added or updated to Microkeeper", "data":{ "added":{"emp_001":68783}, "updated":{"EID":[12345,12346]} } }Notes: On updates that matched an existing record, email/phone re-verification flags are reset if email or phoneno changed.
If nothing was added or updated, an error message is returned.
Get Employee data via API
Via last_modified
You can retrieve staff by last_modified (up to 365 days back) or use "active" to return only active staff.
Via user_list
Alternatively, supply a user_list with EmployeeID, EID, or eusername arrays to fetch specific users.
Step 1
Set the mk_action and mk_data variables.
| Variable name | Values and Example |
|---|---|
| mk_action | get_employees |
| mk_data | {"config":{"last_modified":"2025-10-01"}}or{"config":{"last_modified":"active"}}or{"config":{"user_list":{"EmployeeID":["abc1","abc2"]}}}or{"config":{"user_list":{"EID":["111","222"]}}}or{"config":{"user_list":{"eusername":["jane_d","john_s"]}}} |
Step 2
Review data standards
Refer to the upsert table for exported formats.
Sensitive fields (e.g. TFN) are not exported; instead, etfn will be set or not_set.
get_employees:- EmployeeID is always present (blank string if not set historically) for easier 3rd-party mapping and updating.
- open_balance is returned per employee as
{"YYYY":{"al":hours,"sick":hours,...}}. - leave_quota is returned per employee as
{"leave_key":{"accrual_amount":x.xxx,"payslip_hide":0|1}}. - groups now include
GIDandper(percentage allocation) for each group membership. - super_fund fields are expanded into objects including
SFID,name,ABN,USI, andspinfor each of up to four funds. - custom_* fields include all active custom fields; date-validated custom fields are normalised to
yyyy-mm-dd.
super_fund array
| Variable name | Description | Output format | Example |
|---|---|---|---|
| SFID | Super Fund ID | Integer | 111 |
| name | Common fund name | String | REST Employer |
| ABN | Australian Business Number (may be blank if not recorded) | Number | 76514770399 |
| USI | Unique Super Identifier (not for SMSF) | Alphanumeric | RES0103AU |
| spin | Superannuation Product Identification Number | Alphanumeric | AMP0278AU |
groups array
| Variable name | Description | Output format | Example |
|---|---|---|---|
| GID | Group ID in Microkeeper | Integer | 111 |
| per | Percentage for cost centre tracking (0100) | Decimal | 100 |
open_balance object
| Key | Description | Format | Example |
|---|---|---|---|
| YYYY | Year the opening balance applies to | Year (e.g. 2025) | 2025 |
| open_key | Leave key (e.g. al, sick) | String | al |
| open_amount | Opening hours for that key | Decimal (hours) | 80.000 |
leave_quota object
| Key | Description | Format | Example |
|---|---|---|---|
| leave_key | Leave key (e.g. al, sick) | String | al |
| accrual_amount | Accrual hours amount | Decimal (hours) | 2.923 |
| payslip_hide | Hide balance on payslip | Boolean (0/1) | 0 |
Response
Step 3
The format will be JSON.
A successful response might include no employees if no records matched your filters. The data field will include an employees array.
Successful example:
{
"success": "1",
"authenticated": "1",
"message": "2 staff retrieved from Microkeeper",
"data": {
"employees": [
{
"EID": "3",
"EmployeeID": "emp_001",
"eusername": "john_smith",
"firstname": "John",
"lastname": "Smith",
"...": "...",
"super_fund": {
"SFID": "482",
"name": "REST Employer Sponsored Division",
"ABN": "",
"USI": "RES0103AU",
"spin": "RES0103AU"
},
"groups": [
{ "GID": 111, "per": 100 }
],
"open_balance": {
"2024": { "al": 80, "sick": 16 }"2025": { "sick": 80, "sick": 16 }
},
"leave_quota": {
"al": { "accrual_amount": 2.923, "payslip_hide": 0 }
}
}
]
}
}
- Manual username selection on insert is no longer supported.
- auto_username is forced by design in
upsert_employees. - Duplicate identifiers within a single payload (same
EmployeeID,EIDoreusernameappearing twice) will cause the request to fail.
Updating email and mobile number
If email or phoneno is updated, Microkeeper will reset the verification flags and the employee will need to verify again.