Calculate a run without persisting it
A dry run. The engine values every employee for the period and returns the slips; nothing is written, no payslip ids are issued and no webhook fires.
This is the whole integration for calculate-only partners: send the period, the employees and their inputs, render the response in your own UI. Anything passed inline in employees[] overrides what is stored, so you never have to push attendance first.
Preview is metered against the payroll-run rate limit rather than the general one - it does the same work as a real run.
Headers
Idempotency-Key string | A unique key, at most 255 characters, that makes this request safe to retry. Replaying a key within 24 hours returns the original response and does not act again. |
Body application/json · required
organization_id requiredinteger | The entity to calculate for. |
cycle enum: monthly, weekly, bi-weekly | Pay frequency. Must match the cycle the employees are assigned to. |
period_start requiredstring (date) | First day of the period being paid, inclusive. |
period_end requiredstring (date) | Last day of the period being paid, inclusive. |
employee_ids string[] | Restrict the run to these employees. Omit for every payable employee in the organization. |
department_ids integer[] | Restrict the run to these departments. Combined with employee_ids as a union. |
options PayrollRunOptions | The same five switches the product shows above the Generate button. They decide what the engine reads, not what it computes - statutory rules are never optional. |
employees PreviewEmployeeInput[] | Inline period inputs. Anything sent here wins over what is stored, which is what makes a stateless, calculate-only integration possible. |
Responses
200Calculated slips. Nothing was persisted. PayrollRunPreview400The request was malformed or failed validation. ErrorResponse401The key is missing, unknown, or the HMAC signature did not verify. ErrorResponse403The key is valid but lacks the scope, or cannot reach this organization. ErrorResponse422The request was well-formed but the engine could not compute it - a missing salary structure, no PT state on an employee, or a period with no inputs. ErrorResponse429Rate limit exceeded. Retry after the number of seconds inRetry-After. ErrorResponse
curl -X POST https://api.indpayroll.com/v1/payroll-runs/preview \
-H "Authorization: Bearer $INDP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"organization_id": 42,
"cycle": "monthly",
"period_start": "2026-09-01",
"period_end": "2026-09-30",
"employee_ids": [
"ext-1001",
"ext-1002"
],
"options": {
"use_attendance": true,
"mark_leaves_paid": true,
"mark_absent_unpaid": true,
"include_expense_claims": true,
"add_timelogs": false
}
}'{
"organization_id": 42,
"period_start": "2026-09-01",
"period_end": "2026-09-30",
"cycle": "monthly",
"options": {
"use_attendance": true,
"mark_leaves_paid": true,
"mark_absent_unpaid": true,
"include_expense_claims": true,
"add_timelogs": false
},
"totals": {
"employee_count": 2,
"gross": 144733.33,
"total_deductions": 17516,
"net_payable": 127505.33,
"pf_employee": 3600,
"pf_employer": 3600,
"esi_employee": 0,
"esi_employer": 0,
"professional_tax": 400,
"tds": 13516,
"lwf": 0,
"reimbursements": 288,
"employer_cost": 148333.33
},
"employees": [
{
"employee_id": "1187",
"external_id": "ext-1001",
"name": "Aditi Sharma",
"employee_code": "ACM-0142",
"department": "Engineering",
"period_start": "2026-09-01",
"period_end": "2026-09-30",
"payable_days": 28,
"total_days": 30,
"lop_days": 2,
"earnings": [
{
"code": "BASIC",
"name": "Basic",
"amount": 39666.67,
"taxable": true,
"pro_rated": true
},
{
"code": "HRA",
"name": "House Rent Allowance",
"amount": 15866.67,
"taxable": true,
"pro_rated": true
},
{
"code": "SPL",
"name": "Special Allowance",
"amount": 20253.33,
"taxable": true,
"pro_rated": true
},
{
"code": "INCENTIVE",
"name": "Q2 sales incentive",
"amount": 18000,
"taxable": true,
"pro_rated": false
}
],
"deductions": [
{
"code": "PF",
"name": "Provident Fund",
"amount": 1800
},
{
"code": "PT",
"name": "Professional Tax",
"amount": 200
},
{
"code": "TDS",
"name": "Income Tax",
"amount": 9420
}
],
"employer_contributions": [
{
"code": "PF_EMPLOYER",
"name": "Employer PF",
"amount": 1800
},
{
"code": "EPS",
"name": "Employees Pension Scheme",
"amount": 1250
}
],
"reimbursements": [
{
"code": "EXP",
"name": "Client visit - Cuttack",
"amount": 288
}
],
"basic": 39666.67,
"hra": 15866.67,
"other_earnings": 38253.33,
"overtime_amount": 0,
"overtime_hours": 0,
"gross": 93786.67,
"pf_employee": 1800,
"pf_employer": 1800,
"eps_employer": 1250,
"esi_employee": 0,
"esi_employer": 0,
"professional_tax": 200,
"tds": 9420,
"lwf_employee": 0,
"lwf_employer": 0,
"lop_amount": 6333.33,
"advance_recovery": 0,
"total_deductions": 11420,
"total_reimbursements": 288,
"net_payable": 82654.67,
"employer_cost": 96836.67,
"currency": "INR",
"on_hold": false,
"warnings": []
}
],
"warnings": [],
"calculated_at": "2026-09-30T10:02:18Z"
}