Stairling - Guide
Complete walkthrough to run a payroll calculation through the Verso Partner API: create an employee, inject payroll variables, execute the calculation, and retrieve results.
Prerequisites
Before starting, ensure you have:
- A partner API key (provided by Verso)
- Your partner ID and tenant ID
- The tenant must have the StairlingPayroll regulation imported
All examples use these variables:
Code
All endpoints follow the pattern: GET/POST /partners/{partnerId}/tenants/{tenantId}/...
Step 1 — Discover resources
Verify connectivity and retrieve IDs for your tenant.
Code
Code
Code
Step 2 — Create an employee
Code
Response (201 Created):
Code
Capture the id field — you will need it for case injection and payrun.
Step 3 — Inject case values
All cases are injected via POST /partners/{partnerId}/tenants/{tenantId}/payrolls/{payrollId}/cases using the CaseChangeSetup payload format.
Contrat
Code
Remuneration
Code
Frais
Code
Prevoyance & Mutuelle
Code
PAS (Prelevement a la Source)
Code
Verify injected values
Code
You should see all 10 case field values (Contrat, Remuneration, Frais, PrevoyanceMutuelle, PAS).
Step 4 — Run payroll
Start the payrun job
Code
Response (202 Accepted):
Code
| Field | Description |
|---|---|
forecast | Unique string to isolate this simulation. Required to avoid blocking other jobs. |
employeeIdentifiers | Array of employee identifiers (email/ID). Limits calculation to listed employees. |
periodStart | First day of the pay period (ISO 8601 with timezone). |
Poll until completion
Code
Wait until jobStatus changes from Process to Draft and jobEnd is no longer null. Typical processing time: 1-12 seconds.
Retrieve results
Forecast results are available immediately once the job reaches Draft — no additional steps needed.
Code
That's it — 3 API calls to run a complete payroll: start job, poll status, get results.
For more details on forecast vs real mode, see the Real vs Forecast Mode guide.
Step 5 — Read the results
The response from /payrollresults/sets contains wageTypeResults (individual payslip lines) and collectorResults (aggregated totals).
Example output
Input: 151.67h at 13.00 EUR/h, 20 meals at 20.70 EUR, prevoyance 0.89%, PAS 5%.
Wage Types
| WT | Name | Value (EUR) |
|---|---|---|
| 100 | SalaireBase | 1,971.71 |
| 200 | AssuranceMaladiePatronale | 138.02 |
| 210 | VieillessePlafonneeSalariale | 136.05 |
| 211 | VieillessePlafonneePatronale | 168.58 |
| 212 | VieillesseDeplafonneeSalariale | 7.89 |
| 213 | VieillesseDeplafonneePatronale | 39.83 |
| 220 | AllocationsFamiliales | 68.02 |
| 230 | AccidentsTravail | 76.31 |
| 240 | FNAL | 9.86 |
| 241 | CSA | 5.92 |
| 253 | PrevoyancePatronale | 17.55 |
| 300 | CSGDeductible | 132.92 |
| 301 | CSGNonDeductible | 46.91 |
| 302 | CRDS | 9.77 |
| 400 | AgircArrcoT1Salariale | 62.11 |
| 401 | AgircArrcoT1Patronale | 93.06 |
| 410 | CEGT1Salariale | 16.96 |
| 411 | CEGT1Patronale | 25.44 |
| 450 | AssuranceChomage | 78.87 |
| 451 | AGS | 4.93 |
| 499 | ReductionFillonTotale | -490.96 |
| 500 | ReductionFillonURSSAF | -399.69 |
| 501 | ReductionFillonAGIRC | -91.27 |
| 600 | IndemniteRepas | 414.00 |
Totals
| WT | Name | Value (EUR) |
|---|---|---|
| 900 | TotalBrut | 1,971.71 |
| 910 | TotalCotisationsSalariales | 412.61 |
| 920 | TotalCotisationsPatronales | 747.40 |
| 930 | TotalAllegements | -490.96 |
| 950 | NetImposable | 1,615.79 |
| 960 | PAS | 80.79 |
| 980 | TotalIndemnites | 414.00 |
| 990 | NetAPayer | 1,892.31 |
Troubleshooting
"Payrun with id X has already a payrun job with status Draft"
Existing Draft jobs block new non-forecast job creation. Solutions:
- Use forecast mode — forecast jobs don't block each other
- Delete the blocking job via the backend API
- Advance the blocking job through its lifecycle (Release → Process → Complete)
No results returned
If payrollresults/sets?payrunJobId={id} returns an empty array:
- Verify the job completed successfully (
jobEndis not null,processedEmployeeCount> 0) - Check that
ParametresLegauxcase values exist (PSS, SMIC) — without them, capped contributions return 0 - Ensure all required case values were injected for the employee
Missing case values
Each employee needs at minimum:
| Case | Required Fields |
|---|---|
Contrat | DateDebutContrat |
Remuneration | HeuresTravaillees, TauxHoraire |
Frais | NombreRepas, MontantRepas (commonly forgotten) |
PrevoyanceMutuelle | HasPrevoyance, TauxPrevoyance, HasMutuelleObligatoire, HasMutuelleFacultative |
PAS | TauxPAS |