Operations
Events and webhooks
What happened, as a list or as it happens.
List recent events
GET /v1/events
Recent events of one type, newest first, in exactly the shape webhooks deliver. Requires the scope that reads that data.
Parameters
type required | time_event.recorded | time_import.committed | workday.closed | absence.requested | absence.approved | absence.rejected | absence.cancelled | correction.approved | correction.rejected | employee.joined | |
since optional | string (date-time) | Only events from this moment on. |
limit optional | integer | |
cursor optional | string | The nextCursor of the previous page. |
Response 200
Each item in data:
id | string | Stable. The same event always has the same id. |
type | time_event.recorded | time_import.committed | workday.closed | absence.requested | absence.approved | absence.rejected | absence.cancelled | correction.approved | correction.rejected | employee.joined | |
apiVersion | v1 | |
occurredAt | string (date-time) | |
data | object | The same object the matching list endpoint returns. |
Possible errors: 401, 403, 422, 429.
Example
curl "https://api.mijornada.app/v1/events?type=absence.approved" \
-H "Authorization: Bearer mj_live_…" Example response
{
"data": [
{
"id": "ab:abc123:APPROVED",
"type": "absence.approved",
"apiVersion": "v1",
"occurredAt": "2026-10-15T07:02:11Z",
"data": {
"id": "abc123",
"employeeId": "abc123",
"employeeName": "Ana García López",
"employeeCode": "E014",
"type": "VACATION",
"status": "APPROVED",
"startDate": "2026-10-15",
"endDate": "2026-10-15",
"requestedDays": 5,
"requestedHours": null,
"createdAt": "2026-10-15T07:02:11Z",
"updatedAt": "2026-10-15T07:02:11Z"
}
}
],
"nextCursor": null
} List webhooks
GET /v1/webhooks
Requires the webhooks:manage scope.
Response 200
Each item in data:
id | string | |
targetUrl | string (uri) | |
events | time_event.recorded | time_import.committed | workday.closed | absence.requested | absence.approved | absence.rejected | absence.cancelled | correction.approved | correction.rejected | employee.joined[] | |
filters | object | Only send matching events. Applies to time_event.recorded. |
apiVersion | string | |
status | ACTIVE | DISABLED | |
disabledReason | KEY_REVOKED | TARGET_GONE | TOO_MANY_FAILURES | |
lastSuccessAt | string (date-time) | null | |
createdAt | string (date-time) |
Possible errors: 401, 403, 429.
Example
curl "https://api.mijornada.app/v1/webhooks" \
-H "Authorization: Bearer mj_live_…" Example response
{
"data": [
{
"id": "abc123",
"targetUrl": "https://hooks.example.com/mijornada",
"events": [
"time_event.recorded"
],
"filters": {
"action": "IN",
"worksiteId": "centro-1"
},
"apiVersion": "v1",
"status": "ACTIVE",
"disabledReason": "KEY_REVOKED",
"lastSuccessAt": "2026-10-15T07:02:11Z",
"createdAt": "2026-10-15T07:02:11Z"
}
],
"nextCursor": null
} Create a webhook
POST /v1/webhooks
MiJornada sends a signed POST to targetUrl for each event, about two
minutes after it happens. A clock event is held 90 seconds because it
can still be undone.
Each delivery carries X-MiJornada-Signature: t=<unix>,v1=<hmac>, the
HMAC-SHA256 of <t>.<body> with the secret returned here. It is shown
only once.
Failed deliveries are retried up to 12 times over about a day. Answering
410 stops the webhook. So do 20 failures in a row and three days without
a success, and the company owner is told. Requires the webhooks:manage
scope, plus the scope that reads each event.
Body
targetUrl required | string (uri) | A public https URL. |
events required | time_event.recorded | time_import.committed | workday.closed | absence.requested | absence.approved | absence.rejected | absence.cancelled | correction.approved | correction.rejected | employee.joined[] | |
filters optional | object | Only send matching events. Applies to time_event.recorded. |
Response 201
id | string | |
targetUrl | string (uri) | |
events | time_event.recorded | time_import.committed | workday.closed | absence.requested | absence.approved | absence.rejected | absence.cancelled | correction.approved | correction.rejected | employee.joined[] | |
filters | object | Only send matching events. Applies to time_event.recorded. |
apiVersion | string | |
status | ACTIVE | DISABLED | |
disabledReason | KEY_REVOKED | TARGET_GONE | TOO_MANY_FAILURES | |
lastSuccessAt | string (date-time) | null | |
createdAt | string (date-time) | |
secret | string |
Possible errors: 401, 403, 409, 422, 429.
Example
curl -X POST "https://api.mijornada.app/v1/webhooks" \
-H "Authorization: Bearer mj_live_…" \
-H "Content-Type: application/json" \
-d '{"targetUrl":"https://hooks.example.com/mijornada","events":["time_event.recorded"]}' Example response
{
"id": "abc123",
"targetUrl": "https://hooks.example.com/mijornada",
"events": [
"time_event.recorded"
],
"filters": {
"action": "IN",
"worksiteId": "centro-1"
},
"apiVersion": "v1",
"status": "ACTIVE",
"disabledReason": "KEY_REVOKED",
"lastSuccessAt": "2026-10-15T07:02:11Z",
"createdAt": "2026-10-15T07:02:11Z",
"secret": "whsec_…"
} Delete a webhook
DELETE /v1/webhooks/{id}
Deleting one that no longer exists also returns 204.
Parameters
id required | string |
Response 204
No content.
Possible errors: 401, 403, 429.
Example
curl -X DELETE "https://api.mijornada.app/v1/webhooks/abc123" \
-H "Authorization: Bearer mj_live_…" Last updated: .