Create payslips in bulk
accounting:payrolls.writehttps://api.holded.com/api/v2/payslipsCreates payslips (nóminas) in bulk for a collection of employees in a given liquidation period. This creates PAYSLIPS, NOT salary records (registros salariales) — use /api/v2/salary-records for those. Never call this endpoint when the user asks for a salary record, and never call the salary-record endpoint when the user asks for a payslip. Creation is asynchronous and the response body is empty: there is no job id and no endpoint to poll for status or results. An employee id that cannot be resolved for the account, whose liquidation period is locked, or who already has an approved payslip of any kind overlapping the liquidation month (the calendar month of liquidation_period_start_date), is silently skipped for that employee only — the rest of the batch still succeeds. The same happens for every employee in the batch when the account has no payroll scheme or its default accounting account cannot be resolved. If every employee id in the batch is skipped, the response is still 202 and there is no way to confirm what was actually created. Generating over an approved payslip is not supported: the approved payslip must be deleted first, explicitly, by the user. This endpoint is not idempotent: calling it twice with the same employees and period creates duplicate draft payslips. Do not retry a call whose outcome is unknown.
Request body
Internal ids (24-char hex ObjectId) of the employees to create a payslip for (must be active in the same account). Resolve a name or code to an id first via GET /api/v2/employees — never invent an id. One request creates one payslip per employee. Duplicate ids are collapsed to a single payslip.
Any date within the liquidation period to create payslips for (ISO 8601, YYYY-MM-DD). The whole calendar month is used — day-of-month is ignored. Periods before 2025 are not supported.
Request
import requests
url = "https://api.holded.com/api/v2/payslips"
headers = {
"Authorization": "Bearer YOUR_API_KEY",
"Accept": "application/json",
}
payload = {
"employee_ids": [
"507f1f77bcf86cd799439011",
"507f1f77bcf86cd799439012"
],
"liquidation_period_start_date": "2026-01-01"
}
response = requests.post(url, headers=headers, json=payload)
print(response.json())Responses
Success responses
202Payslip creation job accepted (empty body)Error responses
400Bad requestapplication/json401Invalid or missing API keyapplication/json402The Human Resources gem is not active for this accountapplication/json403Insufficient permissionsapplication/json422Liquidation period start date is earlier than 2025application/json429Rate limit exceededapplication/json