Independence Day offer · ₹52/employee/moClaim offer
INDPayroll
API reference

Statutory

PF, ESI, PT, LWF and TDS returns in filing-ready formats.

Base URLhttps://api.indpayroll.com/v120 endpoints
GET /statutory/pf/ecr

PF ECR file

The Electronic Challan cum Return for the month, in the exact layout the EPFO portal accepts. Built from the locked runs of the period: UAN, name, gross wages, EPF wages, EPS wages, employee share, employer share and EPS contribution per member.

Employees with no UAN are reported in rows with a warning rather than silently dropped - the portal rejects the whole file for one bad member.

Query parameters

organization_id
integer
Organization to act on. Required when the API key can reach more than one organization; optional - and defaulted - when it can reach exactly one.
month required
integer
Calendar month, 1-12.
year required
integer
Four-digit year.
format
enum: json, xlsx, csv, txt, pdf
File format to return instead of JSON. Omit it - or send Accept: application/json - to get JSON rows you can render yourself.

Responses

  • 200 The return as JSON rows, or as a file when format asks for one. StatutoryFileMeta
  • 400 The request was malformed or failed validation. ErrorResponse
  • 401 The key is missing, unknown, or the HMAC signature did not verify. ErrorResponse
  • 403 The key is valid but lacks the scope, or cannot reach this organization. ErrorResponse
  • 422 The 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. ErrorResponse
Request
curl -X GET https://api.indpayroll.com/v1/statutory/pf/ecr \
  -H "Authorization: Bearer $INDP_API_KEY"
Response · 200
{
  "report": "pf_ecr",
  "organization_id": 42,
  "month": 9,
  "year": 2026,
  "generated_at": "2026-10-01T05:12:00Z",
  "employee_count": 86,
  "totals": {
    "gross_wages": 4820000,
    "epf_wages": 1290000,
    "employee_share": 154800,
    "employer_share": 154800,
    "eps": 107500
  },
  "download_url": "https://api.indpayroll.com/v1/statutory/pf/ecr?month=9&year=2026&format=txt",
  "rows": [
    {
      "uan": "101234567890",
      "member_name": "Aditi Sharma",
      "gross_wages": 93787,
      "epf_wages": 15000,
      "eps_wages": 15000,
      "employee_share": 1800,
      "employer_share": 550,
      "eps_contribution": 1250,
      "ncp_days": 2
    }
  ]
}
GET /statutory/pf/form-5

PF Form 5 - new joiners

Members who joined the establishment during the month, with their UAN, date of joining and PF wages.

Query parameters

organization_id
integer
Organization to act on. Required when the API key can reach more than one organization; optional - and defaulted - when it can reach exactly one.
month required
integer
Calendar month, 1-12.
year required
integer
Four-digit year.
format
enum: json, xlsx, csv, txt, pdf
File format to return instead of JSON. Omit it - or send Accept: application/json - to get JSON rows you can render yourself.

Responses

  • 200 The return as JSON rows, or as a file when format asks for one. StatutoryFileMeta
  • 400 The request was malformed or failed validation. ErrorResponse
  • 401 The key is missing, unknown, or the HMAC signature did not verify. ErrorResponse
  • 403 The key is valid but lacks the scope, or cannot reach this organization. ErrorResponse
  • 422 The 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. ErrorResponse
GET /statutory/pf/form-10

PF Form 10 - exits

Members who left during the month, with the date and reason of leaving. Fed by POST /employees/{id}/exit.

Query parameters

organization_id
integer
Organization to act on. Required when the API key can reach more than one organization; optional - and defaulted - when it can reach exactly one.
month required
integer
Calendar month, 1-12.
year required
integer
Four-digit year.
format
enum: json, xlsx, csv, txt, pdf
File format to return instead of JSON. Omit it - or send Accept: application/json - to get JSON rows you can render yourself.

