HyphaBase

Staff

Marcus works Tuesday to Saturday, takes lunch at one, and is off the last week of August. All of which booking needs to know.

Marcus cleans for Brightside. He works Tuesday to Saturday, 8am to 4pm, takes lunch at one, can manage four jobs a day, and he's off the last week of August.

Every one of those facts changes what you can safely book. Availability lives here, and the Bookings module checks against it the day it goes live — model the team properly now and scheduling inherits it for free.

What you can build with Staff · 1:21
Read it instead

Staff is the four things that decide whether someone can take a job: working hours, breaks, capacity, and time off. REST, a secret key, a location header.

Working hours carry a day_of_week, a start_time and an end_time, with effective_from and effective_until so a rota change has a date. Breaks sit inside them, capacity caps the jobs per day, and time off runs pending, approved or rejected.

Ask for everyone at once and a rota screen is one request. Subscribe to employees.time_off.requested to push approvals into whatever your managers already use, and employees.employee.deactivated to close accounts elsewhere the moment somebody leaves.

employees.view reads staff, hours, breaks, capacity and time off. Approving somebody's holiday needs employees.update, so a scheduling integration can read availability without granting it.

Staff: hours, breaks, capacity and time off on one record, which is everything booking needs to know. The guide is below.

Before you start

  • The module switched on for the site. If it isn't, everything below returns 403 regardless of your key — check the site's modules on the Locations page first.
  • A credential with the right scopes — employees.view to read, employees.create to add people.
  • The site's id, for X-Location-Id on every request.

These are people inside a site, not your dashboard staff

A cleaner here is a record in Portland's database. The people who run your business through the dashboard — opening sites, issuing keys — are a different thing entirely, set up in the dashboard: see Staff and roles.

The four things that decide availability

Getting these straight saves a lot of confusion later, because they stack:

What it saysExample
Working hoursThe pattern of a normal weekTue–Sat, 08:00–16:00
Break periodsTime out within a working dayLunch, 13:00–13:30
Capacity settingsHow much someone can take onFour jobs a day
Time offSpecific dates they're away24–31 August

Working hours say when someone could work. Breaks and time off carve out of that. Capacity limits how much fits in what's left.

The endpoints

Working hours

One record per day of the week. day_of_week is an integer, and is_available: false is how you say "not this day" rather than omitting the record.

Prop

Type

Check which integer means which day

Whether the week starts at 0 or 1, and whether that's Sunday or Monday, is the sort of thing that silently books someone on their day off. Create one record you can verify against a real calendar before generating a whole team's hours from a loop.

curl -X POST "https://api.hyphabase.com/api/modules/employees/users/$MARCUS_ID/working-hours" \
  -u sk_live_xxx: -H "X-Location-Id: $HYPHABASE_LOCATION_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "day_of_week": 2,
    "start_time": "08:00",
    "end_time": "16:00",
    "is_available": true
  }'

effective_from and effective_until are the useful part. They let you change someone's hours from a future date without destroying the record of what they used to be — so a historic booking still makes sense against the pattern that applied at the time. Editing in place loses that.

Breaks

Same idea, narrower. day_of_week, a start and end, and an optional label so a rota screen can say "Lunch" rather than a bare time range.

curl -X POST "https://api.hyphabase.com/api/modules/employees/users/$MARCUS_ID/break-periods" \
  -u sk_live_xxx: -H "X-Location-Id: $HYPHABASE_LOCATION_ID" \
  -H "Content-Type: application/json" \
  -d '{"day_of_week": 2, "break_start_time": "13:00", "break_end_time": "13:30", "label": "Lunch"}'

Capacity

max_daily_capacity_units is how much someone can take on in a day. What a "unit" means is yours to define — jobs, hours, rooms — but define it once and use it consistently, because nothing enforces a meaning.

Sarah counts jobs, so Marcus is 4. A four-hour deep clean and a one-hour top-up both count as one, which suits her because travel dominates her day anyway. If that stopped being true she'd switch to hours and update everyone.

Like working hours, capacity settings carry effective_from/effective_until, so a seasonal change is a new record rather than an edit.

Time off

Prop

Type

Requests arrive pending and become real on approve:

curl -X POST "https://api.hyphabase.com/api/modules/employees/users/$MARCUS_ID/time-off/$REQUEST_ID/approve" \
  -u sk_live_xxx: -H "X-Location-Id: $HYPHABASE_LOCATION_ID"

Omit the times for a full day, or include them for an afternoon at the dentist.

Approving time off does not cancel existing bookings

If Marcus is already booked in the week he's now off, those visits stand. Check for conflicts when you approve and reassign or reschedule them — nothing does it for you, and a crew not turning up is worse than an awkward phone call.

Everyone at once

GET /api/modules/employees/staff-availability is the whole team's availability in one request. That's what you build a rota screen from, rather than fetching four sub-resources per person.

One person's actual day — hours, breaks, time off and what's booked against them — arrives with the Bookings module, which reads the availability you set up here.

Adding people

Two ways, and they're for different situations.

Create the record directly with POST /api/modules/employees/users when you're importing or the person doesn't need to sign in.

Send an invitation with POST /api/modules/employees/invitations when they do — they set their own password rather than you inventing one and sending it over WhatsApp. Invitations can be resent and cancelled.

Prefer deactivate over delete when someone leaves. Their history stays intact, and reactivate handles the seasonal cleaner who comes back every summer.

What you get told about

EventWhen
employees.employee.createdSomeone is added
employees.employee.deactivatedSomeone is switched off
employees.time_off.requestedTime off is requested

time_off.requested is the one to wire up — it's how a manager finds out there's something to approve without checking a screen.

What to grant

ScopeLets you
employees.viewRead staff, hours, breaks, capacity and time off
employees.createAdd people, invite them, request time off
employees.updateChange records, approve and reject time off
employees.deleteDelete records

employees.view is safe for a publishable key — enough for a booking page to know who's free, without exposing anything a customer shouldn't see.

Be careful with employees.update: it approves time off, which changes who can be booked.

What goes wrong

Recipes

Set up a new starter. Create or invite the user, add a working-hours record per working day, add breaks, set capacity, then confirm with staff-availability that they show as available when you expect.

Time off that actually works. On employees.time_off.requested, notify a manager. On approval, list visits in that range and either reassign or reschedule each one — then tell the customer.

A seasonal hours change. Don't edit. Add new working-hours records with effective_from set to the changeover date, so past bookings still make sense.

Next

On this page