The staff & resources operations of the Rentals & Bookings GraphQL API: staff members and their skills, hours and time off; resources such as boats, vehicles and rooms; the jobs they are given (bookings that need staff, departures, maintenance tickets and your own custom jobs); assignments, who is free, conflicts and the scheduled hours for payroll. They use the same address, keys and rules as the rest of the API: see GraphQL API reference: Rentals & Bookings for how to send a request, and the API overview for keys, limits and errors. The same operations are in REST, with every field explained: REST API reference: Staff & resources.
Needs the Rentals & Bookings app. Every operation needs a secret key; mutations need Allow changes (write). The Free plan’s API can read only: a mutation is refused with plan_required.
- Ids are global:
gid://sirentals/Staff/7,gid://sirentals/Resource/3,gid://sirentals/StaffAssignment/120,gid://sirentals/ScheduleBlock/31(a time off or blocked time). Every id argument also takes the bare number, andlegacyResourceIdgives it. Locations, products and variants are Shopify’s (gid://shopify/Location/801,Product,ProductVariant), Shopify loginsgid://shopify/StaffMember/โฆ; each also takes the number. - A job is named by its
typeand itsjobId:booking(the booking id),departure(the departure id, see GraphQL API reference: Departures),maintenance_ticket(the ticket id) orcustom(a 26-character id). Only custom jobs are made, changed and cancelled here; the others follow their booking, departure or ticket. Job types explains them. - Times are the store’s wall clock,
Y-m-d H:i; a date alone is that day (as an end, to the end of the day). Ranges withoutfromandtocover today and the next 13 days, at most 92 days. - Jobs never carry a customer’s name or email: only the order name and ids.
- Mutations answer
userErrors { field message code data }when a change is refused:invalid_param,not_found,conflict(the conflicts indata.conflicts),already_assigned,job_cancelled,not_editable,not_live,duplicate,too_many. The REST errors table explains each.rentalStaffMember,rentalResourceandrentalStaffJobanswer null for an id that doesn’t exist; the other queries answererrors[].extensions.code: "not_found"for a staff member, resource or job that doesn’t exist.
curl -s "https://YOUR-API-ADDRESS/graphql/2026-10" -H "Authorization: Bearer sirb_your_secret_key" -H "Content-Type: application/json" \
-d '{"query": "{ rentalStaffMembers(first: 20, skill: \"guide\") { totalCount nodes { id name status skills { code level expiresOn } } } }"}'
Staff members and skills #
Staff members are the people jobs are given to; skills are what they can do (guide, driver, captain โฆ), each held at a level from 1 to 3, with a valid-until date for a skill that expires (a licence or certificate). Archiving a staff member cancels their assignments that haven’t ended.
| Operation | Arguments | What it does |
|---|---|---|
rentalStaffMembersquery ยท secret key returns RentalStaffMemberConnection! | first: Intafter: Stringlast: Intbefore: Stringstatus: RentalStaffStatusFilterquery: Stringskill: StringlocationId: ID | The store’s staff members, by name. status defaults to ACTIVE; query searches name, email and phone; skill is a skill code; locationId keeps the people who work there or anywhere. |
rentalStaffMemberquery ยท secret key returns RentalStaffMember | id: ID! | One staff member with their weekly hours and their time off from today on, or null. |
createRentalStaffMembermutation ยท secret key returns RentalStaffMemberPayload! | input: RentalStaffMemberInput! | Add a staff member. A name and an email or a phone number are needed; everything else is optional. |
updateRentalStaffMembermutation ยท secret key returns RentalStaffMemberPayload! | id: ID!input: RentalStaffMemberInput! | Change a staff member. Only the fields you send change; skills and hours replace their lists. Setting status to active brings an archived person back. |
archiveRentalStaffMembermutation ยท secret key returns RentalStaffMemberPayload! | id: ID! | Remove (archive) a staff member: their assignments that haven’t ended are cancelled, past ones stay. |
addRentalStaffTimeOffmutation ยท secret key returns RentalStaffMemberPayload! | staffId: ID!input: RentalScheduleBlockInput! | Add time off (kind: "time_off", the default) or an extra shift (kind: "extra"). Answers the staff member. |
removeRentalStaffTimeOffmutation ยท secret key returns RentalStaffMemberPayload! | staffId: ID!blockId: ID! | Delete a time off or extra shift. Answers the staff member. |
rentalStaffSkillsquery ยท secret key returns [RentalStaffSkill!]! | includeArchived: Boolean | The store’s skills with how many active staff hold each. A store starts with guide, driver, technician, captain and instructor. includeArchived: true adds the archived ones. |
saveRentalStaffSkillmutation ยท secret key returns RentalStaffSkillPayload! | code: Stringinput: RentalStaffSkillInput! | Add a skill (leave out code; the code is made from the label) or change one. duplicate when an active skill already has that name. |
archiveRentalStaffSkillmutation ยท secret key returns RentalStaffSkillPayload! | code: String! | Archive a skill: the staff who hold it keep it, but it is no longer offered. |
query Guides {
rentalStaffMembers(first: 20, skill: "guide", locationId: "gid://shopify/Location/801") {
totalCount
pageInfo { hasNextPage endCursor }
nodes {
id legacyResourceId name email phone status colour homeLocationId locationIds hoursMode dailyMaxMinutes
notify { email sms daySheet }
skills { code level expiresOn expired }
}
}
}
mutation AddStaffMember {
createRentalStaffMember(input: {
name: "Sam Patel", email: "[email protected]", homeLocationId: "gid://shopify/Location/801",
hours: [{weekday: 6, from: "08:00", to: "16:00"}, {weekday: 7, from: "08:00", to: "16:00"}],
skills: [{code: "guide"}, {code: "captain", expiresOn: "2027-06-30"}],
notify: {daySheet: true}
}) {
staffMember { id legacyResourceId name hoursMode hours { weekday from to } skills { code expiresOn } }
userErrors { field code message }
}
}
mutation Holiday {
addRentalStaffTimeOff(staffId: "gid://sirentals/Staff/7", input: {start: "2026-12-24", end: "2026-12-26", reason: "Holiday"}) {
staffMember { id timeOff { id kind start end reason } } # end "2026-12-27 00:00": to the end of the 26th
userErrors { field code message }
}
}
query Skills {
rentalStaffSkills { code label expires archived holders }
}
mutation AddSkill {
saveRentalStaffSkill(input: {label: "Lead guide"}) { # code "lead-guide"; duplicate when it already exists
skill { code label expires }
userErrors { field code message }
}
}
RentalStaffMemberInput โ A staff member: only name and an email or a phone are needed. On update only the fields sent change; skills and hours replace their lists.
| Field | Type | Notes |
|---|---|---|
name | String | Up to 120 characters; needed to create. |
email | String | An email or a phone number is needed to create. |
phone | String | Stored in international format (+16145550123). |
status | String | active or inactive. |
colour | String | Their colour on the schedule, #RRGGBB. |
homeLocationId | ID | A Shopify location (gid or number). |
locationIds | [ID!] | Other locations they also work at. |
hoursMode | String | opening (the store’s opening hours) or own (hours). Sending hours sets own. |
hours | [RentalStaffHoursInput!] | Their own weekly hours, at most 21 rows; replaces the list. |
dailyMaxMinutes | Int | Most minutes a day, 1-1440: a soft limit (a warning, never a refusal). |
notify | RentalStaffNotifyInput | |
notes | String | Up to 5000 characters. |
skills | [RentalStaffHeldSkillInput!] | Replaces the list. |
staffUserId | ID | The Shopify staff member who uses the app as them (gid://shopify/StaffMember/โฆ or the number). |
posStaffMemberId | ID | Their Shopify POS staff member (gid://shopify/StaffMember/โฆ or the number). |
RentalStaffHoursInput
| Field | Type | Notes |
|---|---|---|
weekday | Int! | 1 = Monday โฆ 7 = Sunday. |
from | String! | HH:MM |
to | String! | HH:MM; at or before from = past midnight. |
locationId | ID | A Shopify location (gid or number); null = any. |
RentalStaffNotifyInput
| Field | Type | Notes |
|---|---|---|
email | Boolean | Email them about new and changed jobs and jobs they are taken off (default true). |
sms | Boolean | Text them about new and changed jobs and jobs they are taken off (default false). |
daySheet | Boolean | An email at 7:00 with the day’s jobs, when email is on (default false). |
RentalStaffHeldSkillInput
| Field | Type | Notes |
|---|---|---|
code | String! | One of the store’s skill codes. |
level | Int | 1-3; leave it out for any level. |
expiresOn | String | Y-m-d; needed for a skill that expires. |
RentalScheduleBlockInput
| Field | Type | Notes |
|---|---|---|
start | String! | Y-m-d or Y-m-d H:i. |
end | String | Y-m-d or Y-m-d H:i. A date alone runs to the end of that day; leave it out for a whole day when start is a date alone. |
kind | String | time_off (default) or extra, for staff. A resource’s block is always blocked. |
reason | String | Up to 200 characters. |
RentalStaffSkillInput
| Field | Type | Notes |
|---|---|---|
label | String | Up to 80 characters. A new skill’s code is made from it (lower case, dashes). |
expires | Boolean | A licence or certificate: each holder needs a valid-until date. |
| Enum | Values |
|---|---|
RentalStaffStatusFilter | ACTIVE โ Active (the default).INACTIVE โ Set to inactive, not removed.ARCHIVED โ Removed (archived).ALL |
| Type | Fields |
|---|---|
RentalStaffMemberOne of the store’s staff members: a person who can be given jobs. | id: ID!, legacyResourceId: Int!, name: String!, email: String, phone: String, status: String!, colour: String!, homeLocationId: ID, locationIds: [ID!]!, hoursMode: String!, hours: [RentalStaffHours!], dailyMaxMinutes: Int, notify: RentalStaffNotify!, notes: String, skills: [RentalStaffHeldSkill!]!, staffUserId: ID, posStaffMemberId: ID, timeOff: [RentalScheduleBlock!], createdAt: String, updatedAt: String |
RentalStaffHoursA weekly working-hours row: weekday 1 = Monday โฆ 7 = Sunday; to at or before from = past midnight. | weekday: Int!, from: String!, to: String!, locationId: ID |
RentalStaffNotify | email: Boolean!, sms: Boolean!, daySheet: Boolean! |
RentalStaffHeldSkillA skill a staff member holds. | code: String!, level: Int, expiresOn: String, expired: Boolean! |
RentalScheduleBlockTime off, an extra shift, or a blocked time of a resource. | id: ID!, kind: String!, start: String!, end: String!, reason: String, source: String |
RentalStaffMemberPayload | staffMember: RentalStaffMember, userErrors: [RentalUserError!]! |
RentalStaffSkill | code: String!, label: String!, expires: Boolean!, archived: Boolean!, holders: Int |
RentalStaffSkillPayload | skill: RentalStaffSkill, userErrors: [RentalUserError!]! |
Resources #
Resources are what a job needs besides people: boats, vehicles, rooms, equipment, with the seats they have. A resource can stand for rental stock (stockLink): it can’t be assigned when those units aren’t free. A blocked time (a repair, a private use) keeps it off jobs.
| Operation | Arguments | What it does |
|---|---|---|
rentalResourcesquery ยท secret key returns RentalResourceConnection! | first: Intafter: Stringlast: Intbefore: Stringstatus: RentalStaffStatusFilterquery: Stringtype: StringlocationId: ID | The store’s resources (boats, vehicles, rooms, equipment), by name. status defaults to ACTIVE; type is a resource type; locationId keeps the ones at that location or at none. |
rentalResourcequery ยท secret key returns RentalResource | id: ID! | One resource with its weekly hours and its blocked times from today on, or null. |
createRentalResourcemutation ยท secret key returns RentalResourcePayload! | input: RentalResourceInput! | Add a resource. name and type are needed. |
updateRentalResourcemutation ยท secret key returns RentalResourcePayload! | id: ID!input: RentalResourceInput! | Change a resource. Only the fields you send change; hours replaces the list. |
archiveRentalResourcemutation ยท secret key returns RentalResourcePayload! | id: ID! | Remove (archive) a resource: its assignments that haven’t ended are cancelled, past ones stay. |
addRentalResourceBlockmutation ยท secret key returns RentalResourcePayload! | resourceId: ID!input: RentalScheduleBlockInput! | Block a resource for a time (a repair, a private use). Answers the resource. |
removeRentalResourceBlockmutation ยท secret key returns RentalResourcePayload! | resourceId: ID!blockId: ID! | Delete a blocked time. Answers the resource. |
query Boats {
rentalResources(first: 20, type: "boat") {
totalCount
nodes { id legacyResourceId name type seats locationId status colour stockLink { productId variantId units } }
}
}
mutation AddBoat {
createRentalResource(input: {
name: "Pontoon 3", type: "boat", seats: 12, locationId: "801",
stockLink: {productId: "gid://shopify/Product/88001", units: 1}
}) {
resource { id legacyResourceId name seats stockLink { productId units } }
userErrors { field code message }
}
}
mutation EngineService {
addRentalResourceBlock(resourceId: "gid://sirentals/Resource/3", input: {start: "2026-12-10", reason: "Engine service"}) {
resource { id blocks { id kind start end reason } }
userErrors { field code message }
}
}
RentalResourceInput
| Field | Type | Notes |
|---|---|---|
name | String | Up to 120 characters; needed to create. |
type | String | boat, vehicle, room, equipment or your own word (stored lower case with dashes). |
seats | Int | 0-10000. |
locationId | ID | One of your locations (gid or number); null = any. |
status | String | active or inactive. |
colour | String | #RRGGBB |
notes | String | Up to 5000 characters. |
stockLink | RentalResourceStockLinkInput | Tie the resource to rental stock: it can’t be assigned when those units aren’t free (stock_unavailable). null removes the link. |
hours | [RentalStaffHoursInput!] | Weekly hours, at most 21 rows; replaces the list. |
RentalResourceStockLinkInput
| Field | Type | Notes |
|---|---|---|
productId | ID! | A rental product (gid or number). |
variantId | ID | One rent variant of it (optional). |
units | Int | Units of that product the resource stands for, 1-1000 (default 1). |
| Type | Fields |
|---|---|
RentalResourceA boat, van, room โฆ: something a job needs, with its seats. | id: ID!, legacyResourceId: Int!, name: String!, type: String!, seats: Int!, locationId: ID, status: String!, colour: String!, stockLink: RentalResourceStockLink, notes: String, hours: [RentalStaffHours!], blocks: [RentalScheduleBlock!], createdAt: String, updatedAt: String |
RentalResourceStockLink | productId: ID!, variantId: ID, units: Int! |
RentalResourcePayload | resource: RentalResource, userErrors: [RentalUserError!]! |
Jobs #
A job’s needs say what it asks for, one row per requirement: count is how many this job needs (a ratio row works it out from the guests or units), assigned the staff or resource ids that fill it, missing how many are still needed, reason unfilled or too_small when something is missing. before and after are the minutes around the job that its assignments also take (set-up, travel, clean-up).
| Operation | Arguments | What it does |
|---|---|---|
rentalStaffJobsquery ยท secret key returns RentalStaffJobConnection! | first: Intafter: Stringlast: Intbefore: Stringfrom: Stringto: Stringtype: Stringstatus: RentalStaffJobFilterlocationId: ID | Jobs between two days (default: today and the next 13 days, at most 92), soonest first. status defaults to OPEN; type is booking, departure, maintenance_ticket or custom. |
rentalStaffJobquery ยท secret key returns RentalStaffJob | type: String!id: String! | One job with its needs (how many each asks for, who fills it, what is missing) and its assignments, or null. |
createRentalStaffJobmutation ยท secret key returns RentalStaffJobPayload! | input: RentalStaffJobInput! | Make a custom job: something staff do that isn’t a booking, such as cleaning the boats on Saturday morning. title, start and end are needed. |
updateRentalStaffJobmutation ยท secret key returns RentalStaffJobPayload! | id: String!input: RentalStaffJobInput! | Change a custom job (id is its job id). Only the fields you send change; its assignments move with it. |
cancelRentalStaffJobmutation ยท secret key returns RentalStaffJobPayload! | type: String!id: String!reason: String | Cancel a custom job and its assignments. Other jobs follow their booking, departure or ticket: not_editable. |
query NextWeek {
rentalStaffJobs(first: 20, from: "2026-12-05", to: "2026-12-11", type: "booking") {
totalCount
pageInfo { hasNextPage endCursor }
nodes {
type jobId ref title orderName start end locationId status guests units before after autoAssign missing
needs { kind skill level type count perGuests perUnits seats seatsTotal mode role assigned missing reason }
}
}
}
query OneJob {
rentalStaffJob(type: "booking", id: "5471") {
ref title start end missing
needs { role count assigned missing reason }
assignments { id subjectType subjectId role start end status source warnings override }
}
}
mutation CleanTheBoats {
createRentalStaffJob(input: {
title: "Clean the boats", start: "2026-12-05 07:00", end: "2026-12-05 08:30", locationId: "801",
needs: [{kind: "staff", count: 2}], after: "15m"
}) {
job { type jobId ref start end after missing needs { role count missing } }
userErrors { field code message }
}
}
RentalStaffJobInput โ A custom job (boat cleaning Saturday 8-10, one technician). On update only the fields sent change.
| Field | Type | Notes |
|---|---|---|
title | String | Up to 200 characters; needed to create. |
start | String | Y-m-d H:i (a date alone = that day). |
end | String | Y-m-d H:i (a date alone = the end of that day). |
locationId | ID | One of your locations (gid or number). |
needs | [RentalStaffNeedInput!] | At most 10 rows; replaces the list. |
notes | String | Up to 5000 characters. |
colour | String | #RRGGBB |
before | String | Minutes before the job that its assignments also take (set-up, travel): 30, 30m, 1h or 1h30m; 0-1440. |
after | String | Minutes after the job that its assignments also take (clean-up); like before. |
RentalStaffNeedInput
| Field | Type | Notes |
|---|---|---|
kind | String! | staff or resource. |
skill | String | A skill code (staff). |
level | Int | 1-3 (staff). |
type | String | A resource type (resource). |
count | Int | How many, 1-100 (default 1). |
perGuests | Int | One for every N guests, instead of count. |
perUnits | Int | One for every N units, instead of count. |
seats | String | Seats the resource needs: party or a number. |
seatsTotal | Boolean | true: the resources of this need seat the party together. |
role | String | A name for the slot (default: the skill, type or kind). |
| Enum | Values |
|---|---|
RentalStaffJobFilter | OPENCANCELLEDALL |
| Type | Fields |
|---|---|
RentalStaffJobA job staff and resources can be given: a booking whose product needs staff, a departure, a maintenance ticket or a custom job. | type: String!, jobId: String!, ref: String!, title: String, url: String, orderName: String, colour: String, notes: String, start: String!, end: String!, locationId: ID, status: String!, cancelReason: String, guests: Int, units: Int, before: Int!, after: Int!, autoAssign: String, needs: [RentalStaffNeed!]!, missing: Int, assignments: [RentalStaffAssignment!], updatedAt: String |
RentalStaffNeedWhat a job needs: one requirement row, with how many the job asks for and what fills it. | kind: String!, skill: String, level: Int, type: String, count: Int!, perGuests: Int, perUnits: Int, seats: String, seatsTotal: Boolean, mode: String!, role: String!, assigned: [Int!], missing: Int, reason: String |
RentalStaffAssignmentA staff member or resource given a job for a window, in a role. | id: ID!, legacyResourceId: Int!, jobType: String!, jobId: String!, subjectType: String!, subjectId: ID!, role: String, start: String!, end: String!, locationId: ID, status: String!, source: String!, warnings: [String!]!, override: JSON, notes: String, cancelReason: String, job: RentalStaffJob, createdAt: String, updatedAt: String |
RentalStaffJobPayload | job: RentalStaffJob, userErrors: [RentalUserError!]! |
Assignments and who is free #
An assignment gives a staff member or resource a job, for the job’s window with its before and after, or a window of its own. Each is checked for conflicts: a hard one (overlap, time_off, blocked, inactive, stock_unavailable) refuses it unless you give forceReason; soft ones (outside_hours, missing_skill, skill_expired, wrong_location, daily_max, too_small) are kept in its warnings. Candidates and conflicts lists every code. A candidate is qualified when it has no conflict at all; only qualified ones are suggested and assigned automatically.
| Operation | Arguments | What it does |
|---|---|---|
rentalFreeStaffquery ยท secret key returns [RentalStaffCandidate!]! | start: Stringend: Stringskill: Stringlevel: IntlocationId: IDjobType: StringjobId: StringincludeBusy: Booleanlimit: Int | Staff free for a window, best first, or for a job (jobType + jobId: its window, and its own assignments don’t count as busy). includeBusy: true also lists the busy ones with their conflicts. limit 1-100, default 20. |
rentalFreeResourcesquery ยท secret key returns [RentalStaffCandidate!]! | start: Stringend: Stringtype: StringminSeats: IntlocationId: IDjobType: StringjobId: StringincludeBusy: Booleanlimit: Int | Resources free for a window or a job, with at least minSeats seats, best first. Same options as rentalFreeStaff. |
rentalStaffAssignmentsquery ยท secret key returns RentalStaffAssignmentConnection! | first: Intafter: Stringlast: Intbefore: Stringfrom: Stringto: StringstaffId: IDresourceId: IDjobType: StringjobId: Stringstatus: RentalStaffAssignmentFilter | Assignments between two days (default: today and the next 13 days), or every assignment of one job (jobType + jobId). status defaults to LIVE (planned, confirmed and done). |
assignRentalStaffmutation ยท secret key returns RentalStaffAssignmentPayload! | input: RentalStaffAssignInput! | Give a staff member or resource a job. A hard conflict refuses it with conflict and the conflicts in data.conflicts, unless you give forceReason; soft conflicts are kept as warnings. |
unassignRentalStaffmutation ยท secret key returns RentalStaffAssignmentPayload! | assignmentId: ID!reason: String | Cancel an assignment. One already cancelled or declined comes back unchanged. |
reassignRentalStaffmutation ยท secret key returns RentalStaffAssignmentPayload! | assignmentId: ID!subjectId: ID!subjectType: StringforceReason: String | Give an assignment’s slot (its role and window) to someone else in one step. The old assignment is cancelled; the new one is checked like assignRentalStaff. not_live when the assignment is no longer active. |
autoAssignRentalJobmutation ยท secret key returns RentalStaffAutoAssignPayload! | jobType: String!jobId: String!commit: Boolean | Fill a job’s missing needs. Without commit it only suggests (nothing is written); commit: true assigns the suggestion, skipping anyone who conflicts. |
query WhoIsFree {
rentalFreeStaff(start: "2026-12-05 09:00", end: "2026-12-05 12:00", skill: "guide", locationId: "801", includeBusy: true) {
id legacyResourceId name rank qualified hard nextFreeAt
conflicts { code hard message otherJob start end }
}
}
mutation AssignAlex {
assignRentalStaff(input: {jobType: "booking", jobId: "5471", subjectId: "gid://sirentals/Staff/7"}) {
assignment { id role start end status warnings }
userErrors { field code message data }
}
}
When Alex is already on another job then, nothing is written and the payload answers:
{"data": {"assignRentalStaff": {"assignment": null, "userErrors": [{
"field": ["input", "subjectId"], "code": "conflict",
"message": "Can't assign: Already on another job then (booking:5480, 2026-12-05 08:00 โ 2026-12-05 11:00). Assign anyway with a reason.",
"data": {"conflicts": [{"code": "overlap", "hard": true,
"message": "Already on another job then (booking:5480, 2026-12-05 08:00 โ 2026-12-05 11:00)",
"subjectType": "staff", "subjectId": 7, "job": "booking:5471", "otherJob": "booking:5480",
"start": "2026-12-05 08:00", "end": "2026-12-05 11:00"}]}}]}}}
mutation AssignAnyway {
assignRentalStaff(input: {
jobType: "booking", jobId: "5471", subjectId: "gid://sirentals/Staff/7", forceReason: "Swaps with Sam at 09:00"
}) {
assignment { id status warnings override } # override: {reason, by, at, codes: ["overlap"]}
userErrors { field code message data }
}
}
mutation FillTheJob {
autoAssignRentalJob(jobType: "booking", jobId: "5471") { # commit: true assigns the matched ids
suggested { index kind role count missing matched candidates { id name rank } }
unmet { index role missing reason }
userErrors { code message }
}
}
mutation Swap {
reassignRentalStaff(assignmentId: "gid://sirentals/StaffAssignment/120", subjectId: "gid://sirentals/Staff/9") {
assignment { id subjectId role start end status }
userErrors { field code message data }
}
}
RentalStaffAssignInput
| Field | Type | Notes |
|---|---|---|
jobType | String! | booking, departure, maintenance_ticket or custom. |
jobId | String! | The job’s id (jobId on RentalStaffJob). |
subjectId | ID! | gid://sirentals/Staff/โฆ, gid://sirentals/Resource/โฆ, or a number with subjectType. |
subjectType | String | staff (default) or resource. |
role | String | The slot it fills, up to 60 characters (default: the role of the need it fills). |
need | Int | The need it fills (its index). |
start | String | A window of its own (default: the job’s with its before and after). |
end | String | With start: a window of its own. |
forceReason | String | Assign through a hard conflict (overlap, time off โฆ): why. |
status | String | planned or confirmed. Default: planned when Settings โบ Staff โบ “Staff confirm their jobs” is on, confirmed otherwise (resources: confirmed). |
notes | String | Up to 2000 characters. |
| Enum | Values |
|---|---|
RentalStaffAssignmentFilter | LIVE โ Planned, confirmed or done (the ones that take the time).PLANNEDCONFIRMEDDECLINEDDONECANCELLEDALL |
| Type | Fields |
|---|---|
RentalStaffCandidateA staff member or resource for a window, best first: already working another part of the same job that day, then at their home location, then the fewest minutes booked that day, then the fewest other skills (resources: the smallest that seats enough). | id: ID!, legacyResourceId: Int!, subjectType: String!, name: String, colour: String, rank: Int!, qualified: Boolean!, hard: Boolean!, conflicts: [RentalStaffConflict!]!, nextFreeAt: String |
RentalStaffConflictWhy a staff member or resource can’t (or shouldn’t) take a job. Hard conflicts refuse unless forced with a reason. | code: String!, hard: Boolean!, message: String!, subjectType: String, subjectId: ID, assignmentId: ID, job: String, otherJob: String, start: String, end: String |
RentalStaffAssignmentPayload | assignment: RentalStaffAssignment, userErrors: [RentalUserError!]! |
RentalStaffAutoAssignPayload | assigned: [RentalStaffAssignment!], suggested: [RentalStaffSuggestion!], unmet: [RentalStaffUnmet!], job: RentalStaffJob, userErrors: [RentalUserError!]! |
RentalStaffSuggestion | index: Int!, kind: String!, role: String!, count: Int!, missing: Int!, matched: [Int!]!, candidates: [RentalStaffCandidate!]! |
RentalStaffUnmet | index: Int!, role: String!, missing: Int!, reason: String! |
Schedules, conflicts and hours #
| Operation | Arguments | What it does |
|---|---|---|
rentalStaffSchedulequery ยท secret key returns RentalStaffSchedule! | subjectId: ID!from: Stringto: String | A staff member’s or resource’s assignments (each with its job) and blocked times between two days (default: today and the next 13 days). subjectId is a gid://sirentals/Staff/โฆ or gid://sirentals/Resource/โฆ; a bare number means a staff member. |
rentalStaffUnassignedquery ยท secret key returns [RentalStaffJob!]! | from: Stringto: StringlocationId: ID | Open jobs still missing staff or resources between two days (default: today and the next 13 days), soonest first. |
rentalStaffConflictsquery ยท secret key returns [RentalStaffConflict!]! | from: Stringto: StringlocationId: ID | Every conflict of the assignments between two days (default: today and the next 13 days). |
rentalStaffHoursquery ยท secret key returns RentalStaffHoursReport! | from: Stringto: StringlocationId: IDstaffId: ID | Scheduled hours per staff member per day, for payroll: their planned, confirmed and done assignments, overlapping ones counted once, a night job split at midnight. Days are Y-m-d, to included; default 7 days from today, at most 92. |
query AlexSchedule {
rentalStaffSchedule(subjectId: "gid://sirentals/Staff/7", from: "2026-12-05", to: "2026-12-06") {
from to
assignments { id role start end status job { ref title orderName start end } }
blocks { id kind start end reason }
}
}
query Gaps {
rentalStaffUnassigned(from: "2026-12-05", to: "2026-12-11") {
type jobId ref title start end missing
needs { role count missing reason }
}
rentalStaffConflicts(from: "2026-12-05", to: "2026-12-11") {
code hard message subjectType subjectId assignmentId job otherJob start end
}
}
query PayrollWeek {
rentalStaffHours(from: "2026-12-01", to: "2026-12-07") {
from to
rows { staffId staffLegacyId name date minutes hours jobs checkedIn }
totals { staffId name minutes hours jobs checkedIn days }
}
}
| Type | Fields |
|---|---|
RentalStaffScheduleA staff member’s or resource’s jobs and blocks between two days. | from: String!, to: String!, assignments: [RentalStaffAssignment!]!, blocks: [RentalScheduleBlock!]! |
RentalStaffHoursReportScheduled hours per staff member per day (rentalStaffHours). | from: String!, to: String!, rows: [RentalStaffHoursDay!]!, totals: [RentalStaffHoursTotal!]! |
RentalStaffHoursDay | staffId: ID!, staffLegacyId: Int!, name: String!, email: String, date: String!, minutes: Int!, hours: Float!, jobs: Int!, checkedIn: Int! |
RentalStaffHoursTotal | staffId: ID!, staffLegacyId: Int!, name: String!, minutes: Int!, hours: Float!, jobs: Int!, checkedIn: Int!, days: Int! |