Responses

  • 200 The return as JSON rows, or as a file when format asks for one. StatutoryFileMeta
  • 400 The request was malformed or failed validation. ErrorResponse
  • 401 The key is missing, unknown, or the HMAC signature did not verify. ErrorResponse
  • 403 The key is valid but lacks the scope, or cannot reach this organization. ErrorResponse
  • 422 The 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. ErrorResponse
GET /statutory/pf/form-12a

PF Form 12A - monthly return

The consolidated monthly return: contributions remitted, members at the start and end of the month, and the challan particulars.

Query parameters

organization_id
integer
Organization to act on. Required when the API key can reach more than one organization; optional - and defaulted - when it can reach exactly one.
month required
integer
Calendar month, 1-12.
year required
integer
Four-digit year.
format
enum: json, xlsx, csv, txt, pdf
File format to return instead of JSON. Omit it - or send Accept: application/json - to get JSON rows you can render yourself.

Responses

  • 200 The return as JSON rows, or as a file when format asks for one. StatutoryFileMeta
  • 400 The request was malformed or failed validation. ErrorResponse
  • 401 The key is missing, unknown, or the HMAC signature did not verify. ErrorResponse
  • 403 The key is valid but lacks the scope, or cannot reach this organization. ErrorResponse
  • 422 The 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. ErrorResponse
GET /statutory/pf/form-3a

PF Form 3A - annual member return

Twelve months of contributions per member for the financial year, the annual companion to the monthly ECR.

Query parameters

organization_id
integer
Organization to act on. Required when the API key can reach more than one organization; optional - and defaulted - when it can reach exactly one.
financial_year
string
Indian financial year in YYYY-YY form. Defaults to the year containing the period.
format
enum: json, xlsx, csv, txt, pdf
File format to return instead of JSON. Omit it - or send Accept: application/json - to get JSON rows you can render yourself.

Responses

  • 200 The return as JSON rows, or as a file when format asks for one. StatutoryFileMeta
  • 400 The request was malformed or failed validation. ErrorResponse
  • 401 The key is missing, unknown, or the HMAC signature did not verify. ErrorResponse
  • 403 The key is valid but lacks the scope, or cannot reach this organization. ErrorResponse
  • 422 The 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. ErrorResponse
GET /statutory/pf/form-6a

PF Form 6A - annual consolidated return

The establishment-level consolidation of every Form 3A for the year.

Query parameters

organization_id
integer
Organization to act on. Required when the API key can reach more than one organization; optional - and defaulted - when it can reach exactly one.
financial_year
string
Indian financial year in YYYY-YY form. Defaults to the year containing the period.
format
enum: json, xlsx, csv, txt, pdf
File format to return instead of JSON. Omit it - or send Accept: application/json - to get JSON rows you can render yourself.

Responses

  • 200 The return as JSON rows, or as a file when format asks for one. StatutoryFileMeta
  • 400 The request was malformed or failed validation. ErrorResponse
  • 401 The key is missing, unknown, or the HMAC signature did not verify. ErrorResponse
  • 403 The key is valid but lacks the scope, or cannot reach this organization. ErrorResponse
  • 422 The 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. ErrorResponse
GET /statutory/pf/statement

PF statement

A readable PF statement for the period - per employee and in total - for reconciliation against the challan.

Query parameters

organization_id
integer
Organization to act on. Required when the API key can reach more than one organization; optional - and defaulted - when it can reach exactly one.
month required
integer
Calendar month, 1-12.
year required
integer
Four-digit year.
format
enum: json, xlsx, csv, txt, pdf
File format to return instead of JSON. Omit it - or send Accept: application/json - to get JSON rows you can render yourself.

Responses

  • 200 The return as JSON rows, or as a file when format asks for one. StatutoryFileMeta
  • 400 The request was malformed or failed validation. ErrorResponse
  • 401 The key is missing, unknown, or the HMAC signature did not verify. ErrorResponse
  • 403 The key is valid but lacks the scope, or cannot reach this organization. ErrorResponse
  • 422 The 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. ErrorResponse
GET /statutory/esi/report

ESI monthly report

ESI wages and contributions for the month, per insured person. The engine re-tests the wage threshold each period and honours the contribution-period rule, so an employee who crosses the ceiling mid-period stays covered to the end of it.

Query parameters

organization_id
integer
Organization to act on. Required when the API key can reach more than one organization; optional - and defaulted - when it can reach exactly one.
month required
integer
Calendar month, 1-12.
year required
integer
Four-digit year.
format
enum: json, xlsx, csv, txt, pdf
File format to return instead of JSON. Omit it - or send Accept: application/json - to get JSON rows you can render yourself.

Responses

  • 200 The return as JSON rows, or as a file when format asks for one. StatutoryFileMeta
  • 400 The request was malformed or failed validation. ErrorResponse
  • 401 The key is missing, unknown, or the HMAC signature did not verify. ErrorResponse
  • 403 The key is valid but lacks the scope, or cannot reach this organization. ErrorResponse
  • 422 The 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. ErrorResponse
GET /statutory/esi/return

ESI return

The half-yearly return in the layout the ESIC portal accepts.

Query parameters

organization_id
integer
Organization to act on. Required when the API key can reach more than one organization; optional - and defaulted - when it can reach exactly one.
financial_year
string
Indian financial year in YYYY-YY form. Defaults to the year containing the period.
quarter
enum: Q1, Q2, Q3, Q4
Financial-year quarter, Q1 (Apr-Jun) through Q4 (Jan-Mar).
format
enum: json, xlsx, csv, txt, pdf
File format to return instead of JSON. Omit it - or send Accept: application/json - to get JSON rows you can render yourself.

Responses

  • 200 The return as JSON rows, or as a file when format asks for one. StatutoryFileMeta
  • 400 The request was malformed or failed validation. ErrorResponse
  • 401 The key is missing, unknown, or the HMAC signature did not verify. ErrorResponse
  • 403 The key is valid but lacks the scope, or cannot reach this organization. ErrorResponse
  • 422 The 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. ErrorResponse
GET /statutory/esi/form-01

ESI Form 01 - employer registration

The employer registration form, pre-filled from the organization profile.

Query parameters

organization_id
integer
Organization to act on. Required when the API key can reach more than one organization; optional - and defaulted - when it can reach exactly one.
format
enum: json, xlsx, csv, txt, pdf
File format to return instead of JSON. Omit it - or send Accept: application/json - to get JSON rows you can render yourself.

Responses

  • 200 The return as JSON rows, or as a file when format asks for one. StatutoryFileMeta
  • 400 The request was malformed or failed validation. ErrorResponse
  • 401 The key is missing, unknown, or the HMAC signature did not verify. ErrorResponse
  • 403 The key is valid but lacks the scope, or cannot reach this organization. ErrorResponse
  • 422 The 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. ErrorResponse
GET /statutory/pt/report

Professional tax report

PT deducted for the month, grouped by state, with the slab each employee fell into. Employees mapped to a state other than the entity's appear under their own state.

Query parameters

organization_id
integer
Organization to act on. Required when the API key can reach more than one organization; optional - and defaulted - when it can reach exactly one.
month required
integer
Calendar month, 1-12.
year required
integer
Four-digit year.
format
enum: json, xlsx, csv, txt, pdf
File format to return instead of JSON. Omit it - or send Accept: application/json - to get JSON rows you can render yourself.

Responses

  • 200 The return as JSON rows, or as a file when format asks for one. StatutoryFileMeta
  • 400 The request was malformed or failed validation. ErrorResponse
  • 401 The key is missing, unknown, or the HMAC signature did not verify. ErrorResponse
  • 403 The key is valid but lacks the scope, or cannot reach this organization. ErrorResponse
  • 422 The 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. ErrorResponse
GET /statutory/pt/return

Professional tax return

The state return for the period. Monthly, half-yearly or annual, following each state's own frequency.

Query parameters

