Time & Attendance
Submit time punches and sync time data between Netchex and a third-party scheduling or T&A system.
This guide covers syncing time-and-attendance data in both directions: retrieving punches already recorded in Netchex, and submitting new punches and earnings.
A punch in this API is a single clock event, not an in/out pair. Each punch has one time and one type (In, Out, InLunch, OutLunch, InBreak, OutBreak, InPaidBreak, OutPaidBreak, InUnpaidBreak, OutUnpaidBreak). A shift is represented as several punches, not one record with both times on it.
Overview
Five endpoints power the T&A sync workflow:
GET /time-punches: retrieve punches within a date range (v3)POST /api/TimePunches/byEmpCodeAndComboDept: submit a batch of punches by employee code, per-record error reporting (v1)POST /api/TimePunches: submit a batch of punches by employee ID, all-or-nothing per company (v1)POST /api/Timecard/earning: submit earnings for a timecard entry (v1)GET /direct-entry-earnings: retrieve earnings already recorded (v3)
Step 1: Retrieve time punches
GET https://external-api.netchexonline.net/time-punches?start-date=2024-01-01&end-date=2024-01-31&company-ids=101&page-size=250&api-version=3.0
Authorization: ApiKey YOUR_API_KEYKey parameters:
| Parameter | Type | Description |
|---|---|---|
start-date | date | Required. Start of the punch date range |
end-date | date | Required. End of the punch date range |
organization-ids, company-ids, or employee-ids | array | Exactly one of these three is required. Providing more than one, or none, returns 400 |
data-source | string | Optional, filter by data source |
project-ids, client-ids | array | Optional, further filter results |
page-size | integer | Max rows per page (1 to 250, default 50) |
page-number | integer | 1-based page number |
{
"pageNumber": 1,
"pageSize": 250,
"totalItemsCount": 1842,
"items": [
{
"id": "98001",
"employeeId": 5001,
"companyId": 101,
"time": "2024-01-15T08:02:00Z",
"type": "In",
"departmentId": 10,
"projectId": null,
"uniqueExternalId": null,
"dataSource": "Swipe",
"sequenceNumber": 1
}
]
}id is a string. Each punch is its own item with one time and one type.
Returns 404 if no records match the filters at all, distinct from an empty page. page-size maxes out at 250. Use pagination for date ranges spanning several weeks.
Step 2: Submit new time punches
If your source system stores employee codes rather than internal IDs, use this endpoint. It reports errors per punch instead of failing the whole batch:
POST https://external-api.netchexonline.net/api/TimePunches/byEmpCodeAndComboDept?api-version=1.0
Authorization: ApiKey YOUR_API_KEY
Content-Type: application/json[
{
"companyId": 101,
"employeeCode": "EMP-1234",
"comboDivBuDeptCode": "DIV-1/BU-1/DEPT-A",
"time": "2024-01-22T08:00:00Z",
"timeZoneOffset": -300,
"type": "In"
}
]comboDivBuDeptCode is three codes joined with /: division, then business unit, then department, in that order.
If any punch fails, the response is 422 Unprocessable Entity with an error per failed punch, everything else in the batch is still saved:
[
{ "companyId": 101, "employeeCode": "EMP-1234", "error": "Department `DIV-1/BU-1/DEPT-A` does not exist or you do not have access." }
]Alternative: submit by employee ID
If you already have internal Netchex employee and department IDs, you can submit directly against them. The tradeoff: if any punch in the batch fails, nothing in that batch is saved for the affected company, validate on your side first.
POST https://external-api.netchexonline.net/api/TimePunches?api-version=1.0
Authorization: ApiKey YOUR_API_KEY
Content-Type: application/json[
{
"companyId": 101,
"employeeId": 5001,
"departmentId": 10,
"time": "2024-01-22T08:00:00Z",
"timeZoneOffset": -300,
"type": "In"
}
]Step 3: Submit earnings for a timecard
Earnings attached to a timecard (regular hours, overtime, tips, and similar) use their own endpoint and their own set of codes, not IDs:
POST https://external-api.netchexonline.net/api/Timecard/earning?api-version=1.0
Authorization: ApiKey YOUR_API_KEY
Content-Type: application/jsonThe path is /api/Timecard/earning, with a capital T and no versioned path segment.
[
{
"employeeCode": "EMP-1234",
"companyId": 101,
"companyCode": "ACME",
"divisionCode": "DIV-1",
"businessUnitCode": "BU-1",
"departmentCode": "DEPT-A",
"locationCode": "LOC-1",
"userCode": "jsmith",
"payCode": "REG",
"units": 8.0,
"date": "2024-01-22",
"comments": "Regular shift",
"clientCode": null,
"projectCode": 0
}
]projectCode doesn't accept null, it's a plain integer. Send 0 (or omit the field) when there's no project to associate.
This endpoint identifies everything by code, not by internal ID, unlike the punch endpoints above. employeeCode here is the same code you'd use for byEmpCodeAndComboDept.
Step 4: Retrieve earnings
GET https://external-api.netchexonline.net/direct-entry-earnings?start-date=2024-01-01&end-date=2024-01-31&company-ids=101&api-version=3.0
Authorization: ApiKey YOUR_API_KEYSame filter rules as GET /time-punches: start-date and end-date are required, and exactly one of organization-ids, company-ids, or employee-ids is required.
{
"pageNumber": 1,
"pageSize": 50,
"totalItemsCount": 1,
"items": [
{
"directEntryEarningId": 55001,
"employeeId": 5001,
"companyEarningId": 1,
"units": 8.0,
"rate": 22.50,
"grossAmount": 180.00,
"date": "2024-01-22",
"departmentId": 11,
"projectId": null,
"comment": "Regular shift",
"uniqueExternalId": null,
"dataSource": "Manual"
}
]
}rate on the response above shows you the rate that was actually applied.
Can an employee be paid a different rate depending on which department they work in? Yes, if department transfer is set up for your company. An employee working across multiple departments can be paid at each department's own rate rather than one fixed rate, departmentId on the earning is what determines which rate applies. Confirm with your Netchex representative whether department transfer is configured for you.
Coming soon: a v3 batch contract
The v1 endpoints above already batch (see "Step 2: Submit new time punches"). This section is about a separate, not-yet-published v3 batch contract — not available on this API today, described here so you know what's planned and can plan around it, or ask for early access.
Netchex's own internal sync pipeline submits punches and direct-entry earnings against a newer v3 batch endpoint, not the v1 ones documented above. We're extending that same v3 batch path to this API. The shape we expect to publish:
{
"items": [
{
"employeeId": "5001",
"time": "2024-01-22T08:00:00Z",
"departmentId": "10",
"type": "In",
"dataSource": "netchex:your-integration-name",
"comment": "optional",
"externalUniqueId": "optional, for idempotent retries"
}
]
}{
"items": [
{
"employeeId": "5001",
"companyEarningId": 3,
"units": 8.0,
"date": "2024-01-22",
"departmentId": "10",
"dataSource": "netchex:your-integration-name",
"transferCodeType": "optional",
"uniqueExternalId": "optional, for idempotent retries"
}
]
}externalUniqueId/uniqueExternalId is the field we care about most for anything syncing on a schedule: it's what lets a re-run of the same batch (after a timeout, a retry, a redeploy) skip records it already submitted instead of double-posting them. If your integration needs this v3 contract sooner than it's publicly available, reach out to the Netchex Integrations team.
Try it in the playground
Test these endpoints interactively in the API reference: