Team members
Team members are technicians, booking owners and calendar slots. They're used as assignees on several other resources — look them up here before setting assigned_team_member_id or employee_id on work orders, maintenance contracts, appointments and certifications.
Scopes: bookings.team.read / bookings.team.write.
Endpoints
/api/workspace/v1/team-members/api/workspace/v1/team-members/{id}/api/workspace/v1/team-members/api/workspace/v1/team-members/{id}/api/workspace/v1/team-members/{id}/api/workspace/v1/team-members/{id}/availabilityQuery availability
Returns the available booking slots for a team member within a date range. Honors per-staff schedule, time-off, existing bookings and (if connected) Google Calendar or Outlook busy intervals. When the member is linked to a calendar group (linked_calendar_group_id), appointments booked through that group's agents, held slots and its time blocks count as busy too.
- Either
duration_minutesORservice_idis required. - With
service_id: duration/buffer come from the service, eligibility is enforced againsthub_service_team_members. - Max 14-day range. Returns up to 100 slots per response (has_more flag).
- Scope:
bookings.team.read.
curl "https://app.staffifyai.com/api/workspace/v1/team-members/42/availability?from=2026-10-15T00:00:00%2B02:00&to=2026-10-22T23:59:59%2B02:00&duration_minutes=60&timezone=Europe/Amsterdam" \ -H "Authorization: Bearer sfy_wsp_live_YOUR_KEY"
The team member object
| Field | Type | Description |
|---|---|---|
| id | integer | Team member id |
| user_id | integer | Linked Staffify user id when the member has a login (null for calendar-only slots) |
| name | string | Display name |
| string | Contact email | |
| phone | string | Contact phone |
| role | string | Free-form job role label (e.g. "Senior CV-monteur") |
| color | string | Hex color for calendar display (e.g. #F97316) |
| active | boolean | False = soft-deactivated (hidden from assignees) |
| sort_order | integer | Display order (lower = earlier) |
| max_concurrent_bookings | integer | How many simultaneous bookings this member can handle |
| notify_on_assignment | boolean | Fire a notification when a workorder/booking is assigned |
| mobile_view_enabled | boolean | Visible in the monteur-PWA mobile view |
| has_google_calendar | boolean | True when the member connected Google Calendar |
| google_calendar_email | string | The Google account email (OAuth tokens stay private) |
| google_calendar_sync_enabled | boolean | Live-sync between Staffify and Google Calendar is on |
| linked_calendar_group_id | integer | null | Read-only. Calendar group that shares one agenda with this member (set in the app under Calendar groups). Bookings of both never overlap. |
List active members + inactive
Default list only returns active=true. Pass ?include_inactive=true to see deactivated members as well (useful for payroll offboarding reports).
curl "https://app.staffifyai.com/api/workspace/v1/team-members?include_inactive=true" \ -H "Authorization: Bearer sfy_wsp_live_YOUR_KEY"
Create a team member
curl "https://app.staffifyai.com/api/workspace/v1/team-members" \
-X POST \
-H "Authorization: Bearer sfy_wsp_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Pieter van der Berg",
"email": "[email protected]",
"role": "CV-monteur",
"color": "#F97316",
"max_concurrent_bookings": 1
}'Deactivate (soft-delete)
DELETE sets active=false. The row stays in the database because work orders, appointments and certifications hold a foreign key to it. A hard-delete would orphan historical records. Idempotent — a second DELETE returns the already-inactive row.
Events
team_member.createdteam_member.updatedteam_member.deactivated