Payroll runs entirely on Cases:
- Case - a form made of CaseFields, each with a
startand optionalend(set by you, or added automatically by Ason) - CaseChange - one reported event - a hire, a bonus, sickness, an address update, and so on
- CaseValue - the value Ason stores for one CaseField within a CaseChange, with its own
start/end - CaseMan - the generic case form in Ason's frontend
Missing Data and Payroll Control aren't a separate mechanism - they're Cases too, generated automatically and resolved the same way as any other Case. Always resolve them through Build - skipping it risks missing newly-required fields, and resolving one can itself generate further Missing Data or Payroll Control cases. See Why always CaseMan.
CaseChanges with CaseMan
- Why fields appear or disappear while filling in a case: dynamic cases are re-evaluated via POST
/tenants/{orgId}/payrolls/{payrollId}/cases/sets/{caseName}("build") after every field change, without saving anything. - Where values are validated: in the reporting call itself - POST
/tenants/{orgId}/payrolls/{payrollId}/cases/setschecks the values and returns errors if something's wrong. Build only reshapes which fields apply; it never checks whether an entered value is correct
Before reporting: GET /tenants/{orgId}/payrolls/{payrollId}/cases/sets (caseType=Company or Employee) lists what you're allowed to report.
Every Case carries a cluster tag - NewEvent is the default, the rest are named slices for anything more specific. Pass one as clusterSetName to narrow that list to just what one screen needs - caseType (not the cluster) decides company vs. employee, so the same tag works for both.
Import Data without CaseMan
Even a complete-looking import opens Missing Data and Payroll Control cases - with many employees, that means many open cases. Why always CaseMan
- Single-field cases are named after their field - importing or reporting just one CaseField means reporting a case with that same name
- Special-Data-Cases - deliberately huge: dozens of mostly-optional fields, meant to capture everything at once instead of one case per field. Examples:
CompanyOnboardingData,EmployeeNewEntryData(Quickstart steps 4 and 6). - Excel import - a generic bulk option: each column maps to a case field, each row to one case change
Not sure which case fits your data? Get in touch.
Master data vs. variable data
Every case field has a time type that decides how a value you report behaves over time:
| Time type | Behavior | start / end | Example |
|---|---|---|---|
| Period (master data) | Valid from start onward until you change it again | only start needed | address, IBAN, civil status |
| Moment (variable data) | Tied to a single point in time; summed within a payrun period | only start needed | hours worked on a day, a one-off bonus |
Moment examples
A one-off bonus - two Moment values reported the same month are summed, not overwritten.
Hours worked (CH.Swissdec.EmployeeActivityWorkedHours) - reported per day, summed the same way.
Period examples
A monthly salary raise mid-month - the period result is pro-rated by active days (15 + 15 of 30), not just the latest value.
A plain overwrite - no summing, no pro-rata. The old value applies right up until the new one starts.
Company & Employee Data
Company data is scoped by divisionId; employee data adds employeeId on top - otherwise identical (documents, history, the same reporting mechanism).
Documents on case values
Some case fields hold a file instead of text/number - a policy PDF, a signed contract, a scanned ID. Same reporting as any case change, just with a documents array (each entry: name, contentType, base64 content) attached to the value.
- The response returns each value's own
id- the case value id you need to retrieve the document later (not the case change id) - Value and documents:
value: nullif there's only a file; thedocumentsarray takes several entries per value - Outputs as documents: every Output (payslip, declaration, posting document) is reported automatically as a Case Change when the Payrun Period closes or finalizes
Case-Change History
Each entry shows case, field and value with Start, End, Created and the reason.
- Future-dated values included: the History view shows future-dated entries too, not just past ones
- No deletes: neither case changes nor their documents can be deleted - corrections go through reporting a new case change
API Endpoints
Case changes:
| What | Call |
|---|---|
| List cases available to report (company or employee) | GET /tenants/{orgId}/payrolls/{payrollId}/cases/sets |
| Build a case's fields (dynamic cases only, nothing saved) | POST /tenants/{orgId}/payrolls/{payrollId}/cases/sets/{caseName} |
| Report a case change | POST /tenants/{orgId}/payrolls/{payrollId}/cases/sets |
| List reported case changes (history) | GET /tenants/{orgId}/payrolls/{payrollId}/changes |
Case values & missing data:
| What | Call |
|---|---|
| Get current data values | GET /tenants/{orgId}/payrolls/{payrollId}/cases/values/time |
| Get a field's value history | GET /tenants/{orgId}/payrolls/{payrollId}/changes/values |
| Count data values (e.g. for missing-data checks) | GET /tenants/{orgId}/payrolls/{payrollId}/cases/values/count |
| List case fields that hold documents | GET /tenants/{orgId}/payrolls/{payrollId}/casefields |
| List missing company data | GET /tenants/{orgId}/payrolls/{payrollId}/missingdata |
| List missing employee data | GET /tenants/{orgId}/payrolls/{payrollId}/missingdata/employees |
Company & employee documents:
| What | Call |
|---|---|
| Get a company document | GET /tenants/{orgId}/companycases/{caseValueId}/documents/{documentId} |
| Get an employee document | GET /tenants/{orgId}/employees/{employeeId}/cases/{caseValueId}/documents/{documentId} |
