Create multiple contributions for a specified employer in a single request

Add MCP server to your AI tool

Allow AI tools and LLMs to interact with the API documentation portal through MCP.

MCP server URL

https://docs.getpenfold.dev/mcp

Standard setup for AI tools providing an mcp.json file

mcp.json
"Penfold Partner API MCP server": {
  "url": "https://docs.getpenfold.dev/mcp"
}
Close
POST /employers/{employer_id}/contributions

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.

Path parameters

  • employer_id string Required
application/json

Body Required

An array of ContributionBody objects representing the contributions to be created.

  • employee_id string Required

    Identifier for the employee associated with the contribution.

  • employer_contributions_amount number(money) Required

    The updated amount of the employer's contribution for the given pay period.

  • employee_contributions_amount number(money) Required

    The updated amount of the employee's contribution for the given pay period.

  • employer_contributions_percent number(int)

    The updated employer's contribution percentage for the given pay period.

    Minimum value is 0, maximum value is 100.

  • employee_contributions_percent number(int)

    The updated employee's contribution percentage for the given pay period.

    Minimum value is 0, maximum value is 100.

  • pay_period_start_date string(date) Required

    The start date of the pay period for which the contributions were made, in YYYY-MM-DD format.

  • pay_period_end_date string(date) Required

    The end date of the pay period for which the contributions were made, in YYYY-MM-DD format.

Responses

  • 201 application/json

    Submission created successfully for the contributions.

    Hide response attributes Show response attributes object
    • id string Required

      ID of the upload.

    • employer_id string | null

      ID of the employer the upload was made for.

    • put_destination_url string | null Required

      Destination URL where the actual file should be sent, using a PUT request. Only present when status is AwaitingFile. We recommend using the AWS S3 client SDK to perform the upload.

    • created_at string(date-time) Required

      Datetime the upload was created.

    • updated_at string(date-time) Required

      Datetime the upload was last updated.

    • processing_started string(date-time) | null Required

      Datetime of when processing of the file began.

    • processing_ended string(date-time) | null Required

      Datetime of when processing of the file ended, or null if it has not ended.

    • processing_time number | null Required

      The number of seconds it took to process the file end-to-end (if applicable).

    • total_errors number Required

      The number of errors produced in processing the file. Zero if there are none or processing is not finished. Use the {upload_id}/errors endpoint to retrieve detailed information of the errors.

    • contributions_created number Required

      The number of contributions created during processing. Zero if processing is not finished.

    • contributions_unprocessed number

      The number of contributions that failed to be created during processing. Zero if processing is not finished.

    • contributions_already_existed number Required

      The number of contributions that already existed prior to processing, and which have been skipped during processing of the upload. Zero if processing is not finished.

    • employer_contributions number Required

      The total of employer contributions created for the upload, excluding contributions that already existed. Zero if processing is not finished.

    • employee_contributions number Required

      The total of employee contributions created for the upload, excluding contributions that already existed. Zero if processing is not finished.

    • total_contributions number Required

      The total of contributions created for the upload, excluding contributions that already existed. Zero if processing is not finished.

    • filename string | null Required

      The filename of the uploaded file (if applicable).

    • status string Required

      The status of the upload. Error indicates the file was not able to be processed. PartiallyProcessed indicates that validation passed and processing ran eagerly, but some records succeeded while others produced errors — treat this status as incomplete and re-submit the failing records (or the entire file) to recover. Processing is idempotent per pay period, so successfully-processed records will be skipped on re-submission. To retrieve the errors for an Error or PartiallyProcessed upload, use the /uploads/{upload_id}/errors endpoint.

      Values are AwaitingFile, ReceivedFile, Processing, Processed, Error, Timeout, or PartiallyProcessed.

  • 400 application/json

    Bad request, the request is malformed or contains invalid data.

    Hide response attributes Show response attributes object
    • error string

      A descriptive error message.

    • validation_errors array[object]
      Hide validation_errors attributes Show validation_errors attributes object
      • field string Required

        The name of the field that failed validation.

      • message string Required

        A descriptive error message.

  • 401 application/json

    Unauthorized, the request requires authentication, and the provided credentials are either missing or incorrect.

    Hide response attribute Show response attribute object
    • error string

      A descriptive error message.

  • 404 application/json

    Employer not found, the specified employer_id does not match any existing employer.

    Hide response attribute Show response attribute object
    • error string

      A descriptive error message.

POST /employers/{employer_id}/contributions
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":10,"employee_contributions_percent":20,"pay_period_start_date":"2023-03-01","pay_period_end_date":"2023-03-15"}]'
Request examples
[
  {
    "employee_id": "e9876-wxyz-4321-stuv",
    "employer_contributions_amount": 1200.0,
    "employee_contributions_amount": 300.0,
    "employer_contributions_percent": 10,
    "employee_contributions_percent": 20,
    "pay_period_start_date": "2023-03-01",
    "pay_period_end_date": "2023-03-15"
  }
]
Response examples (201)
{
  "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"
}
Response examples (400)
{
  "error": "Bad request: invalid data provided.",
  "validation_errors": [
    {
      "field": "email",
      "message": "Email address is invalid."
    }
  ]
}
Response examples (401)
{
  "error": "Bad request: invalid data provided."
}
Response examples (404)
{
  "error": "Bad request: invalid data provided."
}