Push clock events (clock in/out, breaks)
POST/v1/attendance/eventsships in v1.1scope: attendance:write
Submit up to 500 events per request. Each event is processed independently and the response lists one result per event, in the same order as the request.
Idempotent on external_id (per company and source): resending an event you already sent returns duplicate and changes nothing, so it is always safe to retry a request that timed out.
Employee matching. employee_ref identifies the person. Events whose employee cannot be matched are stored, not dropped, with result unmatched_employee: the company's HR team links the person once in Ahlan Hamad and every stored event for them is then processed automatically. You do not need to resend.
Branches. branch_ref is your identifier for the location. An unknown branch never rejects an event — it is stored as given and HR can map it later.
Clock events are paired into shifts in the company's timezone; a shift that crosses midnight belongs to the day it started. Break time is subtracted from worked time.
Request body
Example:
{
"events": [
{
"external_id": "qompos-sess-8812-in",
"employee_ref": {
"type": "external_id",
"value": "cashier-0042"
},
"type": "clock_in",
"at": "2026-09-29T08:02:11+04:00",
"branch_ref": "dubai-marina-01",
"source": "qompos"
},
{
"external_id": "qompos-sess-8812-out",
"employee_ref": {
"type": "external_id",
"value": "cashier-0042"
},
"type": "clock_out",
"at": "2026-09-29T16:31:40+04:00",
"branch_ref": "dubai-marina-01",
"source": "qompos"
}
]
}
Responses
| Status | Description | Body |
|---|
207 | Per-event results, in request order. | object |
400 | Malformed request (bad query parameter, invalid JSON, unknown cursor). | Problem |
401 | Missing, malformed, revoked or wrong-environment API key. | Problem |
403 | The key is valid but lacks the required scope (insufficient_scope), or the Partner API is not enabled for this company (api_not_enabled). | Problem |
413 | More than 500 events, or body larger than 1 MB. | Problem |
422 | The body is well-formed JSON but fails validation. | Problem |
429 | Too many requests for this key. | Problem |
Read back daily attendance
GET/v1/attendanceships in v1.1scope: attendance:read
One record per employee per day, as Ahlan Hamad holds it after pairing clock events. Includes days recorded by other sources (the employee app, manual HR entries) — check sources.
Parameters
| Name | In | Type | Description |
|---|
fromrequired | query | string (date) | |
torequired | query | string (date) | Inclusive. At most 62 days after from. |
employee_id | query | string | |
limit | query | integer | Page size. Range: 1–200Default: 50 |
cursor | query | string | Opaque next_cursor from the previous page. Omit for the first page. |
Responses
| Status | Description | Body |
|---|
200 | A page of attendance days. | Page + object |
400 | Malformed request (bad query parameter, invalid JSON, unknown cursor). | Problem |
401 | Missing, malformed, revoked or wrong-environment API key. | Problem |
403 | The key is valid but lacks the required scope (insufficient_scope), or the Partner API is not enabled for this company (api_not_enabled). | Problem |
429 | Too many requests for this key. | Problem |