organization_id
integer
Organization to act on. Required when the API key can reach more than one organization; optional - and defaulted - when it can reach exactly one.
month required
integer
Calendar month, 1-12.
year required
integer
Four-digit year.
format
enum: json, xlsx, csv, txt, pdf
File format to return instead of JSON. Omit it - or send Accept: application/json - to get JSON rows you can render yourself.

Responses

  • 200 The return as JSON rows, or as a file when format asks for one. StatutoryFileMeta
  • 400 The request was malformed or failed validation. ErrorResponse
  • 401 The key is missing, unknown, or the HMAC signature did not verify. ErrorResponse
  • 403 The key is valid but lacks the scope, or cannot reach this organization. ErrorResponse
  • 422 The 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. ErrorResponse
GET /statutory/lwf/return

Labour welfare fund return

The LWF return for the period, in the contributing state's format. Most states collect half-yearly; the engine follows the state's own frequency.

Query parameters

organization_id
integer
Organization to act on. Required when the API key can reach more than one organization; optional - and defaulted - when it can reach exactly one.
month required
integer
Calendar month, 1-12.
year required
integer
Four-digit year.
format
enum: json, xlsx, csv, txt, pdf
File format to return instead of JSON. Omit it - or send Accept: application/json - to get JSON rows you can render yourself.

Responses

  • 200 The return as JSON rows, or as a file when format asks for one. StatutoryFileMeta
  • 400 The request was malformed or failed validation. ErrorResponse
  • 401 The key is missing, unknown, or the HMAC signature did not verify. ErrorResponse
  • 403 The key is valid but lacks the scope, or cannot reach this organization. ErrorResponse
  • 422 The 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. ErrorResponse
POST /statutory/lwf/mark-submitted

Mark the LWF return filed

Records that the return was submitted on the state portal, with the acknowledgement number. The filing dashboard moves the period from generated to submitted.

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

period required
string
The period filed, YYYY-MM for monthly states or YYYY-H1/YYYY-H2 for half-yearly ones.
submitted_on required
string (date)
reference
string
Portal acknowledgement number.
amount
number (double)
An amount in the organization's payroll currency, to two decimal places.

Responses

  • 200 Recorded. StatutoryFiling
  • 400 The request was malformed or failed validation. ErrorResponse
  • 404 No such resource, or it belongs to an organization this key cannot reach. ErrorResponse
Request
curl -X POST https://api.indpayroll.com/v1/statutory/lwf/mark-submitted \
  -H "Authorization: Bearer $INDP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "period": "2026-H2",
  "submitted_on": "2026-10-12",
  "reference": "LWF/OD/2026/889231",
  "amount": 4320
}'
GET /statutory/tds/24q

TDS Form 24Q

The quarterly salary TDS statement, with Annexure I (deductee-wise deduction) and, in the fourth quarter, Annexure II (salary details). Request format=txt for the FVU-ready text file.

Query parameters

organization_id
integer
Organization to act on. Required when the API key can reach more than one organization; optional - and defaulted - when it can reach exactly one.
financial_year
string
Indian financial year in YYYY-YY form. Defaults to the year containing the period.
quarter
enum: Q1, Q2, Q3, Q4
Financial-year quarter, Q1 (Apr-Jun) through Q4 (Jan-Mar).
format
enum: json, xlsx, csv, txt, pdf
File format to return instead of JSON. Omit it - or send Accept: application/json - to get JSON rows you can render yourself.

Responses

  • 200 The return as JSON rows, or as a file when format asks for one. StatutoryFileMeta
  • 400 The request was malformed or failed validation. ErrorResponse
  • 401 The key is missing, unknown, or the HMAC signature did not verify. ErrorResponse
  • 403 The key is valid but lacks the scope, or cannot reach this organization. ErrorResponse
  • 422 The 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. ErrorResponse
GET /statutory/tds/26q

TDS Form 26Q

The quarterly statement for non-salary deductions made by the organization.

Query parameters

