Skip to content
MiJornada

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: .