Ingest payroll time events
POST/payroll/time-events
Batch-ingests time-tracking events from external HR, attendance, or timesheet systems into the payroll module. Events are correlated with the specified payroll run for calculation. Supply an Idempotency-Key header to safely retry on network failure without duplicating records; the key is tied to external_event_id per event.
Request
Header parameters
| Name | Type | Required | Description |
|---|---|---|---|
Idempotency-Key | string | No | A client-generated unique key for this batch. Repeating the same key within 24 hours returns the original accepted response without re-processing the batch. Max length: 128 |
Request body
Content type application/json (required).
| Field | Type | Required | Description |
|---|---|---|---|
payroll_run_id | integer | No | Optional ID of the payroll run to associate these events with. If omitted, events are held in a staging queue for the next open run. |
events | array of object · PayrollTimeEventV1 | Yes | Array of time event records to ingest (maximum 500 per request). Min items: 1 · Max items: 500 |
events[].external_event_id | string | No | Client-provided unique identifier for the event. Used for idempotent re-ingestion — duplicate external_event_ids are silently skipped. Max length: 128 |
events[].employee_id | integer | Yes | ID of the employee this event belongs to. |
events[].event_type | string | Yes | Classification of the time event. "timesheet" — a weekly/bi-weekly approved hours summary. "punch" — an individual clock-in/clock-out record. "overtime" — overtime hours claimed for premium pay. "leave_impact" — leave taken that affects payable hours. One of: |
events[].occurred_at | string (date-time) | Yes | Timestamp when the event was recorded or the timesheet was approved. |
events[].starts_at | string (date-time), nullable | No | Start of the period covered by this event (for timesheet or range events). |
events[].ends_at | string (date-time), nullable | No | End of the period covered by this event. |
events[].hours | number (float), nullable | No | Total hours represented by this event. Required for timesheet and overtime types. |
events[].source | string, nullable | No | Identifier of the originating system (e.g. "clockify", "bamboohr", "manual"). Max length: 80 |
events[].payload | object | No | Optional provider-specific metadata (e.g. project codes, approval references) passed through for audit. |
Example
{
"payroll_run_id": 14,
"events": [
{
"external_event_id": "ts_wk14_emp42",
"employee_id": 42,
"event_type": "timesheet",
"occurred_at": "2026-04-07T17:00:00Z",
"starts_at": "2026-04-01T08:00:00Z",
"ends_at": "2026-04-07T17:00:00Z",
"hours": 35.5,
"source": "clockify",
"payload": {
"project": "CLIENT_A",
"approved_by": 7
}
},
{
"external_event_id": "ot_wk14_emp42",
"employee_id": 42,
"event_type": "overtime",
"occurred_at": "2026-04-06T20:00:00Z",
"hours": 3.0,
"source": "clockify"
}
]
}
Responses
202 Events accepted for processing. Individual event failures are reported in the response
Content type application/json, object.
| Field | Type | Required | Description |
|---|---|---|---|
accepted | integer | No | Number of events successfully queued. |
rejected | integer | No | Number of events rejected due to validation errors. |
errors | array of object | No | Per-event validation errors for rejected events. |
errors[].index | integer | No | |
errors[].external_event_id | string | No | |
errors[].reason | string | No |
Example
{
"accepted": 2,
"rejected": 0,
"errors": []
}
422 Validation failed — top-level request structure is invalid
Example request
curl -X POST "https://{tenant}.faciotech.net/api/v1/payroll/time-events" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"payroll_run_id": 14, "events": [{"external_event_id": "ts_wk14_emp42", "employee_id": 42, "event_type": "timesheet", "occurred_at": "2026-04-07T17:00:00Z", "starts_at": "2026-04-01T08:00:00Z", "ends_at": "2026-04-07T17:00:00Z", "hours": 35.5, "source": "clockify", "payload": {"project": "CLIENT_A", "approved_by": 7}}, {"external_event_id": "ot_wk14_emp42", "employee_id": 42, "event_type": "overtime", "occurred_at": "2026-04-06T20:00:00Z", "hours": 3.0, "source": "clockify"}]}'