Create multiple contributions for a specified employer in a single request. Asynchronous — the response is an Upload object representing queued work, not a final result. Contribution identifiers are not available in this response; poll GET /uploads/{upload_id} until the status is terminal, then fetch contributions via GET /uploads/{upload_id}/contributions and any errors via GET /uploads/{upload_id}/errors. Processing is idempotent per pay period: re-submitting the same records will only process those not already created successfully — the recommended way to recover from a PartiallyProcessed upload.
Body
Required
An array of ContributionBody objects representing the contributions to be created.
-
Identifier for the employee associated with the contribution.
-
The updated amount of the employer's contribution for the given pay period.
-
The updated amount of the employee's contribution for the given pay period.
-
The updated employer's contribution percentage for the given pay period. Accepts whole numbers or decimals with up to 3 decimal places (e.g. 4.561). Minimum 0, maximum 100.
Minimum value is
0, maximum value is100. -
The updated employee's contribution percentage for the given pay period. Accepts whole numbers or decimals with up to 3 decimal places (e.g. 4.561). Minimum 0, maximum 100.
Minimum value is
0, maximum value is100. -
The start date of the pay period for which the contributions were made, in YYYY-MM-DD format.
-
The end date of the pay period for which the contributions were made, in YYYY-MM-DD format.
-
Your platform's unique identifier for this employee. Penfold stores it to link the employee back to your platform, for example when the employee signs in to Penfold through your platform. Required for employers managed by a Partner organisation that uses single sign-on with Penfold; omit it otherwise. Maximum 255 characters.
Maximum length is
255.
Responses
-
Submission created successfully for the contributions.
-
Bad request, the request is malformed or contains invalid data.
-
Unauthorized, the request requires authentication, and the provided credentials are either missing or incorrect.
-
Employer not found, the specified employer_id does not match any existing employer.
curl \
--request POST 'https://payroll-api.getpenfold.dev/v4/employers/{employer_id}/contributions' \
--header "Authorization: Bearer $ACCESS_TOKEN" \
--header "Content-Type: application/json" \
--data '[
{
"employee_id": "e9876-wxyz-4321-stuv",
"employer_contributions_amount": 1200.0,
"employee_contributions_amount": 300.0,
"employer_contributions_percent": 4.561,
"employee_contributions_percent": 4.561,
"pay_period_start_date": "2023-03-01",
"pay_period_end_date": "2023-03-15",
"external_id": "emp_01HXYZ"
}
]'
[
{
"employee_id": "e9876-wxyz-4321-stuv",
"employer_contributions_amount": 1200.0,
"employee_contributions_amount": 300.0,
"employer_contributions_percent": 4.561,
"employee_contributions_percent": 4.561,
"pay_period_start_date": "2023-03-01",
"pay_period_end_date": "2023-03-15",
"external_id": "emp_01HXYZ"
}
]
{
"id": "string",
"employer_id": "string",
"put_destination_url": "string",
"created_at": "2026-05-04T09:42:00Z",
"updated_at": "2026-05-04T09:42:00Z",
"processing_started": "2023-03-01T11:00:00Z",
"processing_ended": "2023-03-01T12:00:00Z",
"processing_time": 47,
"total_errors": 10,
"contributions_created": 5,
"contributions_unprocessed": 0,
"contributions_already_existed": 0,
"employer_contributions": "500.34",
"employee_contributions": "734.11",
"total_contributions": "1234.45",
"filename": "papdis.csv",
"status": "Processed"
}
{
"error": "Bad request: invalid data provided.",
"validation_errors": [
{
"field": "email",
"message": "Email address is invalid."
}
]
}
{
"error": "Bad request: invalid data provided."
}
{
"error": "Bad request: invalid data provided."
}