Practical Example: Clock In a Shift

An end-to-end walkthrough — get notified the moment an employee clocks in a shift in Factorial.

This example walks through a complete webhook integration, from subscription to payload, using the attendance/shift/clock_in event.

When is the event triggered?

The event fires when an employee clocks in a shift and the timer starts — for example by clicking Clock in in Factorial, or clocking in from the mobile app.

Step 1 — Create the subscription

Use attendance/shift/clock_in as the subscription_type:

curl --request POST \
  --url https://api.factorialhr.com/api/2026-10-01/resources/api_public/webhook_subscriptions \
  --header 'x-api-key: YOUR_API_KEY' \
  --header 'content-type: application/json' \
  --header 'accept: application/json' \
  --data '{
    "company_id": 55,
    "subscription_type": "attendance/shift/clock_in",
    "target_url": "https://yourapp.com/webhooks/factorial/clock-in",
    "name": "Shift clock in",
    "challenge": "2zal4e6d",
    "enabled": true,
    "api_version": "2026-10-01"
  }'
curl --request POST \
  --url https://api.factorialhr.com/api/2026-10-01/resources/api_public/webhook_subscriptions \
  --header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
  --header 'content-type: application/json' \
  --header 'accept: application/json' \
  --data '{
    "company_id": 55,
    "subscription_type": "attendance/shift/clock_in",
    "target_url": "https://yourapp.com/webhooks/factorial/clock-in",
    "name": "Shift clock in",
    "challenge": "2zal4e6d",
    "enabled": true,
    "api_version": "2026-10-01"
  }'

Keep the id from the response so you can disable or delete the subscription later.

Step 2 — Receive the payload

When an employee clocks in, Factorial sends:

{
  "employee_id": 1,
  "now": "2026-06-23T11:00:00.000+00:00",
  "latitude": 52.377956,
  "longitude": 4.89707,
  "accuracy": 5,
  "observations": "I clocked in 10 minutes before",
  "location_type": "business_trip",
  "workplace_id": 5,
  "time_settings_break_configuration_id": 2,
  "project_worker_id": 3,
  "subproject_id": 4
}
FieldDescription
employee_idThe employee who clocked in
nowTimestamp of the clock in
latitude / longitude / accuracyGeolocation captured at clock in, when available
observationsFree-text note entered by the employee
location_typeWhere the shift is worked, e.g. office, work_from_home, business_trip
workplace_idThe workplace associated with the shift
time_settings_break_configuration_idBreak configuration applied to the shift
project_worker_id / subproject_idProject assignment, when time is tracked against projects

Step 3 — Handle it

app.post("/webhooks/factorial/clock-in", async (req, res) => {
  if (req.get("x-factorial-wh-challenge") !== process.env.FACTORIAL_WH_CHALLENGE) {
    return res.sendStatus(401);
  }

  const shift = req.body;

  // Acknowledge immediately, then process out of band
  res.sendStatus(200);

  // Retries carry an identical body, so this key skips duplicates
  const dedupeKey = `clock_in:${shift.employee_id}:${shift.now}`;
  if (await processedEvents.exists(dedupeKey)) return;

  await externalTimeTracker.startShift({
    employeeId: shift.employee_id,
    startedAt: shift.now,
    workplaceId: shift.workplace_id
  });

  await processedEvents.insert(dedupeKey);
});

Why subscribe to this event?

  • Trigger an action in an external system the moment an employee starts work — access control, machine assignment, task dispatch.
  • Keep shifts in sync with an external time-tracking or workforce-management platform.
  • Feed real-time presence data into dashboards or operational tooling.

Related


Did this page help you?