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

Period inputs

Attendance, leave, overtime, expenses and advances the run consumes.

Base URLhttps://api.indpayroll.com/v116 endpoints
GET /attendance

Read attendance for a window

Exactly what the run will read. Use it to reconcile before calculating.

Query parameters

from required
string (date)
Start of the window, inclusive.
to required
string (date)
End of the window, inclusive.
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.
employee_id
string
page
integer
1-based page number.
per_page
integer
Items per page. The engine caps this at 200.

Responses

  • 200 Attendance records. object
  • 400 The request was malformed or failed validation. ErrorResponse
  • 401 The key is missing, unknown, or the HMAC signature did not verify. ErrorResponse
POST /attendance/bulk

Upsert daily attendance

Up to 5,000 rows per call, keyed on employee and date. This is the usual way a partner's own biometric or roster system feeds the engine.

Rows for a period that is already locked are rejected; rows for a calculated but unlocked run are accepted and take effect when you recalculate.

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
records required
AttendanceRecord[]
overwrite
boolean
True replaces an existing record for the same employee and date; false keeps what is there.

Responses

  • 200 Per-row outcome. BulkUpsertResult
  • 400 The request was malformed or failed validation. ErrorResponse
  • 409 The resource is in a state that forbids the change - a locked or paid run, a duplicate external_id, or a settlement already approved. ErrorResponse
  • 429 Rate limit exceeded. Retry after the number of seconds in Retry-After. ErrorResponse
Request
curl -X POST https://api.indpayroll.com/v1/attendance/bulk \
  -H "Authorization: Bearer $INDP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "organization_id": 42,
  "overwrite": true,
  "records": [
    {
      "employee_id": "ext:emp-1001",
      "date": "2026-09-14",
      "status": "present",
      "hours_worked": 8.5,
      "in_time": "09:34",
      "out_time": "18:41"
    },
    {
      "employee_id": "ext:emp-1002",
      "date": "2026-09-14",
      "status": "absent"
    },
    {
      "employee_id": "ext:emp-1201",
      "date": "2026-09-14",
      "status": "present",
      "hours_worked": 11,
      "overtime_hours": 3,
      "shift_id": 4
    }
  ]
}'
Response · 200
{
  "accepted": 3,
  "rejected": 0,
  "errors": []
}
GET /leaves

List leave records

Query parameters

from required
string (date)
Start of the window, inclusive.
to required
string (date)
End of the window, inclusive.
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.
employee_id
string
status
enum: pending, approved, rejected, cancelled
page
integer
1-based page number.
per_page
integer
Items per page. The engine caps this at 200.

Responses

  • 200 Leave records. object
  • 401 The key is missing, unknown, or the HMAC signature did not verify. ErrorResponse
POST /leaves

Create a leave record

paid: false makes every day loss of pay regardless of the run's mark_leaves_paid switch. If your own workflow already approved the leave, send status: approved and the engine will not wait for an approval it never gets.

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

employee_id required
string
Employee id, or ext: + your own identifier.
leave_type
string
Your own leave-type name. It is stored as sent and shown on approvals.
from required
string (date)
First day of the leave, inclusive.
to required
string (date)
Last day of the leave, inclusive.
days
number
Omit to let the engine count the span against the holiday calendar and weekly offs.
paid
boolean
status
enum: pending, approved, rejected, cancelled
Send approved directly when the approval happened in your own workflow.
reason
string
Free text shown to approvers.

Responses

  • 201 Created. Leave
  • 400 The request was malformed or failed validation. ErrorResponse
  • 409 The resource is in a state that forbids the change - a locked or paid run, a duplicate external_id, or a settlement already approved. ErrorResponse
Request
curl -X POST https://api.indpayroll.com/v1/leaves \
  -H "Authorization: Bearer $INDP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "employee_id": "ext:emp-1001",
  "leave_type": "Casual Leave",
  "from": "2026-09-21",
  "to": "2026-09-22",
  "paid": true,
  "status": "approved"
}'
PATCH /leaves/{id}

