Versioning
The URL carries the major version - /v1. Within it, behaviour is pinned to a dated contract, so a change to how something is calculated never lands on your integration unannounced.
Your key is pinned to a version - GET /me reports it as api_version. Override it per request with the INDP-Version header while you test a newer one.
curl https://api.indpayroll.com/v1/payroll-runs \
-H "Authorization: Bearer $INDP_API_KEY" \
-H "INDP-Version: 2026-09-01"What we may change without a new version
- Adding an endpoint, an optional parameter or a new field to a response.
- Adding a new value to an enum you only read - a new error
code, a new webhook event. - Statutory rates and slabs. PF, ESI, PT, LWF and TDS follow the law, and the law moves. A rate change is not a breaking change; it is the product working.
Write a tolerant clientIgnore fields you do not know, and never reject a response for carrying one. That single habit survives most of what a payroll API does over a year.
What gets a new version
- Removing or renaming a field, or changing its type.
- Making an optional parameter required.
- Changing what a status code means, or the shape of the error envelope.
- Changing a default that alters a calculated amount - the salary-days basis, say.
Deprecation
A deprecated version keeps working for at least 12 months from the announcement. Deprecated responses carry a Deprecation header and a Sunset date, and the partner console shows which of your keys still call them.