Version 2.6 and the purpose of this specification
The twenty-two-page specification dated 11 September 2026 lets payroll developers validate and submit IR8 A, Appendix 8 A and Appendix 8 B through HTTP/JSON. It covers onboarding, security, limits, all sample-object families and response handling. The separate Data Items and Validation Rules workbook is a reference attachment rather than a PDF chapter; this article does not invent workbook rules absent from the source.
Version history and compatibility changes
BaselineAugust 2024; network/message securityNovember 2024; finalisedMay 2025 adds OAuth 2.1 and revised endpoints, removes ERIS sectionsB/C/D and updates examples. June 2025 makes postalCode a string. July/September/December 2025 revise character validation; December also makes returnCode, acknowledgementCode and messageCode strings. June 2026 removes unused messageCode and updates responses; September 2026 updates links. Implement the selected edition rather than combining older numeric response types with new samples.
Onboarding: Corppass, applications and sandbox first
Developers need Corppass before subscribing. Through APEX create an application, generate API keys, create an OAuth 2.1 client and subscribe to the desired API. Sandbox testing precedes production. Use the IRAS testing entity and sandbox OAuth client; annual validation tests assess software compatibility. Successful testing and IRAS approval are required for production access, which also needs a production OAuth client.
Authorisation flows and endpoints
Obtain a Corppass authorisation token through OAuth 2.1. The authorisation parameter tax_agent=y denotes acting for a client; n denotes the organisation’s own affairs. POST to https://sandbox.api.gov.sg/iras/employment-income-records/v 2/Submit for sandbox or https://public.api.gov.sg/iras/employment-income-records/v 2/Submit for production. The header example still shows an older /iras/prod/EmpIncomeRecords/submit path: use the current endpoint table rather than treating that example as an alternative endpoint.
Server security and all required headers
Server-to-server connection uses TLS and IP whitelisting. Support HTTP/2, TLS1.2/1.3 and GET/POST, with ECDHE-RSA-AES256-GCM-SHA384 or ECDHE-RSA-AES128-GCM-SHA256. Supply x-apex-apikey, Authorization with Bearer plus the JWT Corppass access token, and Content-Type application/json; the example also uses Accept application/json. Request the EmpIncomeSub scope. Sample credentials are illustrative and must not be used as real keys.
Batch limits, selective resubmission and rate limiting
Maximum 2000 employee records and 8 MB per request. The apparent 20001 in extracted text is 2000 with footnote 1, confirmed by the rejected 2001 example. Split 3000 employees into 2000 and 1000 within the size limit; if only the second chunk fails, correct/resend that chunk, not the accepted first. A1000-record batch over 8 MB also fails. Keep the record cap configurable. The limit is 3000 requests per application per hour; HTTP429 indicates rate-limit exhaustion and the source directs retrying next hour.
Production restrictions and common data formats
Production is for actual AIS submission; testing there is prohibited and may suspend/terminate access. JSON is case-sensitive with camel-case properties and ISO8601 dates YYYY-MM-DD. Unless explicitly optional, specify all properties. String(n) limits length; Number(4) allows four whole digits; Decimal(13,2) allows thirteen whole digits and two decimals. Allowed string characters are ASCII32–127, ü/Ü/İ, LF/CR, en/em dashes and smart quotes. Use the whitelist rather than the superseded blacklist revisions.
Submission header: every information category
orgAndSubmissionInfo contains validateOnly and bypassWarning; incomeYear, employerTaxRefNumber and submissionType; authorisedPersonName/contactNumber/emailAddress; softwareCompanyName/softwareName; totalNumber IR8 A/amountTotalIncomeOf IR8 A and totalNumberOfApp 8 A/totalNumberOfApp 8 B. Reconcile header counts and income with the employee array. The source’s detailed required values and validations are delegated to the workbook.
Employee identity and employment fields
employeePersonalParticulars is an array. Each item identifies recordId, idType/idNumber, name/dateOfBirth/sex, addressType and three address lines, string postalCode and foreign-country code, designation/bankCode, commencementDate/cessationDate, plus nested ir 8 a/appendix 8 A/appendix 8 B. Preserve exact keys: the overview’s iR8 A label differs from the sample ir 8 a key. Do not infer valid addressType values from the multiple-appendix sample, which incorrectly places a job title there while its earlier sample uses L/F.
IR8 A fields: pay, other income and deductions
The object includes payment-period dates; salary/bonus and noncontractual bonus paid date; director fees/approval date/section 45 indicator; allowances, commission, gratuity/notice pay/ex-gratia, loss-of-office compensation and indicator; post 1993 pension benefits and fund name; overseas employer pension contributions, excess/voluntary CPF; share-option/share-award gains under 10(1)(b)/(g), benefits-in-kind, other income and total. Also include exempt/remission amount and indicator, employer-borne-tax indicator and relevant employer/employee borne amounts, CPF/designated-fund contributions, payroll donations, Mosque Building Fund and payroll life-insurance premiums.
Appendix 8 A: all accommodation and benefit groups
Repeat accommodationRecords with accommodationId, address, occupation dates/days, employee sharing, annual value, furnishing indicator/value, employer rent and residence taxable values, employee rent contribution, utilities/housekeeping, driver and servant/gardener/upkeep. Outside that array are hotel/serviced-apartment actual cost, employee payment and taxable value; leave passage/incidental benefits; interest, insurance, holiday, education, club entrance/transfer fees, asset gains, full vehicle cost, car benefit, other nonmonetary benefits and total benefits-in-kind.
Appendix 8 B: equity remuneration and both totals
eebrRecords repeats eebrId, company tax identifier/name, plan type, grant/exercise-or-vesting dates, exercise price, market value per share, share number and gross gains. Totals separate post 2003 section 10(1)(b) and pre 2003 section 10(1)(g) gains. ERIS sectionsB/C/D were removed in version 2.0; they should not be inserted from older payloads.
IR8 A-only example: three employees and reconciled income
The 2024 original-submission example has three IR8 A records totalling S$165000 and zero appendix counts. A has S$36000 salary plus S$3000 bonus=S$39000, CPF7800 and donation 12. B has 24000 salary plus 2000 bonus=26000 and ceases 30 June 2024. C is a foreign-address director with 100000 fees approved 30 June 2024 and section 45 indicatorY. Empty appendix objects remain in each employee record. Illustrative identifiers do not establish actual taxpayer facts.
Multiple-appendix example and internal sample inconsistencies
One employee’s total income is 77000, with one 8 A and one 8 B. Two accommodation rows show rent 1000 with no employee contribution, then rent 1500 less 800=700; each adds 300 utilities/driver/upkeep. The sample labels 1 January–30 June 2024 as 181 days despite the leap-year calendar: validate actual dates instead of copying that number. ESOW500 shares at 4 with zero exercise price yields 2000; a pre 2003 ESOP1000 shares at 1 yields 1000. Several illustrative total/period values require validation against the workbook rather than treating every sample value as a tax calculation.
All response codes and diagnostic fields
returnCode is a string:10 processed successfully,20 accepted with nonfatal warnings,30 error/not processed,40 warning/not processed. Successful submission returns data.acknowledgementCode as a string. info carries messageCode/message, warnings and fieldInfoList; diagnostics identify section, field, message and affected record IDs, with similar failures grouped. Codes 850301 indicate argument errors,850302 service exception and 850305 invalid sandbox test user. The table mixes Info/info and record ID while samples use recordId: confirm exact runtime casing rather than blindly copying the table.
Warnings versus validation-only: acceptance is different
bypassWarning=true allows acceptance with warnings and code 20; false with warnings gives 40 and no accepted submission. A clean request gives 10. validateOnly=true performs checks but does not submit even if code 10 is returned, and gives no acknowledgementCode; a valid access token is still required. Accepted production submissions email both the company contact and the address in the submission. The screenshot email illustrates receipt rather than replacing the returned acknowledgement.
Error examples and a practical integration checklist
Missing authorised name, birth date or payment start date produces field diagnostics; an invalid end date can require income-year 31 December or cessation date. Source examples mix 2024 income with a 2025 end-date message, so apply the real income year and workbook rule, not a fixed sample year. Amendments with bypassWarning=false may stop at 40. Generic exception 30/850302 directs contact with API_SUPPORT@iras.gov.sg. Separate validation from submission, save acknowledgements, reconcile accepted batches, correct only failed chunks and retain the official specification/workbook links.
Official source
This article independently explains the substantive contents of the official PDF, including the relevant conditions, procedures and annexes. The linked document remains the authoritative source for its original wording, and later changes should be checked separately.
Read the official PDF ↗