Approve, reject or cancel a leave

For partners who run approvals inside INDPayroll. Only approved leave reaches the engine.

Path parameters

id required
string
INDPayroll id of the resource.

Body application/json · required

status required
enum: approved, rejected, cancelled
remarks
string

Responses

  • 200 Updated. Leave
  • 404 No such resource, or it belongs to an organization this key cannot reach. ErrorResponse
  • 409 The resource is in a state that forbids the change - a locked or paid run, a duplicate external_id, or a settlement already approved. ErrorResponse
Request
curl -X PATCH https://api.indpayroll.com/v1/leaves/{id} \
  -H "Authorization: Bearer $INDP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "status": "approved",
  "remarks": "Approved by reporting manager."
}'
GET /overtime-requests

List overtime requests

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.
employee_id
string
status
enum: pending, approved, rejected
page
integer
1-based page number.
per_page
integer
Items per page. The engine caps this at 200.

Responses

  • 200 Overtime requests. object
  • 401 The key is missing, unknown, or the HMAC signature did not verify. ErrorResponse
POST /overtime-requests

Raise an overtime request

Only approved hours are paid. Send status: approved when the approval happened in your system.

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

employee_id required
string
date required
string (date)
hours required
number
policy_id
integer
pay_code
string
reason
string
status
enum: pending, approved

Responses

  • 201 Created. OvertimeRequest
  • 400 The request was malformed or failed validation. ErrorResponse
Request
curl -X POST https://api.indpayroll.com/v1/overtime-requests \
  -H "Authorization: Bearer $INDP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "employee_id": "ext:emp-1201",
  "date": "2026-09-14",
  "hours": 3,
  "policy_id": 2,
  "status": "approved"
}'
POST /overtime-requests/{id}/approve

Approve an overtime request

Path parameters

id required
string
INDPayroll id of the resource.

Body application/json · optional

hours
number
Approve fewer hours than were claimed.
remarks
string

Responses

  • 200 Approved. OvertimeRequest
  • 404 No such resource, or it belongs to an organization this key cannot reach. ErrorResponse
  • 409 The resource is in a state that forbids the change - a locked or paid run, a duplicate external_id, or a settlement already approved. ErrorResponse
GET /overtime-policies

List overtime policies

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.

Responses

  • 200 Policies. object
  • 401 The key is missing, unknown, or the HMAC signature did not verify. ErrorResponse
POST /overtime-policies

Create an overtime policy

The multipliers and pay codes overtime hours are valued at. Indian factory overtime is commonly twice the ordinary rate; the default multipliers reflect that, but nothing here is imposed.

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
name required
string
calculation_basis required
enum: basic, gross, fixed_rate
weekday_multiplier
number
weekly_off_multiplier
number
holiday_multiplier
number
fixed_hourly_rate
number (double)
An amount in the organization's payroll currency, to two decimal places.
max_hours_per_month
number
pay_codes
object[]
active
boolean

Responses

  • 201 Created. OvertimePolicy
  • 400 The request was malformed or failed validation. ErrorResponse
Request
curl -X POST https://api.indpayroll.com/v1/overtime-policies \
  -H "Authorization: Bearer $INDP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "organization_id": 42,
  "name": "Plant - shop floor",
  "calculation_basis": "basic",
  "weekday_multiplier": 1.5,
  "weekly_off_multiplier": 2,
  "holiday_multiplier": 2,
  "max_hours_per_month": 50,
  "pay_codes": [
    {
      "code": "OT_WEEKDAY",
      "multiplier": 1.5
    },
    {
      "code": "OT_HOLIDAY",
      "multiplier": 2
    }
  ]
}'
POST /overtime-policies/{id}/assign

Assign employees to an overtime policy

Path parameters

id required
string
INDPayroll id of the resource.

Body application/json · required

