Events
Your agency sends events to Stafflion at POST {base}/api/v1/webhooks/partners, where {base} is the base URL of the environment (see Before you start). Authenticate with the Bearer token from the token endpoint.
Common request fields
| Field | Type | Required | Description |
|---|---|---|---|
event_name | string | yes | One of shift_request, shift_claimed, shift_update, shift_call_out. |
event_data | object | yes | Payload for the event. See each event below. |
occurred_at | string | yes | Date and time when the event occurred, in UTC (RFC3339). Example: 2026-07-24T00:00:00.000Z. |
Send Authorization: Bearer <access_token> and Content-Type: application/json.
shift_request
Your agency requests to work a shift Stafflion published. The request carries the full shift and clinician details.
| Field | Type | Required | Description |
|---|---|---|---|
partner_facility_id | string | yes | Partner facility ID. |
partner_shift_id | string | yes | Partner shift ID of a shift Stafflion published. |
shift_start_time | string | yes | Shift start time in UTC (RFC3339). |
shift_end_time | string | yes | Shift end time in UTC (RFC3339). |
partner_clinician | object | yes | Clinician details. See Clinician. |
{
"event_name": "shift_request",
"event_data": {
"partner_facility_id": "efa61cc1-caf8-4544-9f3a-a8946d51026b",
"partner_shift_id": "deb1b3c4-72a8-493a-ba34-46eebb81ef94",
"shift_start_time": "2026-07-24T07:00:00.000Z",
"shift_end_time": "2026-07-24T15:00:00.000Z",
"partner_clinician": {
"id": "a98600a7-6c73-4095-ab17-7c5d8c02870c",
"first_name": "Jane",
"last_name": "Doe",
"email": "jdoe@example.com",
"phone": "000-000-0000",
"position": "CNA",
"clinician_tier": "Tier 1",
"compensation": {
"base_hourly_rate": 35.0,
"overtime_hourly_rate": 52.5,
"bonus": {"type": "fixed", "value": 100.0}
}
}
},
"occurred_at": "2026-07-24T00:00:00.000Z"
}
shift_claimed
Your agency confirms that a clinician claimed the shift. For a shift Stafflion did not publish, include shift_start_time and shift_end_time, and Stafflion creates the shift.
| Field | Type | Required | Description |
|---|---|---|---|
partner_facility_id | string | yes | Partner facility ID. |
partner_shift_id | string | yes | Partner shift ID. |
partner_clinician | object | yes | Clinician details. See Clinician. |
shift_id | string | no | Stafflion shift ID, only if your agency maps it. |
partner_secondary_shift_id | string | no | Secondary partner shift ID. |
shift_start_time | string | when Stafflion did not publish the shift | Shift start time in UTC (RFC3339). |
shift_end_time | string | when Stafflion did not publish the shift | Shift end time in UTC (RFC3339). |
{
"event_name": "shift_claimed",
"event_data": {
"partner_facility_id": "efa61cc1-caf8-4544-9f3a-a8946d51026b",
"partner_shift_id": "deb1b3c4-72a8-493a-ba34-46eebb81ef94",
"shift_start_time": "2026-07-24T07:00:00.000Z",
"shift_end_time": "2026-07-24T15:00:00.000Z",
"partner_clinician": {
"id": "a98600a7-6c73-4095-ab17-7c5d8c02870c",
"first_name": "Jane",
"last_name": "Doe",
"email": "jdoe@example.com",
"phone": "000-000-0000",
"position": "CNA",
"compensation": {
"base_hourly_rate": 35.0,
"overtime_hourly_rate": 52.5,
"bonus": {"type": "percentage", "value": 10.0}
}
}
},
"occurred_at": "2026-07-24T00:00:00.000Z"
}
shift_update
Send this event only after a shift_claimed has been sent for the shift, that is, once the shift is taken by a clinician.
| Field | Type | Required | Description |
|---|---|---|---|
partner_facility_id | string | yes | Partner facility ID. |
partner_shift_id | string | yes | Partner shift ID. |
shift_start_time | string | yes | New shift start time in UTC (RFC3339). |
shift_end_time | string | yes | New shift end time in UTC (RFC3339). |
shift_id | string | no | Stafflion shift ID, only if your agency maps it. |
{
"event_name": "shift_update",
"event_data": {
"partner_facility_id": "efa61cc1-caf8-4544-9f3a-a8946d51026b",
"partner_shift_id": "deb1b3c4-72a8-493a-ba34-46eebb81ef94",
"shift_start_time": "2026-07-24T08:00:00.000Z",
"shift_end_time": "2026-07-24T16:00:00.000Z"
},
"occurred_at": "2026-07-24T00:00:00.000Z"
}
shift_call_out
| Field | Type | Required | Description |
|---|---|---|---|
partner_facility_id | string | yes | Partner facility ID. |
partner_shift_id | string | yes | Partner shift ID. |
partner_clinician_id | string | yes | Partner clinician ID. |
{
"event_name": "shift_call_out",
"event_data": {
"partner_facility_id": "efa61cc1-caf8-4544-9f3a-a8946d51026b",
"partner_shift_id": "deb1b3c4-72a8-493a-ba34-46eebb81ef94",
"partner_clinician_id": "a98600a7-6c73-4095-ab17-7c5d8c02870c"
},
"occurred_at": "2026-07-24T00:00:00.000Z"
}
Clinician
| Field | Type | Required | Description |
|---|---|---|---|
id | string | yes | Partner clinician ID. |
first_name | string | yes | First name. |
last_name | string | yes | Last name. |
email | string | yes | Email. |
phone | string | yes | Phone. |
position | string | yes | Exact position name, for example LPN. |
compensation | object | yes | Pay details. See below. |
clinician_tier | string | no | Clinician tier as free text, for example Tier 1. |
Compensation
| Field | Type | Required | Description |
|---|---|---|---|
base_hourly_rate | number | yes | Base hourly rate without bonuses. |
overtime_hourly_rate | number | yes | Overtime hourly rate. |
bonus | object | yes | type is fixed or percentage. value is the amount, or the percentage. |
The latest event for a clinician replaces the previous pay details. A percentage bonus is applied to base_hourly_rate over the shift length.
Responses
A successful event returns 200 with message and shift. clinician is returned when the event identifies a clinician.
{
"message": "success",
"shift": {
"id": 1048012,
"partner_shift_id": "deb1b3c4-72a8-493a-ba34-46eebb81ef94",
"partner_secondary_shift_id": null
},
"clinician": {
"id": 139898,
"partner_clinician_id": "a98600a7-6c73-4095-ab17-7c5d8c02870c"
}
}
Error responses carry only message:
{
"message": "Shift not found"
}
Error messages
| Status | Message | When |
|---|---|---|
| 404 | Shift not found | The shift is unknown, deleted, or not shared with your agency. A shift_claimed for a shift Stafflion did not publish also returns this when it has no shift_start_time and shift_end_time. |
| 404 | Facility not found with the ID '<partner_facility_id>' | The partner facility is not linked to a Stafflion facility. |
| 400 | Shift has already ended | The shift end time has passed. |
| 400 | Shift is already taken | Another clinician already holds the shift. |
| 400 | Clinician doesn't have the required position to claim this shift | The clinician's position does not match the shift. |
| 400 | More than one shift/slot found. Please provide a clinician identifier to disambiguate | Several shifts match and no clinician identifier was sent. |
| 400 | No shift found for the given clinician | No shift matches the given clinician. |
| 400 | Shift is not taken by any clinician | The shift has no clinician to call out. |
| 400 | Missing param 'partner_facility_id', Missing 'partner_shift_id' param, Missing param 'partner_clinician_id' | A required identifier is missing from shift_request. |
| 400 | Missing 'shift_id' or 'partner_shift_id' param | shift_update has no shift identifier. |
| 422 | Validation failed | The body is invalid. errors lists each invalid field. |