organization_id
integer
Organization to act on. Required when the API key can reach more than one organization; optional - and defaulted - when it can reach exactly one.
financial_year
string
Indian financial year in YYYY-YY form. Defaults to the year containing the period.
quarter
enum: Q1, Q2, Q3, Q4
Financial-year quarter, Q1 (Apr-Jun) through Q4 (Jan-Mar).
format
enum: json, xlsx, csv, txt, pdf
File format to return instead of JSON. Omit it - or send Accept: application/json - to get JSON rows you can render yourself.

Responses

  • 200 The return as JSON rows, or as a file when format asks for one. StatutoryFileMeta
  • 400 The request was malformed or failed validation. ErrorResponse
  • 401 The key is missing, unknown, or the HMAC signature did not verify. ErrorResponse
  • 403 The key is valid but lacks the scope, or cannot reach this organization. ErrorResponse
  • 422 The 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. ErrorResponse
GET /statutory/filings

Filing dashboard

Every return the organization owes, what is generated, what is filed and what is late. This is the screen a partner rebuilds in their own UI to keep clients out of trouble.

Query parameters

organization_id
integer
Organization to act on. Required when the API key can reach more than one organization; optional - and defaulted - when it can reach exactly one.
from
string
Earliest period to include, YYYY-MM.
to
string
status
enum: not_generated, generated, submitted, acknowledged, overdue
type
enum: pf_ecr, esi_return, pt_return, lwf_return, tds_24q, tds_26q

Responses

  • 200 Filing rows. object
  • 401 The key is missing, unknown, or the HMAC signature did not verify. ErrorResponse
Request
curl -X GET https://api.indpayroll.com/v1/statutory/filings \
  -H "Authorization: Bearer $INDP_API_KEY"
Response · 200
{
  "data": [
    {
      "id": "fil_01J9K7YR4H",
      "type": "pf_ecr",
      "period": "2026-09",
      "due_date": "2026-10-15",
      "status": "generated",
      "generated_at": "2026-10-01T05:12:00Z",
      "amount": 309600
    },
    {
      "id": "fil_01J9K7YR4J",
      "type": "esi_return",
      "period": "2026-09",
      "due_date": "2026-10-15",
      "status": "not_generated",
      "amount": 43860
    },
    {
      "id": "fil_01J9K7YR4K",
      "type": "tds_24q",
      "period": "2026-Q2",
      "due_date": "2026-10-31",
      "status": "overdue",
      "amount": 1296480
    }
  ]
}
GET /government-forms

List tracked challans and acknowledgements

Query parameters

organization_id
integer
Organization to act on. Required when the API key can reach more than one organization; optional - and defaulted - when it can reach exactly one.
type
enum: pf_challan, esi_challan, pt_challan, lwf_challan, tds_challan, acknowledgement, other
period
string
page
integer
1-based page number.
per_page
integer
Items per page. The engine caps this at 200.

Responses

  • 200 Tracked forms. object
  • 401 The key is missing, unknown, or the HMAC signature did not verify. ErrorResponse
POST /government-forms

Track a challan or acknowledgement

Records something you filed or paid outside INDPayroll - a TRRN, a challan, a portal acknowledgement - against the period, so the filing dashboard reflects reality.

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
integer
type required
enum: pf_challan, esi_challan, pt_challan, lwf_challan, tds_challan, acknowledgement, other
period required
string
reference_number required
string
amount
number (double)
An amount in the organization's payroll currency, to two decimal places.
paid_on
string (date)
document_url
string (uri)
notes
string

Responses

  • 201 Created. GovernmentForm
  • 400 The request was malformed or failed validation. ErrorResponse
Request
curl -X POST https://api.indpayroll.com/v1/government-forms \
  -H "Authorization: Bearer $INDP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "organization_id": 42,
  "type": "pf_challan",
  "period": "2026-09",
  "reference_number": "TRRN 1234567890123",
  "amount": 309600,
  "paid_on": "2026-10-12"
}'
GET /government-forms/{id}

Retrieve a tracked form

Path parameters

id required
string
INDPayroll id of the resource.

Responses

  • 200 The form. GovernmentForm
  • 404 No such resource, or it belongs to an organization this key cannot reach. ErrorResponse