employee_ids required
string[]
effective_from
string (date)
Defaults to the first day of the current period.

Responses

  • 200 Assigned. Ack
  • 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/overtime-policies/{id}/assign \
  -H "Authorization: Bearer $INDP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "employee_ids": [
    "ext:emp-1201",
    "ext:emp-1202"
  ],
  "effective_from": "2026-10-01"
}'
GET /expenses

List expenses

Send payroll=1 for the claims eligible to ride on the next payslip - approved, flagged include_in_payroll, and not yet carried into a run.

Query parameters

payroll
enum: 0, 1
1 restricts the list to claims eligible for the next payslip.
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.
employee_id
string
status
enum: draft, submitted, approved, rejected, paid
page
integer
1-based page number.
per_page
integer
Items per page. The engine caps this at 200.

Responses

  • 200 Expenses. object
  • 401 The key is missing, unknown, or the HMAC signature did not verify. ErrorResponse
POST /expenses

Create a reimbursable expense

Send an amount, or send distance_km and let the engine value the claim at the organization's per-km rate. Reimbursements are paid on the payslip but sit outside gross - they are not taxable and carry no PF or ESI.

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

employee_id required
string
Employee id, or ext: + your own identifier.
category
string
Your own category name - travel, food, lodging.
description
string
What the claim is for. Printed as the reimbursement line on the payslip.
amount
number (double)
Claimed amount. Omit when sending distance_km.
distance_km
number
expense_date required
string (date)
When the expense was incurred.
include_in_payroll
boolean
receipt_url
string (uri)
Link to the receipt you hold.
status
enum: draft, submitted, approved
Send approved when the approval happened in your own workflow.

Responses

  • 201 Created. Expense
  • 400 The request was malformed or failed validation. ErrorResponse
Request
curl -X POST https://api.indpayroll.com/v1/expenses \
  -H "Authorization: Bearer $INDP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "employee_id": "ext:emp-1001",
  "category": "Travel",
  "description": "Client visit - Cuttack, two-wheeler",
  "distance_km": 64,
  "expense_date": "2026-09-11",
  "include_in_payroll": true,
  "status": "submitted"
}'
POST /expenses/{id}/approve

Approve an expense for the next run

Approved claims with include_in_payroll are picked up by any run calculated with include_expense_claims: true.

Path parameters

id required
string
INDPayroll id of the resource.

Body application/json · optional

approved_amount
number (double)
An amount in the organization's payroll currency, to two decimal places.
remarks
string

Responses

  • 200 Approved. Expense
  • 404 No such resource, or it belongs to an organization this key cannot reach. ErrorResponse
  • 409 The resource is in a state that forbids the change - a locked or paid run, a duplicate external_id, or a settlement already approved. ErrorResponse
GET /employees/{id}/advances

List advances and loans

Path parameters

id required
string
Employee id, or your own identifier prefixed with ext: - /employees/ext:emp-1001.

Responses

  • 200 Advances, with what is still outstanding. object
  • 404 No such resource, or it belongs to an organization this key cannot reach. ErrorResponse
POST /employees/{id}/advances

Create an advance with a recovery schedule

One installment is deducted per period from start_period until the principal is recovered. Any balance outstanding when the employee exits is recovered in the full and final settlement.

Path parameters

id required
string
Employee id, or your own identifier prefixed with ext: - /employees/ext:emp-1001.

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

type
enum: advance, loan
principal required
number (double)
An amount in the organization's payroll currency, to two decimal places.
installments required
integer
installment_amount
number (double)
An amount in the organization's payroll currency, to two decimal places.
start_period required
string
interest_percent
number
reason
string

Responses

  • 201 Created. Advance
  • 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/employees/{id}/advances \
  -H "Authorization: Bearer $INDP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "type": "advance",
  "principal": 60000,
  "installments": 6,
  "start_period": "2026-10",
  "reason": "Medical advance"
}'