NAV Navbar

SimplePay API Docs

  • Introduction
  • Authentication
  • Available Resources
  • Bulk Inputs
  • Clients
  • Employees
  • Payment Frequencies
  • Pay Points
  • Payslips
  • Pay Runs
  • Reports
  • Calculations
  • Inherited Calculations
  • Service Periods
  • Leave
  • Template Profile Mappings
  • Rate Limits
  • Errors
  • Introduction

    This site explains how to use the SimplePay API in order to send and receive data. The SimplePay API is an HTTP RESTful service. It is recommended that you familiarise yourself with RESTful APIs before browsing this site.

    Please contact us at [email protected] if you have any queries or issues related to API functionality.

    SimplePay Terminology

    Before using the API, please take note of the following terminology:

    Resource Details
    client A company
    wave A pay frequency, i.e. the frequency with which employees are paid
    pay_point Means of grouping employees, e.g. by department
    calculation A payslip item. System-defined calculations are specified by their name, e.g. basic_salary. Custom calculations are specified using a numeric ID e.g. 12345

    Authentication

    Authentication involves two steps. Firstly, API users should generate a key to be used with API requests. Then this key should be added to all API requests as a header in a specific format. The process is as follows:

    Authorization: the_api_key_from_simplepay

    Depending on which tool or programming environment you use, headers are added to HTTP requests in different ways.

    Example Request with Correct Authentication

    Request

    # With the command line you can pass the correct header with each request
    curl -i -X GET https://api.payroll.simplepay.cloud/v1/clients/ -H 'Content-Type: application/json' -H 'Authorization: the_api_key_from_simplepay'
    

    You can test that you are able to access the API using this key with the following request for a list of clients, using the command line tool called cURL.

    Make sure to replace the_api_key_from_simplepay with your API key.

    Response

    [
      {
        "client":{...},
      },{
        "client":{...},
      }
    
    ]
    

    When you run this command from your command line you, should see a response body that looks something like this snippet ->

    If you can successfully retrieve a list of clients, you have authenticated your API call successfully.

    Available Resources

    The SimplePay API currently allows you to interact with clients and employees on SimplePay.

    Bulk Inputs

    Client Information

    Employee Profiles

    Payment Frequencies

    Payslips

    Calculations

    Inherited Calculations

    Service Periods

    Reports

    Leave

    Template Profile Mappings

    ** Additional functionality is being assessed and developed incrementally based on user requirements

    Bulk Inputs

    Update Employees and Payslips

    Request

    Request

    https://api.payroll.simplepay.cloud/v1/clients/:client_id/bulk_input
    

    This is an HTTP POST request to this URL ->

    Where the parameter :client_id is the ID of a specific client obtained from the call to get a list of clients.

    Request Body

    Request Body

    { "entities": [
        {
          "id": "243",
          "payslip_id": "4257689",
          "attributes": {
            "first_name": "Juliet",
            "calc.basic_salary.fixed_amount": "4300",
            "calc.commission.commission_input": "160",
            "calc.extra_pay.amount": "100",
            "calc.annual_bonus.amount": "220",
            "calc.76523.amount": "122"
          }
        },{
          "id": "243",
          "payslip_id": "12765",
          "attributes": {
            "calc.commission.commission_input": "120"
          }
        },{
          "id": "9003",
          "payslip_id": "1235",
          "attributes": {
            "calc.basic_salary.fixed_amount": "3450",
            "calc.commission.commission_input": "400"
          }
        },{
          "id": "21103",
          "payslip_date": "2020-12-31",
          "attributes": {
            "calc.annual_bonus.amount": "220",
          }
        },{
          "id": "8792",
          "attributes": {
            "first_name": "Mitchell",
            "calc.basic_salary.hourly_paid": "true",
            "calc.basic_salary.normal_rate_input": "20"
          }
        }
    ] }
    

    The request body should be a JSON object. It contains a list of entity hashes. Each entity hash refers to a single employee and contains the following keys

    Name Description
    id The employee ID

    payslip_id A payslip identifier. This is only relevant when payslip specific inputs are included in the attributes.
    payslip_date A payslip identifier that can be used instead of "payslip_id". The regular payslip for the pay period that ends on "payslip_date" will be updated. Once-off payslips cannot be specified by date. This is only relevant when payslip specific inputs are included in the attributes.
    attributes A hash containing the inputs to be added or updated for the employee.
 Valid calculation attribute IDs and inputs can be found using the “Get a list of Calculations” request. These calculation IDs must be prefixed with "calc." to indicate that they are calculation attributes e.g. "calc.annual_bonus.amount" or "calc.76523.amount" for a custom calculation.

    Note: Finalised payslips cannot be updated.

    An example is shown ->

    Response

    Response

    [
      {
        "id": "243",
        "payslip_id": "4257689",
        "success": "true",
        "message": "Information for Juliet Bordet was saved successfully"
      },{
        "id": "243",
        "payslip_id": "12765",
        "success": "true",
        "message": "Information for Juliet Bordet was saved successfully"
      },{
        "id": "9003",
        "payslip_id": "1235",
        "success": "false",
        "message": "Information for Hannes Hvilken failed to save"
        "errors": {
          "calc.commission.commission_input": “Commission is not enabled”
        }
      },{
        "id": "21103",
        "payslip_id": "20762",
        "payslip_date": "2020-12-31",
        "success": "true",
        "message": "Information for Henry Browning was saved successfully"
      },{
        "id": "8792",
        "success": "true",
        "message": "Information for Mitchell Sykler was saved successfully”
      }
    ]
    

    If executed correctly the response body is a JSON object with details of which entities were saved correctly. The response contains a list of entity hashes that correspond to those in the request. The entity hashes contain the employee id, a payslip identifier if necessary, and a success or failure message and boolean. If any of the attributes failed to save, the message will indicate failure and an errors hash will also be included. The errors hash’s key are the attributes that did not save and the values are the error messages.

    An example is shown ->

    Clients

    Get a List of Clients

    Request

    Request

    https://api.payroll.simplepay.cloud/v1/clients/
    

    This is an HTTP GET request to URL ->



    Response

    Response

    [
      {"client":{
        "id":36818,
        "name":"API QA Company",
        "physical_address":{
          "unit_no": "10878",
          "complex":"Bridge Towers",
          "st_name": "5 North Bridge Road",
          "postal_code": "149281"
        },
        ...
      }}
    ]
    

    If executed correctly the response body is a JSON array with a list of clients, which should be similar to this snippet ->

    Employees

    Get a list of Employees

    Request

    Request

    https://api.payroll.simplepay.cloud/v1/clients/:client_id/employees
    

    This is an HTTP GET request to URL ->

    Where the parameter :client_id is the ID of a specific client obtained from the call to get a list of clients.

    You can use the include query parameter to specify a comma-separated list of entities that you want included.

    For example, appending ?include=service_periods,recent_payslips to the URL will include the service periods and recent 12 payslips of the employee in the response.

    Allowed entities: service_periods (will return all service periods), recent_payslips (will return last 12 payslips), and recent_payslips_with_data (will return last 12 payslips with their payslip items).

    Note 1: When recent_payslips_with_data is requested, api may respond with 202 status with an error message when there are payslips which require calculations. Please try after a while to get the prepared result.

    Note 2: Payslips whose calculations are still in progress will have the dirty attribute set to true, and nett_pay attribute unavailable in the response. Please try again later to obtain nett pay.

    Response

    Response

    [
      {"employee":{
        "first_name": "Kenneth",
        "last_name": "Parker",
        "birthdate": "1985-02-06",
        "appointment_date": "2010-02-06",
        "wave_id": 2,
        "payment_method": "cash",
        "physical_address": {
          "unit_no": "22",
          "st_name": "North Bridge Rd",
          "postal_code": "149281"
        },
        ...
      }}
    ]
    

    If executed correctly the response body is a JSON array with a list of employees, which should be similar to this snippet ->

    Request

    https://api.payroll.simplepay.cloud/v1/clients/:client_id/employees?include=service_periods
    

    Response

    [
      {"employee": {
        "first_name": "Kenneth",
        "last_name": "Parker",
        "birthdate": "1985-02-06",
        "appointment_date": "2010-02-06",
        ...
        "service_periods": [
          {"service_period": {
            "id": 1110,
            "employee_id": 12345,
            "start_date": "2016-08-01",
            "end_date": "2019-10-18",
            "negative": false,
            "created_at": "2016-08-02T12:57:20.313+02:00",
            "updated_at": "2019-09-11T09:56:16.415+02:00",
            "attribs": null,
            "termination_code": 2
          }},
          ...
        ]
      }}
    ]
    

    Request

    https://api.payroll.simplepay.cloud/v1/clients/:client_id/employees?include=recent_payslips
    

    Response

    [
      {"employee": {
        "first_name": "Kenneth",
        "last_name": "Parker",
        "birthdate": "1985-02-06",
        ...
        "recent_payslips": [
          {"payslip": {
            "id": 43,
            "date": "2017-09-27",
            "special": false,
            "finalised": true,
            "ss_released": true,
            "payment_run_id": 87908,
            "dirty": false,
            "nett_pay": 3480.02
          }},
          ...
        ]
      }}
    ]
    

    Request

    https://api.payroll.simplepay.cloud/v1/clients/:client_id/employees?include=recent_payslips_with_data
    

    Response

    [
      {"employee": {
        "first_name": "Kenneth",
        "last_name": "Parker",
        "birthdate": "1985-02-06",
        ...
        "recent_payslips_with_data": [
          {"payslip": {
            "id": 24017537,
            "date": "2017-09-27",
            "special": false,
            "finalised": true,
            "ss_released": true,
            "payment_run_id": nil,
            "dirty": false,
            "nett_pay": 3480.02,
            "data": {
              "income": [["Extra Pay", "2000.0"], ["Total", "2000.0"]],
              "deduction": [["UIF - Employee", "20.0"], ["Tax (PAYE)", "360.0"], ["Total", "380.0"]],
              "grand_total": [["Nett Pay", "1620.0"]],
              "sideline": [["Employer contribution", [["SDL - Employer", "20.0"], ["UIF - Employer", "20.0"], ["Total", "40.0"]]]],
              "leave_payments": {},  
            }
          }},
          ...
        ]
      }}
    ]
    

    Get a specific Employee

    Request

    Request

    https://api.payroll.simplepay.cloud/v1/employees/:id
    

    This is an HTTP GET request to URL ->

    Where the parameter :id is the ID of a specific employee obtained from the call to get a list of employees.

    Response

    Response

      {
        "employee":{
        "first_name": "Kenneth",
        "last_name": "Parker",
        "birthdate": "1985-02-06",
        "appointment_date": "2010-02-06",
        "wave_id": 2,
        "payment_method": "cash",
        "physical_address": {
          "unit_no": "22",
          "st_name": "North Bridge Rd",
          "postal_code": "149281"
        },
        "custom_fields":
        {
          "7651": "4",
          "53621": "011 568 0721"
        },
        ...
      }
    }
    

    If executed correctly the response body is a JSON array with a list of employees, which should be similar to this snippet ->

    Create an Employee

    Request

    Request

    https://api.payroll.simplepay.cloud/v1/clients/:client_id/employees
    

    This is an HTTP POST request to URL ->

    Where the parameter :client_id is the ID of a specific client obtained from the call to get a list of clients.

    Request Body

    Request Body

    { "employee": {
      "wave_id": 1350675273,
      "first_name": "Alice",
      "last_name": "Williams"
      ...
    }}
    

    The request body should be a JSON object containing the details of the employee to be saved. An abbreviated request body sample is shown to the right ->

    There are several required attributes for creating an employee, as well as certain optional ones. The applicability of the various attributes will vary depending on the individual employee. Please see the examples to the right of the Employee Attributes tables below.

    Response

    Response

    {
      "message": "Employee has been created/updated",
      "id": 22304,
      "number: "0012"
    }
    

    If executed correctly the response body is a JSON object with details of the transaction and the ID of the created employee, and should be similar to this snippet ->

    Employee Attributes

    Request body - Female Muslim Chinese Singapore Citizen paid by GIRO

    { "employee": {
      "wave_id": 1350676447,
      "first_name": "Juliet",
      "last_name": "Tang",
      "name_format": 2,
      "birthdate": "1985-02-06",
      "appointment_date": "2010-02-06",
      "legal_status": "CITIZEN",
      "nric": "S8785154J",
      "gender": "M",
      "race": "CHINESE",
      "religion": "MUSLIM",
      "sdl_exempt": "false",
      "cpf_exempt": "false",
      "payment_method": "eft_manual",
      "bank_account": {
        "bank_id": 2081327566,
        "account_number": "123456778",
        "branch_code": "456"
      },
      "number": "00002"
    }}
    

    Request body - Male Buddhist Eurasian Singapore Permanent Resident paid via cheque

    { "employee": {
      "wave_id": 1350676447,
      "first_name": "Jeffery",
      "last_name": "Walsh",
      "birthdate": "1985-02-06",
      "appointment_date": "2010-02-06",
      "legal_status": "PR",
      "nationality": "354",
      "nric": "S8785154J",
      "pr_date" : "2009-01-01",
      "gender": "M",
      "race": "EURASIAN",
      "religion": "BUDDHIST",
      "sdl_exempt": false,
      "cpf_exempt": false,
      "payment_method": "cheque",
      "physical_address":
      {
        "type": "L",
        "block_no": "5",
        "st_name": "Orchard Link",
        "level_no": "22",
        "unit_no": "6",
        "postal_code": "237978"
      },
      "number": "1234567"
    }}
    

    Request body - Male Christian Indian Foreigner with a Work Permit and paid cash

    { "employee": {
      "wave_id": 1350676447,
      "first_name": "Nitesh",
      "last_name": "Pillay",
      "name_format": 1,
      "birthdate": "1985-02-06",
      "appointment_date": "2010-02-06",
      "legal_status": "FOREIGNER_WP",
      "nationality": "354",
      "fin": "F9864842U",
      "gender": "M",
      "race": "INDIAN",
      "religion": "CHRISTIAN",
      "sdl_exempt": "false",
      "cpf_exempt": "false",
      "payment_method": "cash",
      "number": "EMP003",
      "custom_fields":
      {
        "8764": true,
        "53621": "011 568 0721"
      }
    }}
    

    Request body - Foreign address

    { "employee": {
      "wave_id": 1350676447,
      "first_name": "Nitesh",
      "last_name": "Pillay",
      "name_format": 2,
      "birthdate": "1985-02-06",
      "appointment_date": "2010-02-06",
      "legal_status": "FOREIGNER_WP",
      "nationality": "354",
      "fin": "F9864842U",
      "gender": "M",
      "race": "INDIAN",
      "religion": "CHRISTIAN",
      "sdl_exempt": false,
      "cpf_exempt": false,
      "payment_method": "cash",
      "physical_address": {
        "type": "F",
        "address_line1": "123",
        "address_line2": "Moreton Drive",
        "address_line3": "Queensland",
        "tx_uf_postal_code": "4008",
        "country_code": "701"
      },
      "number": "EMP005"
    }}
    

    The following attributes may be required for the creation of an employee. Certain attributes are always required while others are only conditionally required based on the value of another attribute. There are also certain optional attributes, which can be ignored for creation and added during an update if required.

    Parent Attributes

    Attribute Details Type Applicability
    wave_id The ID of the wave to which the employee belongs Integer Required
    first_name Employee first name String Required
    last_name Employee last name String Required
    name_format Order in which the employee's first and last name will be used. The following are valid values:
    • 1 - First name Last name
    • 2 - Last name First name
    • 3 - Single name (specified in the first_name field)
    Integer Optional, will default to "1" unless overridden.
    payment_method Method by which employee is paid. The following are valid values:
    • "cash"
    • "cheque"
    • "eft_manual" (for employees paid by GIRO)
    String Required
    birthdate Employee date of birth in the format YYYY-MM-DD Date String Required
    appointment_date The date of appointment in the format YYYY-MM-DD Date String Required
    legal_status Employee legal status in Singapore. The following are valid values:
    • "CITIZEN" - Singapore Citizen
    • "PR" - Singapore Permanent Resident
    • "FOREIGNER" - Foreigner without a Work Permit
    • "FOREIGNER_WP" - Foreigner with a Work Permit
    • "FD_MALAYSIA" - Malaysian foreign director
    • "FD_OTHER" - Any other foreign director
    String Required
    nric Employee NRIC starting with "S" or "T" String Required if legal_status is "CITIZEN" or "PR"
    fin Employee FIN String Required if legal_status is "FOREIGNER" or "FOREIGNER_WP"
    malaysian_ic Employee Malaysian IC String Required if legal_status is "FD_MALAYSIA"
    passport_number Employee passport number String Required if legal_status is "FD_OTHER"
    nationality Employee nationality. Please see the Data Lists section for valid values String Required if legal_status is "PR", "FOREIGNER", "FOREIGNER_WP", "FD_MALAYSIA" or "FD_OTHER".
    pr_date Employee date of attaining Singaporean PR status in format YYYY-MM-DD Date String Required if legal_status is "PR"
    gender Employee gender. The following are valid values:
    • "M" - Male
    • "F" - Female
    String Required
    race Employee race. Used to determine applicability of Self-Help Group Funds. Please see the Data Lists section for valid values String Required
    religion Employee religion. Used to determine applicability of Self-Help Group Funds. Please see the Data Lists section for valid values String Required
    sdl_exempt Employee SDL exempt indicator Boolean Required
    cpf_exempt Employee CPF exempt indicator Boolean Required
    bank_account Employee bank details object. Please see Child Attributes table below Hash Required if payment_method is "eft_manual"
    physical_address Employee address object. Please see Child Attributes table below Hash Optional
    number Employee identifying number for payroll purposes. String Required if client employee_number_mode is "EMPLOYEE_NUMBER_MANUAL" - must be set via UI
    custom_fields Custom employee fields object. Please see Child Attributes table below Hash Optional

    Child Attributes

    Parent Attribute Details Type Applicability
    bank_id bank_account ID of employee bank. Please see the Data Lists section for valid values Integer Required for parent
    account_number Employee bank account number of minimum four (4) characters String Required for parent
    branch_code Employee bank branch code of three (3) characters String Required for parent
    physical_address type Employee address type. The following are valid values:
    • "L" - Local residential address
    • "F" - Foreign address
    • "C" - Local C/O address
    • "N" - Not available
    String Required for parent
    block_no Street number of employee local physical address String Optional. Only if type is "L"
    st_name Street name of employee local physical address String Optional. Only if type is "L"
    level_no Building level of employee local physical address String Optional. Only if type is "L"
    unit_no Unit number of employee local physical address String Optional. Only if type is "L"
    postal_code Postal code of employee local physical address String Optional. Only if type is "L"
    address_line1 First line of employee foreign or C/O physical address String Optional. Only if type is "F" or "C"
    address_line2 Second line of employee foreign or C/O physical address String Optional. Only if type is "F" or "C"
    address_line3 Third line of employee foreign or C/O physical address String Optional. Only if type is "F" or "C"
    tx_uf_postal_code Postal code for employee foreign or C/O physical address String Optional. Only if type is "F" or "C"
    country_code Country code for employee foreign physical address. Please see the Data Lists section for valid values String Optional. Only if type is "F"
    custom_fields [Custom Field ID] Custom employee fields are identified using numerical ID keys. Values for dropdown options are also returned as IDs.
    There is currently no endpoint to retrieve custom fields so, for now, these can both be found by inspecting the HTML of the input element on an employee's Basic Info page.
    Specified in field definition Specified in field definition

    Data Lists

    The valid values for the following employee attributes can be found by unhiding the Constants sheet in the SimplePay bulk import / export file:

    This file can be downloaded through the UI by going to Employees > Bulk Actions > Bulk Add Employees.

    Update an Employee

    Request

    Request

    https://api.payroll.simplepay.cloud/v1/employees/:id
    

    This is an HTTP PATCH request to URL ->

    Where the parameter :id is the SimplePay system ID of an employee.

    Request Body

    Request body

    { "employee": {
      "first_name": "Alice",
      "last_name": "Williams",
      "birthdate": "1985-02-06",
    }}
    

    The request body should be a JSON object containing the details of the employee to be changed. An example is shown ->

    You only need to send those attributes which need to be changed for an employee.

    Response

    Response

    {
      "message": "Employee has been created/updated",
      "id": 1,
      "number": "0001"
    }
    

    If executed correctly the response body is a JSON object with details of the transaction, and should be similar to this snippet ->

    Delete an employee

    Request

    Request

    https://api.payroll.simplepay.cloud/v1/employees/:id
    

    This is an HTTP DELETE request to URL ->

    Where the parameter :id is the SimplePay system ID of an employee.

    Response

    Response

    {
      "message": "Employee with number 1100 has been deleted."
    }
    

    If executed correctly the response body is a JSON object with details of the transaction, and should be similar to this snippet ->

    Payment Frequencies

    Get a list of Payment Frequencies

    Request

    Request

    https://api.payroll.simplepay.cloud/v1/clients/:client_id/waves
    

    This is an HTTP GET request to URL ->

    Where the parameter :client_id is the ID of a specific client obtained from the call to get a list of clients.

    Including the parameter format=simplified will result in simplified descriptions of the payment frequencies that use a text frequency value instead of describing the frequency using length_months and length_weeks.

    Note that, for most frequency types, first_end_date as provided by this request is normalised to be a date in January 2008 or 2009. The period_offset can be used to determine the end date specified during the pay frequency creation. The period_offset is the number of pay periods (e.g. months) between the normalised first_end_date and the date provided during creation.

    If it applies to the frequency, interim_first_end_date is also a normalised date.

    Response

    Response

    [
      {"wave":{
        "id":1350761618,
        "length_months":1,
        "length_weeks":0,
        "first_end_date":"2008-01-31",
        "first_period_offset":139,
        "notification_days_before":null,
        "finalisation_days_before":null,
        "client_id":84407,
        "interim_first_end_date":null,
        "created_at":"2019-08-22T16:52:08.336+02:00",
        "updated_at":"2019-08-22T16:52:08.336+02:00",
        "payslip_payment_day":null,
        "custom_name":null,
        "pay_dates":{
          "enabled":false
        },
        "name": "Monthly, ending on the 31st"
      }}
      ...
    ]
    

    Response - Simplified Format

    [
      {"wave":{
        "id":1350761618,
        "first_end_date":"2008-01-31",
        "client_id":84407,
        "interim_first_end_date":null,
        "created_at":"2019-08-22T16:52:08.336+02:00",
        "updated_at":"2019-08-22T16:52:08.336+02:00",
        "custom_name":null,
        "pay_dates":{
          "enabled":false},
        "frequency":"monthly",
        "name": "Monthly, ending on the 31st"
      }},
      ...
    ]
    

    If executed correctly the response body is a JSON array with a list of payment frequencies (called 'waves' on the SimplePay system), which should be similar to this snippet ->

    Create a Pay Frequency

    Request

    Request

    https://api.payroll.simplepay.cloud/v1/clients/:client_id/waves
    

    This is an HTTP POST request to URL ->

    Where the parameter :client_id is the ID of a specific client obtained from the call to get a list of clients.

    Request Body

    Request Body

    {
      "frequency": "monthly",
      "last_day_of_month": "31",
      "first_end_date": "2019-05-31"
    }
    

    The request body should be a JSON object containing the details of the pay frequency to be saved. A request body sample is shown to the right ->

    There are several required attributes for creating a pay frequency, as well as certain optional ones. The applicability of the various attributes will vary depending on the client and the type of frequency. Please see the Pay Frequency Attributes table below for details.

    Pay Frequency Attributes

    Attribute Details Type Applicability
    frequency The following are valid values:
    • "weekly"
    • "fortnightly"
    • "twice_a_month"
    • "monthly"
    String Required
    interim_day_of_month The interim day of the month. A number between 1 and 31. Integer Optional unless frequency is "twice_a_month"
    last_day_of_month The last day of the month. A number between 1 and 31. Integer Optional unless frequency is "monthly" or "twice_a_month".
    first_end_date The end date of the first period in the format YYYY-MM-DD.
    Note that first_end_date is not stored in the database exactly as provided here. See Get a list of Payment Frequencies for details.
    Date String Required
    custom_name A custom name for the pay frequency String Optional. Setting this will throw an error unless the feature is enabled for the client.
    pay_dates Pay dates object. Please see Pay Dates Attributes table below Hash Optional. Setting this will throw an error unless the feature is enabled for the client.

    Pay Dates Attributes

    Attribute Details Type Applicability
    enabled Determines if pay dates will be used. Boolean Required for parent
    type The pay date schedule type. The following are valid values:
    • "relative"
    • "fixed"
    String Required for parent. If frequency is "weekly" or "fortnightly" then type must be "relative".
    days_offset The offset between the payslip end date and pay date Integer Required if type is "relative"
    when For type "relative" this determines whether the pay date is before or after the payslip end date. The following are valid values:
    • "before"
    • "after"
    For type "fixed" this determines in which month the pay date occurs. The following are valid values:
    • "previous"
    • "current"
    • "next"
    String Required for parent
    day The day in the month of a fixed pay date. A number between 1 and 31. Integer Required if type is "fixed"
    interim_day The interim day in the month of a fixed pay date. A number between 1 and 31. Integer Required if frequency is "twice_a_month" and type is "fixed"
    interim_when This determines in which month the pay date occurs. The following are valid values:
    • "previous"
    • "current"
    • "next"
    String Required if frequency is "twice_a_month" and type is "fixed"

    Response

    Response

    {
      "message": "Wave has been created/updated",
      "id": 234
    }
    

    If executed correctly the response body is a JSON object with details of the transaction and the ID of the created wave (pay frequency), and should be similar to this snippet ->

    Pay Points

    Get a list of Pay Points

    Request

    Request

    https://api.payroll.simplepay.cloud/v1/clients/:client_id/pay_points
    

    This is an HTTP GET request to URL ->

    Where the parameter :client_id is the ID of a specific client obtained from the call to get a list of clients.

    Response

    Response

    [
      {"pay_point":{
        "id":1,
        "name":"Pay Point 1",
        "created_at":"2017-08-10T16:01:01.471+02:00",
        "updated_at":"2017-08-10T16:01:01.471+02:00",
        "client_id":2,
        "physical_address":{
          "unit_no": "107",
          "st_name": "Rivonia Rd.",
          "postal_code": "2196"
        },
      }}
      ...
    ]
    

    If executed correctly the response body is a JSON array with a list of pay points, which should be similar to this snippet ->

    Payslips

    Get a list of Payslips for an Employee

    Request

    Request

    https://api.payroll.simplepay.cloud/v1/employees/:employee_id/payslips
    

    This is an HTTP GET request to URL ->

    Where the parameter :client_id is the ID of a specific client, obtained from the call to get a list of clients, and the parameter :employee_id is the ID of a specific employee, obtained from the call to get a list of employees.

    Note: Payslips whose calculations are still in progress will have the dirty attribute set to true, and nett_pay attribute unavailable in the response. Please try again later to obtain nett pay.

    Response

    Response

    [
      {
        "payslip": {
          "id":43,
          "date":"2017-09-27",
          "special":false,
          "finalised":true,
          "dirty":false,
          "nett_pay":3480.02,
          "ss_released": true,
          "payment_run_id": 87908
        }
      },
      {
        "payslip": {
          "id":44,
          "date":"2017-10-04",
          "special":false,
          "finalised":false,
          "dirty":true,
          "ss_released": false,
          "payment_run_id": 89879
        }
      }
    ]
    

    If executed correctly the response body is a JSON array with a list of payslips, which should be similar to this snippet ->

    Get a Specific Payslip for an Employee

    Request

    Request

    https://api.payroll.simplepay.cloud/v1/payslips/:payslip_id
    

    This is an HTTP GET request to URL ->

    Where the parameter :payslip_id is the ID of a particular payslip, obtained from the above call to list the payslips.

    Response

    Response

    {"payslip":
      {"income":[
          ["basic_salary","10000.0"],
          ["total","10000.0"]
        ],
      "deduction":[
          ["sinda","12.0"],
          ["cpf_employee","450.0"],
          ["total","462.0"]
        ],
        "grand_total":[
          ["nett_pay","9538.0"]
        ],
        "sideline":[
          ["employer_contribution",
              [["cpf_employer","540.0"],
              ["sdl_employer","11.25"],
              ["total","551.25"]
            ]
          ]
        ],
        "leave":{
          "annual_leave":{
            "accrual":"1.1667",
            "taken":0,
            "balance":"3.5001"
          },
          "sick_leave":{
            "accrual":0,
            "taken":0,
            "balance":"14.0"
          },
          "id":1701992
        }
      }
    }
    

    If executed correctly the response body is a JSON object containing the relevant information for the payslip, similar to this snippet ->

    The contents of the first hash after the ID correspond to the various items on the particular payslip. This information will therefore depend on how each employee's payslip is set up, i.e. what income, deduction, allowance etc items they have:

    The contents of the second hash relate to the employee's leave types and balances.

    Requesting a PDF payslip

    Request

    https://api.payroll.simplepay.cloud/v1/payslips/:payslip_id.pdf
    

    This is an HTTP GET request to URL ->

    Response

    If successful, this will return the binary data for the PDF version of the payslip. Note: you should ideally send the Content-Type: application/pdf header as part of the request.

    Pay Runs

    Get a list of Pay Runs

    Request

    This is an HTTP GET request to URL ->

    Where the parameter :client_id is the ID of a specific client obtained from the call to get a list of clients.

    Request

    https://api.payroll.simplepay.cloud/v1/clients/:client_id/payment_runs
    

    Response

    If executed correctly the response body is a JSON array with a list of pay runs, which should be similar to this snippet ->

    Response

    [
      {
        "payment_run": {
          "id": 2890831,
          "wave_id": 1350864197,
          "period_offset": 171,
          "period_end_date": "2022-04-30",
          "total": 22809.55,
          "created_at": "2022-05-27T09:45:59.592+02:00",
          "updated_at": "2022-05-27T09:45:59.592+02:00",
          "special": false
        }
      },
      {
        "payment_run": {
          "id": 2890811,
          "wave_id": 1350864197,
          "period_offset": 170,
          "period_end_date": "2022-03-31",
          "total": 22966.38,
          "created_at": "2022-05-27T09:45:05.843+02:00",
          "updated_at": "2022-05-27T09:45:05.843+02:00",
          "special": false
        }
      }
    ]
    

    Get a list of Payslips in a Pay Run

    Request

    This is an HTTP GET request to URL ->

    Where the parameter :payment_run_id is the ID of a specific pay run obtained from the call to get a list of pay runs in a client.

    Request

    https://api.payroll.simplepay.cloud/v1/payment_runs/:payment_run_id/payslips
    

    Response

    If executed correctly the response body is a JSON array with a list of payslips in the pay run, which should be similar to this snippet ->

    Response

    [
      {
        "payslip": {
          "id": 30796888,
          "date": "2023-04-30",
          "special": false,
          "finalised": true,
          "ss_released": false,
          "payment_run_id": 2890831,
          "dirty": false,
          "nett_pay": 9536.25,
          "data": {
            "income": [
              [
                "Basic Salary",
                "10000.0"
              ],
              [
                "Total",
                "10000.0"
              ]
            ],
            "deduction": [
              [
                "UIF - Employee",
                "100.0"
              ],
              [
                "Tax (PAYE)",
                "363.75"
              ],
              [
                "Total",
                "463.75"
              ]
            ],
            "grand_total": [
              [
                "Nett Pay",
                "9536.25"
              ]
            ],
            "sideline": [
              [
                "Employer contribution",
                [
                  [
                    "SDL - Employer",
                    "100.0"
                  ],
                  [
                    "UIF - Employer",
                    "100.0"
                  ],
                  [
                    "Total",
                    "200.0"
                  ]
                ]
              ]
            ],
            "leave_payments": {}
          }
        }
      }
      ...
    ]
    
    

    Get the Accounting Journal Info of a Pay Run

    Request

    This is an HTTP GET request to URL ->

    Where the parameter :payment_run_id is the ID of a specific pay run obtained from the call to get a list of pay runs in a client.

    Request

    https://api.payroll.simplepay.cloud/v1/payment_runs/:payment_run_id/accounting
    

    Response

    If executed correctly the response body is a JSON array with the accounting journal info of the pay run, which should be similar to this snippet -> If Accounting Splits are not set up, they will not be included in the response. See the second example response.

    Response - With Accounting Splits

    [
      {
        "accounting_splits": [
          {
            "id": "9940",
            "name": "Split A"
          },
          {
            "id": "9941",
            "name": "Split B"
          }
        ],
        "debit": [
          {
            "category": "salary_expense",
            "line_item": "basic_salary",
            "label": "Basic Salary",
            "amount": {
              "9940": 10000,
              "9941": 20000
            }
          },
          {
            "category": "expense",
            "line_item": "sdl_employer",
            "label": "SDL - Employer",
            "amount": {
              "9940": 100,
              "9941": 200
            }
          },
          {
            "category": "expense",
            "line_item": "uif_employer",
            "label": "UIF - Employer",
            "amount": {
              "9940": 100,
              "9941": 200
            }
          }
        ],
        "credit": [
          {
            "category": "liability",
            "line_item": "tax",
            "label": "Tax (PAYE)",
            "amount": {
              "9940": 363.75,
              "9941": 727.5
            }
          },
          {
            "category": "liability",
            "line_item": "nett_pay",
            "label": "Nett Pay",
            "amount": {
              "9940": 9536.25,
              "9941": 19072.5
            }
          },
          {
            "category": "liability",
            "line_item": "uif_total",
            "label": "UIF Total",
            "amount": {
              "9940": 200,
              "9941": 400
            }
          },
          {
            "category": "liability",
            "line_item": "sdl_employer",
            "label": "SDL - Employer",
            "amount": {
              "9940": 100,
              "9941": 200
            }
          }
        ]
      }
      ...
    ]
    
    

    Response - Without Accounting Splits being set up

    [
      {
        "accounting_splits": [],
        "debit": [
          {
            "category": "salary_expense",
            "line_item": "basic_salary",
            "label": "Basic Salary",
            "amount": {
              "": 30000
            }
          },
          {
            "category": "expense",
            "line_item": "sdl_employer",
            "label": "SDL - Employer",
            "amount": {
              "": 300
            }
          },
          {
            "category": "expense",
            "line_item": "uif_employer",
            "label": "UIF - Employer",
            "amount": {
              "": 300
            }
          }
        ],
        "credit": [
          {
            "category": "liability",
            "line_item": "tax",
            "label": "Tax (PAYE)",
            "amount": {
              "": 1091.25
            }
          },
          {
            "category": "liability",
            "line_item": "nett_pay",
            "label": "Nett Pay",
            "amount": {
              "": 28608.75
            }
          },
          {
            "category": "liability",
            "line_item": "uif_total",
            "label": "UIF Total",
            "amount": {
              "": 600
            }
          },
          {
            "category": "liability",
            "line_item": "sdl_employer",
            "label": "SDL - Employer",
            "amount": {
              "": 300
            }
          }
        ]
      }
      ...
    ]
    
    

    Reports

    General

    Filtering on Employee IDs and Wave IDs

    Humanizing the Data

    Backwards Compatibility

    The following section has been updated to use our advised method of retrieving reports through POST requests, however we will continue to support the GET requests as described previously.

    Transaction History Report

    Request

    https://api.payroll.simplepay.cloud/v1/clients/:client_id/reports/transaction_history
    

    Request

    This is an HTTP POST request to URL ->

    Where the parameter :client_id is the ID of a specific client, obtained from the call to get a list of clients. transaction_history is the ID for this report

    Request Body

    {
      "start_date": "2017-12-01",
      "end_date": "2017-12-31",
      "wave_ids": [1,2],
      "employee_ids": [6,2],
      "account_names": ["basic_salary","tax"],
      "humanize": true
    }
    
    

    Request Body

    The request body should be a JSON object. It contains the fields that will determine which information is included in the report.

    Name Type Examples
    start_date String "2016-11-23"
    end_date String "2017-02-13"
    wave_ids Array null or [2, 3]
    employee_ids Array null or [6, 7, 9]
    account_names Array ["basic_salary", "medical_aid_self", "pension_fund_employee", "tax"]
    custom_fields Array null or ["first_name", "last_name", "pay_point_id", "appointment_date"]
    humanize Boolean null, true, false

    Account Names

    Unfortunately for now, in order to retrieve the account names, you'll have to generate a report on the front end with the accounts selected and inspect the request URL.

    Custom Fields

    As with Account Names, in order to retrieve the available custom fields, you'll have to generate a report on the front end with the custom fields (Additional Fields) selected and then inspect the request URL. In addition, "first_name" and "last_name" have been made available as custom fields.

    Response

    [
      {"employee":"6","Date":"2017-12-31","Basic Salary":"R 15,000.00","Tax":"R 1,473.75"},
      {"employee":"2","Date":"2017-12-31","Basic Salary":"R 12,000.00","Tax":"R 1,023.75"}
    ]
    

    Response

    If executed correctly the response body is a JSON object containing the relevant information for the report, similar to this snippet ->

    The response comes back in the form of an array of hashes, each hash containing the data relevant to a certain employee, identified by the employee number as given in the request.

    Variance Report

    Request

    https://api.payroll.simplepay.cloud/v1/clients/:client_id/reports/variance
    

    Request

    This is an HTTP POST request to URL ->

    Where the parameter :client_id is the ID of a specific client, obtained from the call to get a list of clients. variance is the ID for this report

    Request Body

    {
      "wave_id": 1,
      "period_offset": 119, 
      "employee_ids": [6], 
      "humanize": true
    }
    

    Request Body

    The request body should be a JSON object. It contains the fields that will determine which information is included in the report.

    Name Type Examples
    wave_id Number 131
    employee_ids Array null or [6, 7, 9]
    period_offset Number 112
    humanize Boolean null, true, false

    Period offset ID

    In order to get this ID, please generate a report on the front end and check for the IDs you need in the request URL.

    Response

    [
      {"employee":"6","Type":"Benefit","Transaction":{"taxable_income":1,"retirement_funding_income":0,"non_retirement_funding_income":1,"uif_income":1,"sdl_income":1,"type":"benefit","cost_to_company_account":"pension_fund_employer","code":3817,"name":"pension_fund_benefit","formula":{},"frequency":"regular","calculation_output":true},"Previous":"R 300.00","Selected":"R 300.00","Variance":"R 0.00"},
      {"employee":"6","Type":"Deduction","Transaction":{"type":"deduction","caption":"Pension Fund - Employee","code":4001,"accounting":{"group":"exclude"},"name":"pension_fund_employee","formula":{},"frequency":"regular","calculation_output":true},"Previous":"R 500.00","Selected":"R 500.00","Variance":"R 0.00"},
      {"employee":"6","Type":"Deduction","Transaction":{"name":"tax","caption":"Tax","description":"Tax","type":"deduction","trace":true},"Previous":"R 1,473.75","Selected":"R 1,473.75","Variance":"R 0.00"},
      {"employee":"6","Type":"Deduction","Transaction":{"name":"uif_self","caption":"UIF - Employee","description":"UIF - Employee","type":"deduction","accounting":{"group":"exclude"}},"Previous":"R 148.72","Selected":"R 148.72","Variance":"R 0.00"},
      {"employee":"6","Type":"Employer contribution","Transaction":{"type":"employer_contribution","caption":"Pension Fund - Employer","taxable_income":0,"code":4472,"name":"pension_fund_employer","formula":{},"frequency":"regular","calculation_output":true},"Previous":"R 300.00","Selected":"R 300.00","Variance":"R 0.00"},
      {"employee":"6","Type":"Employer contribution","Transaction":{"name":"sdl_employer","caption":"SDL - Employer","description":"SDL - Employer","type":"employer_contribution","accounting_addition":{"group":"liability"},"code":4142},"Previous":"R 145.00","Selected":"R 145.00","Variance":"R 0.00"},
      {"employee":"6","Type":"Employer contribution","Transaction":{"name":"uif_employer","caption":"UIF - Employer","description":"UIF - Employer","type":"employer_contribution"},"Previous":"R 148.72","Selected":"R 148.72","Variance":"R 0.00"},
      {"employee":"6","Type":"Income","Transaction":{"taxable_income":1,"uif_income":1,"sdl_income":1,"type":"income","caption":"Basic Salary","frequency":"regular","fractional":true,"name":"basic_salary","formula":{},"calculation_output":true},"Previous":"R 15,000.00","Selected":"R 15,000.00","Variance":"R 0.00"},
      {"employee":"6","Type":"Summary","Transaction":{"name":"gross_remuneration","caption":null,"type":"summary"},"Previous":"R 15,300.00","Selected":"R 15,300.00","Variance":"R 0.00"},
      {"employee":"6","Type":"Summary","Transaction":{"name":"taxable_income","caption":"Gross Remuneration - Taxable Portion (before deductions)","description":"Gross Remuneration - Taxable Portion (before deductions)","type":"summary"},"Previous":"R 15,300.00","Selected":"R 15,300.00","Variance":"R 0.00"},
      {"employee":"6","Type":"Taxable income deduction","Transaction":{"name":"retirement_deduction","caption":null,"type":"taxable_income_deduction"},"Previous":"R 800.00","Selected":"R 800.00","Variance":"R 0.00"},
      {"employee":"6","Type":"Total","Transaction":{"name":"nett_pay","caption":"Nett Pay","description":"Nett Pay","type":"total"},"Previous":"R 12,877.53","Selected":"R 12,877.53","Variance":"R 0.00"}
    ]
    

    Response

    If executed correctly the response body is a JSON object containing the relevant information for the report, similar to this snippet ->

    The response comes back in the form of an array of hashes, each hash containing the data relevant to a certain employee, identified by the employee number as given in the request.

    Comparison Leave Report

    Request

    https://api.payroll.simplepay.cloud/v1/clients/:client_id/reports/comparison_leave
    

    Leave Types

    In order to get the leave type IDs, generate a report on the front end with the leave types selected and inspect the request URL.

    Request

    This is an HTTP POST request to URL ->

    Where the parameter :client_id is the ID of a specific client, obtained from the call to get a list of clients. comparison_leave is the ID for this report

    Request Body

    The request body should be a JSON object. It contains the fields that will determine which information is included in the report.

    {
      "start_date": "2017-12-01",
      "end_date": "2017-12-31",
      "wave_ids": [1,2],
      "employee_ids": [6,2],
      "leave_types": [5,6],
      "humanize": true
    }
    

    Request Body

    Name Type Examples
    start_date String "2016-11-23"
    end_date String "2017-02-13"
    wave_ids Array null or [2, 3]
    employee_ids Array null or [6, 7, 9]
    leave_types Array [5, 6]
    humanize Boolean null, true, false

    Response

    [
      {"employee":"6","leave_type":"Annual","Date":"2017-12-31","Accrual":"1.25","Entitlement":"3.75","Taken":null,"Adjustment":null,"Balance":"18.75"},
      {"employee":"6","leave_type":"Sick","Date":"2017-12-31","Accrual":null,"Entitlement":"30.00","Taken":null,"Adjustment":null,"Balance":"30.00"},
      {"employee":"2","leave_type":"Annual","Date":"2017-12-31","Accrual":"1.25","Entitlement":"5.81","Taken":null,"Adjustment":null,"Balance":"5.81"},
      {"employee":"2","leave_type":"Sick","Date":"2017-12-31","Accrual":null,"Entitlement":"30.00","Taken":null,"Adjustment":null,"Balance":"30.00"}
    ]
    

    Response

    If executed correctly the response body is a JSON object containing the relevant information for the report, similar to this snippet ->

    The response comes back in the form of an array of hashes, each hash containing the data relevant to a certain employee, identified by the employee number as given in the request.

    Leave Liabilities Report (BETA)

    Request

    https://api.payroll.simplepay.cloud/v1/clients/:client_id/reports/leave_liability_v2
    

    Request

    This is an HTTP POST request to URL ->

    Where the parameter :client_id is the ID of a specific client, obtained from the call to get a list of clients. leave_liability_v2 is the ID for this report

    Request Body

    {
      "date": "2017-12-31",
      "wave_ids": [1,2],
      "employee_ids": [6,2],
      "humanize": true
    }
    

    Request Body

    The request body should be a JSON object. It contains the fields that will determine which information is included in the report.

    Name Type Examples
    date String "2016-11-23"
    wave_ids Array null or [2,3]
    employee_ids Array null or [6,7,9]
    humanize Boolean null, true, false

    Response

    Response

    [
      {"employee":"6","Days":"18.75","Daily Rate":"R 692.31","Liability":"R 12,980.78"},
      {"employee":"2","Days":"5.81","Daily Rate":"R 553.85","Liability":"R 3,215.91"}
    ]
    

    If executed correctly the response body is a JSON object containing the relevant information for the report, similar to this snippet ->

    The response comes back in the form of an array of hashes, each hash containing the data relevant to a certain employee, identified by the employee number as given in the request.

    Tracked Balances Report (BETA)

    Parameters

    Request

    https://api.payroll.simplepay.cloud/v1/clients/:client_id/reports/tracked_balances
    

    Request

    This is an HTTP POST request to URL ->

    Where the parameter :client_id is the ID of a specific client, obtained from the call to get a list of clients. tracked_balances is the ID for this report

    Request Body

    {
      "wave_ids": [1,2],
      "employee_ids": [6,2],
      "date": "2017-12-31",
      "humanize": true
    }
    

    Request Body

    The request body should be a JSON object. It contains the fields that will determine which information is included in the report.

    Name Type Examples
    date String "2016-11-23"
    wave_ids Array null or [2,3]
    employee_ids Array null or [6,7,9]
    humanize Boolean null, true, false

    Response

    Response

    [
      {"employee":"6","Loans":"R 10000.00","Savings":"R 110.00","Garnishees":"R 0.00"},
      {"employee":"2","Loans":"R 2000.00","Savings":"R 0.00","Garnishees":"R 0.00"}
    ]
    

    If executed correctly the response body is a JSON object containing the relevant information for the report, similar to this snippet ->

    The response comes back in the form of an array of hashes, each hash containing the data relevant to a certain employee, identified by the employee number as given in the request.

    Large Reports

    This section should be used if the caller expects significant data to be pulled from a specific report and is likely to time out. There is no guarantee that the report will get executed immediately (as it gets queued), so please ensure that this is used from a batch process or appropriate UI is shown to the end user and the status polled every 10 seconds (at the minimum).

    By following the below steps, the report can be run and later retrieved with a Universally Unique Identifier (UUID).

    Request 1

    https://api.payroll.simplepay.cloud/v1/clients/:client_id/reports/:report/async
    

    Request 1

    This is an HTTP POST request to URL ->

    Where the only change to the report endpoint is the addition of the /async in the path.

    Request Body 1

    The Request Body is specific to the report.

    Response 1

    [
      {"message":"Started","uuid":"ad8b49de-fa5c-4603-8831-b26cb086941a"}
    ]
    

    Response 1

    If executed correctly the response status is HTTP 200 and the response body is a JSON object containing the UUID, similar to this snippet ->

    A response status of HTTP 429 signifies that too many requests are already queued.

    The UUID can be used in the Request 2 section to verify the status of the report.

    Request 2

    https://api.payroll.simplepay.cloud/v1/clients/:client_id/reports/poll/:uuid
    

    Request 2

    This is an HTTP GET request to URL ->

    Where the parameter :client_id is the ID of the specific client used in Request 1. :uuid is the UUID response retrieved in Response 1.

    Response 2

    If the report is still running, you may get HTTP 204 and you should check back later with the same request. If the report is complete, you will get HTTP 200 with the response body as the JSON object of the report -- same as if you'd got it from the regular endpoint.

    HTTP Status

    The SimplePay API utilizes conventional HTTP response codes to indicate the success or failure of a request.

    Code Error Message Description
    200 Success Report is running or completed with results
    429 Too Many Requests Too many reports have already been queued
    404 Requested Resource Not Found UUID not found
    204 No Content Report still running

    Calculations

    Get a list of Calculations

    Note: Inherited calculations will be displayed with a null id field.

    Request

    Request

    https://api.payroll.simplepay.cloud/v1/employees/:employee_id/calculations
    https://api.payroll.simplepay.cloud/v1/payslips/:payslip_id/calculations
    

    This is an HTTP GET request to URL ->

    Since a calculation can be associated with a client, an employee, or a payslip, there are 3 types of requests that can be used.

    Response

    Response

    [
      {"id":172,"employee_id":9,"payslip_id":null,"inputs":{"no_autopay_public_holidays":"false","fixed_amount":15000.0,"additional_paid_hours":"false","override_calculated_rate":"false"},"calculation_id":null,"account_components":{},"deleted":false,"account_outputs":{},"client_id":2,"created_at":"2018-01-09T16:08:06.287+02:00","updated_at":"2018-01-09T16:08:06.287+02:00","calculation_def_id":null,"profile_id":null,"skip":false,"multiplier":null,"input_formulas":{},"skip_rule":false,"overrides":{},"outputs":{},"system_type":"basic_salary"},
      {"id":170,"employee_id":9,"payslip_id":null,"inputs":{"full_day_hours_input":8.0,"schedule":"fixed","works_mon":"true","day_type_mon":"full","works_tue":"true","day_type_tue":"full","works_wed":"true","day_type_wed":"full","works_thu":"true","day_type_thu":"full","works_fri":"true","day_type_fri":"full","works_sat":"false","works_sun":"false"},"calculation_id":null,"account_components":{},"deleted":false,"account_outputs":{},"client_id":2,"created_at":"2018-01-09T16:08:06.257+02:00","updated_at":"2018-01-09T16:08:06.257+02:00","calculation_def_id":null,"profile_id":null,"skip":false,"multiplier":null,"input_formulas":{},"skip_rule":false,"overrides":{},"outputs":{"full_day_hours":8.0,"avg_working_day":0.0,"full_days_per_week":5.0,"scheduled_days_per_week":5.0,"annual_leave_entitlement":15.0,"scheduled_hours_per_week":40.0},"system_type":"week_hours"},
      {"id":121,"employee_id":9,"payslip_id":null,"inputs":{"fixed_amount":9000.0},"calculation_id":null,"account_components":{},"deleted":false,"account_outputs":{},"client_id":2,"created_at":"2018-01-09T16:07:47.823+02:00","updated_at":"2018-02-19T13:17:03.036+02:00","calculation_def_id":null,"profile_id":null,"skip":false,"multiplier":null,"input_formulas":{},"skip_rule":false,"overrides":{},"outputs":{},"system_type":"annual_bonus"},
      {"id":122,"employee_id":9,"payslip_id":null,"inputs":{"fixed_amount":9001.0},"calculation_id":null,"account_components":{},"deleted":false,"account_outputs":{},"client_id":2,"created_at":"2018-01-09T16:07:47.835+02:00","updated_at":"2018-01-09T16:07:48.097+02:00","calculation_def_id":5465465,"profile_id":null,"skip":false,"multiplier":null,"input_formulas":{},"skip_rule":false,"overrides":{},"outputs":{},}
    ]
    

    If executed correctly the response body is a JSON array with a list of calculations, which should be similar to this snippet ->

    Get a specific Calculation

    Note: If you wish to view a specific inherited calculation, use Get a specific Inherited Calculation instead.

    Request

    Request

    https://api.payroll.simplepay.cloud/v1/calculations/:id
    

    This is an HTTP GET request to URL ->

    Where the parameter :id is the ID of a specific calculation obtained from the call to get a list of calculations.

    Response

    Response

    {"id":60,"employee_id":null,"payslip_id":16,"inputs":{"fixed_amount":9000.0},"calculation_id":9,"account_components":{},"deleted":false,"account_outputs":{},"client_id":2,
    "created_at":"2018-01-09T16:07:30.880+02:00","updated_at":"2018-01-09T16:07:30.938+02:00","calculation_def_id":null,"profile_id":null,"skip":false,"multiplier":null,
    "input_formulas":{},"skip_rule":"false","overrides":{},"outputs":{"short_pay":0.0,"normal_pay":0.0,"sunday_pay":0.0,"normal_rate":51.92307692,"short_hours":0.0,"sunday_rate":103.8462,
    "basic_salary":9000.0,"holiday_rate":103.8462,"normal_hours":0.0,"overtime_pay":0.0,"sunday_hours":0.0,"overtime_rate":77.8846,"shifts_worked":0.0,"overtime_hours":0.0,"sick_leave_pay":0.0,
    "sunday_overtime":0.0,"annual_leave_pay":0.0,"custom_leave_pay":0.0,"public_holiday_pay":0.0,"sunday_overtime_rate":103.8462,"additional_normal_pay":0.0,"sunday_overtime_hours":0.0,
    "annual_leave_pay_extra":0.0,"directors_remuneration":0.0,"sunday_pay_fluctuating":0.0,"compassionate_leave_pay":0.0,"hours_worked_plus_payable":0.0,"labour_broker_remuneration":0.0,
    "non_directors_remuneration":0.0,"unpaid_leave_negative_income":0.0,"independent_contractor_remuneration":0.0},"system_type":"basic_salary"}
    

    If executed correctly the response body is a JSON object of the requested calculation, which should be similar to this snippet ->

    Create/Update a Calculation

    This request can be used to either create or update a calculation. If a calculation of the same type exists, the calculation will be updated with the details provided. When doing an update, only the supplied attributes are updated, existing attributes are kept as-is.

    Note:

    Request 1

    https://api.payroll.simplepay.cloud/v1/employees/:employee_id/calculations
    

    Request 1

    This is an HTTP POST request to URL ->

    Request 2

    https://api.payroll.simplepay.cloud/v1/payslips/:payslip_id/calculations
    

    Request 2

    This is an HTTP POST request to URL ->

    Example Request body

    {
      "calc_type”:”annual_bonus",
      "calculation_details":{
        “amount”:123
        }
    }
    

    Response

    Response

    {
      "message": "Calculation annual_bonus has been created/updated",
      "id": 910490037
    }
    

    If executed correctly the response body is a success message with the ID of the created or updated calculation, which should be similar to the 'Response' snippet ->

    Delete a Calculation

    Request

    Request

    https://api.payroll.simplepay.cloud/v1/calculations/:id
    

    This is an HTTP DELETE request to this URL ->

    Where the parameter :id is the ID of a specific calculation obtained from the call to get a list of calculations.

    Response

    Response

    {
      "message": "Calculation with id 9104 has been deleted."
    }
    

    If executed correctly the response body is a success message containing the ID of the deleted calculation, which should be similar to this snippet ->

    Inherited Calculations

    Get a list of Inherited Calculations

    Request

    https://api.payroll.simplepay.cloud/v1/employees/:employee_id/inherited_calculations
    

    Request

    This is an HTTP GET request to URL ->

    Response

    Response

    [
      {
        "id": 3278, "profile_id": null, "employee_id": 4535, "short_name": "week_hours", "calculation_def_id": null, "created_at": "2020-02-19T23:27:18.909+08:00", "updated_at": "2020-02-19T23:27:18.909+08:00",
        "inputs": { "full_day_hours_input": 8.8, "schedule": "fixed", "leave_any_day": "true", "works_mon": "false", "works_tue": "true", "works_wed": "true", "works_thu": "true", "works_fri": "false", "works_sat": "true", "works_sun": "true", "day_type_mon": "full", "day_type_tue": "full", "day_type_wed": "full", "day_type_thu": "full", "day_type_fri": "full", "day_type_sat": "full", "day_type_sun": "full", "full_days_per_week": 5.0 },
        "inputs_history": {
          "2020-03-01": { "works_fri": "false", "works_mon": "false", "leave_any_day": "true" },
          "2019-07-01": { "works_sat": "true", "works_sun": "true", "day_type_sat": "full", "day_type_sun": "full", "full_days_per_week": "5.0" },
          "": { "full_day_hours_input": "8.8", "schedule": "fixed", "works_mon": "true", "works_tue": "true", "works_wed": "true", "works_thu": "true", "works_fri": "true", "works_sat": "false", "works_sun": "false", "day_type_mon": "full", "day_type_tue": "full", "day_type_wed": "full", "day_type_thu": "full", "day_type_fri": "full" }
        }
      },
      ...
    ]
    

    If executed correctly the response body is a JSON array with a list of inherited calculations associated with the employee, which should be similar to this snippet ->

    Get a specific Inherited Calculation

    Request

    https://api.payroll.simplepay.cloud/v1/inherited_calculations/:id
    

    Request

    This is an HTTP GET request to URL ->

    Where the parameter :id is the ID of a specific inherited calculation obtained from the call to get a list of inherited calculations.

    Response

    Response

    {
      "id": 3278, "profile_id": null, "employee_id": 4535, "short_name": "week_hours", "calculation_def_id": null, "created_at": "2020-02-19T23:27:18.909+08:00", "updated_at": "2020-02-19T23:27:18.909+08:00",
      "inputs": { "full_day_hours_input": 8.0, "schedule": "fixed", "leave_any_day": "true", "works_mon": "false", "works_tue": "true", "works_wed": "true", "works_thu": "true", "works_fri": "true", "works_sat": "true", "works_sun": "true", "day_type_mon": "full", "day_type_tue": "full", "day_type_wed": "full", "day_type_thu": "full", "day_type_fri": "full", "day_type_sat": "full", "day_type_sun": "full", "full_days_per_week": 5.0 },
      "inputs_history": {
        "2020-03-01": { "works_mon": "false", "leave_any_day": "true" },
        "2019-07-01": { "works_sat": "true", "works_sun": "true", "day_type_sat": "full", "day_type_sun": "full", "full_days_per_week": "5.0" },
        "": { "full_day_hours_input": "8.0", "schedule": "fixed", "works_mon": "true", "works_tue": "true", "works_wed": "true", "works_thu": "true", "works_fri": "true", "works_sat": "false", "works_sun": "false", "day_type_mon": "full", "day_type_tue": "full", "day_type_wed": "full", "day_type_thu": "full", "day_type_fri": "full" }
      }
    }
    

    If executed correctly the response body is a JSON object of the requested inherited calculation, which should be similar to this snippet ->

    Inherited Calculation Attributes

    Note:

    Name calc_type Associated with Requirements
    Regular Hours week_hours Employee v2
    Attribute Details Type Applicability
    calc_type The inherited calculation to be updated or created. String Required
    effective_date The date on which the Inherited Calculation takes effect. In the format YYYY-MM-DD. Date String See Request under Update an Inherited Calculation
    calculation_details Please see Available Attributes table(s) below. Hash Required

    Available Regular Hours Attributes

    Note: # refers to a day of the week and can be either mon, tue, wed, thu, fri, sat or sun.

    Attribute Details Type Applicability
    full_day_hours_input Hours per day Integer Optional
    schedule See Help Site for more information.
    • "fixed" - Fixed
    • "casual" - Casual / Temp
    String Optional
    leave_any_day Allow leave on any day Boolean Optional. Applicable if schedule is "fixed" and enabled by Customer Support
    works_# Does the employee work on the specified weekday. Boolean Optional. Applicable if schedule is "fixed"
    day_type_#
    • "full" - Normal Day
    • "partial" - Partial Day
    String Optional. Applicable if works_# is true
    partial_hours_# Amount of hours the employee works on the specified weekday Integer Optional. Applicable if day_type_# is "partial"
    full_days_per_week See Help Site for more information.
    • "" - "Will cancel any override set"
    • Integer - "Will override current value"
    Blank or Integer Optional, will default to number of works_# unless overridden.

    Update an Inherited Calculation

    Only the supplied attributes are updated, existing attributes are kept as-is.

    Request

    https://api.payroll.simplepay.cloud/v1/employees/:employee_id/inherited_calculations
    

    Request

    This is an HTTP PATCH request to this URL ->

    The effective_date field is required if the employee has finalised payslips.

    Example Request body

    {
      "calc_type": "week_hours",
      "effective_date": "2020-04-01",
      "calculation_details": {
        "full_day_hours_input": 8.0,
        "schedule": "fixed",
        ...
      }
    }
    

    Response

    Response

    {
      "message": "Inherited calculation Week Hours has been created/updated",
      "id": 3226
    }
    

    If executed correctly the response body is a success message with the ID of the created or updated inherited calculation, which should be similar to the 'Response' snippet ->

    Service Periods

    Get a list of service periods for an employee

    Request

    Request

    https://api.payroll.simplepay.cloud/v1/employees/:employee_id/service_periods
    

    This is an HTTP GET request to URL ->

    Where the parameter :employee_id is the ID of a specific employee, obtained from the call to get a list of employees.

    Meanings for termination_code values can be found by viewing the Reason For Termination drop-down list on the End Service page.

    The negative field will always be false in Singapore and can be ignored.

    In a terminated service period, the attribs field will contain the ir21 boolean flag. This indicates whether the employee requires an IR21 form.

    Response

    Response

    [{
      "service_period":
      {
        "id": 1111,
        "employee_id": 12345,
        "start_date": "2019-11-02",
        "end_date": null,
        "negative": false,
        "created_at": "2019-09-11T10:01:41.539+02:00",
        "updated_at": "2019-09-11T10:01:41.539+02:00",
        "attribs": null,
        "termination_code": null
      }
    },
    {
      "service_period":
      {
        "id": 1110,
        "employee_id": 12345,
        "start_date": "2016-08-01",
        "end_date": "2019-10-18",
        "negative": false,
        "created_at": "2016-08-02T12:57:20.313+02:00",
        "updated_at": "2019-09-11T09:56:16.415+02:00",
        "attribs": { "ir21": true },
        "termination_code": 2
      }
    }]
    

    If executed correctly the response body is a JSON hash containing the list of service period hashes, which should be similar to this snippet ->

    Update service period termination information

    Request

    Request

    https://api.payroll.simplepay.cloud/v1/employees/:employee_id/service_periods/end_service
    

    This is an HTTP POST request to URL ->

    Where the parameter :employee_id is the ID of a specific employee, obtained from the call to get a list of employees.

    This request can be used both to end an employee's service and to update termination information that was previously recorded.

    Request Body

    Request Body

    { 
      "employee_action": {
        "termination_date": "2019-10-18", 
        "termination_code": 3,
        "ir21": true
      } 
    }
    

    The request body should be a JSON object containing the details of the termination. A request body sample is shown to the right ->

    Response

    Response

    {
      "message":"Employee has been terminated"
    }
    
    

    If executed correctly the response body is a success message indicating that the employee has been terminated, which should be similar to this snippet ->

    Reinstate an employee

    Request

    Request

    https://api.payroll.simplepay.cloud/v1/employees/:employee_id/service_periods/reinstate
    

    This is an HTTP POST request to URL ->

    Where the parameter :employee_id is the ID of a specific employee, obtained from the call to get a list of employees.

    Request Body

    Request Body

    {
      "employee_action": {
        "appointment_date": "2019-11-02"
      }
    }
    

    The request body should be a JSON object containing the appointment date of the new service period. A request body sample is shown to the right ->

    Response

    Response

    {
      "message":"Employee has been reinstated"
    }
    

    If executed correctly the response body is a success message indicating that the employee has been reinstated, which should be similar to this snippet ->

    Undo termination of an employee

    Request

    Request

    https://api.payroll.simplepay.cloud/v1/employees/:employee_id/service_periods/undo_end_service
    

    This is an HTTP DELETE request to URL ->

    Where the parameter :employee_id is the ID of a specific employee, obtained from the call to get a list of employees.

    Response

    Response

    {
      "message":"Termination has been cancelled"
    }
    

    If executed correctly the response body is a success message indicating that the most recent termination has been cancelled, which should be similar to this snippet ->

    Leave

    Get an employee's leave balance

    Request

    Request

    https://api.payroll.simplepay.cloud/v1/employees/:employee_id/leave_balances
    

    This is an HTTP GET request to URL ->

    Where the parameter :employee_id is the ID of a specific employee, obtained from the call to get a list of employees. The desired date is passed through as a parameter, as you can see in the added parameters, we are first requesting the leave balance on 2022-12-01. Alternatively, instead of a specific date, latest can be used to get the balances as of the last day that they were updated.

    Added Parameters - Desired Date

    ?date=2022-12-01
    

    Response

    Response

    {
      "5":4.5968,
      "6":30,
      "7":3
    }
    

    Added Parameters - latest

    ?date=latest
    

    Response

    {
      "type_id":5,
      "balance":8.1331,
      "date":"2023-07-14"
    },
    {
      "type_id":6,
      "balance":27,
      "date":"2023-05-20"
    },
    {
      "type_id":7,
      "balance":1,
      "date":"2023-05-20"
    }
    

    If executed correctly the response body is a JSON hash containing the ID key and the leave balance, which should be similar to this snippet ->

    Get a list of available leave types

    Request

    Request

    https://api.payroll.simplepay.cloud/v1/clients/:client_id/leave_types
    

    This is an HTTP GET request to URL ->

    Where the parameter :client_id is the ID of a specific client, obtained from the call to get a list of clients.

    Response

    Response

    {
      "5":"Annual",
      "6":"Sick",
      "7":"Compassionate",
      "8":"Unpaid"
    }
    

    If executed correctly the response body is a JSON hash containing the ID key and leave type value, which should be similar to this snippet ->

    Get a list of leave days for an employee

    Request

    Request

    https://api.payroll.simplepay.cloud/v1/employees/:employee_id/leave_days
    

    This is an HTTP GET request to URL ->

    Where the parameter :employee_id is the ID of a specific employee, obtained from the call to get a list of employees.

    Response

    Response

    [
      [{"id":46,"date":"2018-02-12","hours":null,"leave_type":"annual_leave","type_id":5}],
      [{"id":47,"date":"2018-02-13","hours":null,"leave_type":"annual_leave","type_id":5}],
      [{"id":49,"date":"2018-02-15","hours":null,"leave_type":"compassionate_leave","type_id":7}],
      [{"id":52,"date":"2018-02-18","hours":null,"leave_type":"sick_leave","type_id":6}],
      [{"id":54,"date":"2018-02-20","hours":null,"leave_type":"sick_leave","type_id":6}],
      [{"id":152,"date":"2018-01-12","hours":null,"leave_type":"annual_leave","type_id":5}],
      [{"id":151,"date":"2018-01-11","hours":7.0,"leave_type":"annual_leave","type_id":5}],
      [{"id":155,"date":"2018-01-11","hours":1.0,"leave_type":"compassionate_leave","type_id":7}],
    ]
    

    If executed correctly the response body is a JSON array containing each of the employees' approved leave days similar to this snippet ->

    The hash contains the ID of the leave day (Used to update and delete), the date, number of hours taken (it's null when it's a full day), the leave type and the leave type id.

    Create a new leave day

    Request

    Request

    https://api.payroll.simplepay.cloud/v1/employees/:employee_id/leave_days
    

    This is an HTTP POST request to URL ->

    Where the parameter :employee_id is the ID of a specific employee, obtained from the call to get a list of employees.

    Request Body

    Request Body

    {
      "date":"2017-12-11",
      "hours":"2",
      "type_id":"2"
    }
    

    The request body should be a JSON object containing the details of the leave day to be saved. A request body sample is shown to the right ->

    The type_id can be obtained from the call to get a list of available leave types. If hours are set to "null", a full day of leave will be created.

    Response

    Response

    {
      "message": "Leave day created",
      "id": 157
    }
    

    If executed correctly the response body is a JSON object with details of the transaction and the ID of the created leave day, and should be similar to this snippet ->

    Create multiple new leave days

    Request

    Request

    https://api.payroll.simplepay.cloud/v1/employees/:employee_id/leave_days/create_multiple
    

    This is an HTTP POST request to URL ->

    Where the parameter :employee_id is the ID of a specific employee, obtained from the call to get a list of employees.

    Request Body

    Request Body

    {
      "dates": [
        {"date": "2017-12-01", "hours": 1, "type_id": 3},
        {"date": "2017-12-05", "hours": 3, "type_id": 2},
        {"date": "2017-12-06", "hours": 2, "type_id": 4}
      ]
    }
    

    The request body should be a JSON object containing the details of the leave days to be saved. A request body sample is shown to the right ->

    The type_id can be obtained from the call to get a list of available leave types. If hours are set to "null", a full day of leave will be created.

    Response

    Response

    {
      "message": "Leave dates have been created",
      "ids": [1234, 1235, 1236]
    }
    

    If executed correctly the response body is a JSON object with details of the transaction and an array containing the IDs of the created leave dates, and should be similar to this snippet ->

    Update an existing leave day

    Request

    Request

    https://api.payroll.simplepay.cloud/v1/leave_days/:leave_day_id
    

    This is an HTTP PATCH request to URL ->

    Where the parameter :leave_day_id is the ID of the leave day you wish to update, obtained from the call to get a list of leave days for an employee.

    Request Body

    Request body

    {
      "date":"2017-12-11",
      "hours":"2",
      "type_id":"2"
    }
    

    The request body should be a JSON object containing the details of the leave day to be changed. An example is shown ->

    You only need to send those attributes which need to be changed for the leave day.

    Response

    Response

    {
      "message": "Leave day successfully updated.",
      "id": 157
    }
    

    If executed correctly the response body is a JSON object with details of the transaction as well as the ID of the updated leave day, and should be similar to this snippet ->

    Delete an existing leave day

    Request

    Request

    https://api.payroll.simplepay.cloud/v1/leave_days/:leave_day_id
    

    This is an HTTP DELETE request to URL ->

    Where the parameter :leave_day_id is the ID of the leave day you wish to update, obtained from the call to get a list of leave days for an employee.

    Response

    Response

    {
      "message": "Leave day with id 157 has been deleted."
    }
    

    If executed correctly the response body is a JSON object with details of the transaction as well as the ID of the deleted leave day, and should be similar to this snippet ->

    Template Profile Mappings

    Get a list of profile mappings

    Profile mappings are mappings between a template and an employee.

    Request

    Request

    https://api.payroll.simplepay.cloud/v1/employees/:employee_id/profile_mappings
    

    This is an HTTP GET request to URL ->

    Where the parameter :employee_id is the ID of a specific employee, obtained from the call to get a list of employees.

    Response

    Response

    [{
      "profile_mapping": {
        "id":1000,
        "employee_id":1234,
        "profile_id":123345,"inputs":{},
        "created_at":"2019-02-05T09:46:16.623+02:00",
        "updated_at":"2019-02-05T09:46:41.061+02:00",
        "excluded_calculations":[],
        "included_calculations":[111, 222]
      }
    }]
    

    If executed correctly the response body is a JSON array with a list of the profile mappings associated with the employee, which should be similar to this snippet ->

    Create a profile mapping

    Request

    Request

    https://api.payroll.simplepay.cloud/v1/employees/:employee_id/profile_mappings
    

    This is an HTTP POST request to URL ->

    Where the parameter :employee_id is the ID of an employee.

    Request Body

    Request Body

    {
      "profile_mapping": {
        "profile_id": "12344",
        "employee_id": "5678"
      }
    }
    

    The request body should be a JSON object defining the profile mapping, which contains the IDs for the profile and the employee. The profile_id is the template's ID and can be found on the website in Settings > Templates. An example is shown ->

    Response

    Response

    {
      "message": "Profile mapping has been created/updated",
      "id":123345
    }
    

    If executed correctly the response body is a JSON object with confirmation of the creation and the ID of the new profile mapping, and should be similar to this snippet ->

    Delete a profile mapping

    Request

    Request

    https://api.payroll.simplepay.cloud/v1/profile_mappings/:profile_mapping_id
    

    This is an HTTP DELETE request to URL ->

    Where the parameter :profile_mapping_id is the ID of a profile mapping, obtained from the call to get a list of profile mappings for an employee.

    Response

    Response

    {
      "message": "Profile mapping has been deleted",
      "id":123345
    }
    

    If executed correctly the response body is a JSON object with confirmation of the deletion and the ID of the deleted profile mapping, and should be similar to this snippet ->

    Update a profile mapping

    Request

    Request

    https://api.payroll.simplepay.cloud/v1/profile_mappings/:profile_mapping_id
    
    

    This is an HTTP PUT request to URL ->

    Where the parameter :profile_mapping_id is the ID of a profile mapping, obtained from the call to get a list of profile mappings for an employee.

    Request Body

    Request Body

    {
      "profile_mapping":{
        "optional_calculation_ids":[123, 234]
      }
    }
    

    The request body should be a JSON object containing the profile mapping details. The optional_calculation_ids provided will be enabled on the mapping. Any excluded IDS will be disabled on the mapping. An example is shown ->

    Response

    Response

    {
      "message": "Profile mapping has been created/updated",
      "id":123345
    }
    

    If executed correctly the response body is a JSON object with confirmation of the update and the ID of the updated profile mapping, and should be similar to this snippet ->

    Rate Limits

    The SimplePay API makes use of rate limits. The default maximum number of requests per hour is 1000. The below headers communicate information about these limits:

    The default limit of 1000 can be raised by contacting Support, along with justification that it is required.

    We also have a per-source IP rate limit which cannot be raised due to system stability concerns – if the HTTP 429 doesn't include the above headers, API users are advised to contact Support as they should never hit it in practice.

    Errors

    Response

    { 
        message: "API User is not authorized or does not exist."
    }
    

    The SimplePay API utilizes conventional HTTP response codes to indicate the success or failure of a request. There will also be a JSON response containing a message, similar to the example on the right ->

    200: Success | 400: Validation Error | 404: Requested Resource Not Found

    429: Indicates that the request rate limit has been reached. Currently the limit is 1000 requests and is reset on the hour. Limit information will be communicated through the HTTP header fields X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset as described above.

    500: Indicates that an exception occurred in our code. Retrying may or may not help. If this persists, please contact support.

    503: Down for maintenance. All API callers MUST be able to gracefully recover from this code, and wait at least 10 minutes before retrying.