Read the housekeeping pacing report
const url = 'https://api.aerandil.com/v1/housekeeping/pacing?property_id=2489E9AD-2EE2-8E00-8EC9-32D5F69181C0';const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request GET \ --url 'https://api.aerandil.com/v1/housekeeping/pacing?property_id=2489E9AD-2EE2-8E00-8EC9-32D5F69181C0' \ --header 'Authorization: Bearer <token>'The housekeeping pacing report for one property and one business date — hubOS’s productivity report, counted in OPERA’s housekeeping credits. Per attendant: the credit target on their shift that day and the share of it completed (target_percent); credits assigned, completed, in progress and pending (pending or blocked) with their share of the assigned; rooms assigned, cleaned and on do-not-disturb; cleaning_seconds (completed_at − started_at of each complete task), transition_seconds (the gaps between one task’s completion and the attendant’s next start) and deviation_seconds (cleaning time less standard minutes, over the tasks that carry a standard — standard_seconds). The summary adds credits on tasks nobody holds (credits_unassigned), a count of unpriced tasks, and rooms on the board / assigned / cleaned / pending / inspected / on do-not-disturb. Skipped tasks count nowhere.
Credits and standard minutes are what each task was minted with from the property’s housekeeping credit rules (set_housekeeping_credit_rule); targets are set at clock_in or with set_shift_credit_target. A reader not cleared for staff data sees no targets. Computed on read from the tasks and shifts — the same value hospitality.function.housekeeping_pacing returns.
Live data: always Cache-Control: no-store.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Query Parameters
Section titled “Query Parameters”The property whose floor to read.
The business date, YYYY-MM-DD; omitted, the property’s local calendar day — the day its housekeeping sheet is dated by.
Responses
Section titled “Responses”The report. A day with no tasks is an empty report, not a 404.
object
object
object
Examplegenerated
{ "attendants": [ { "cleaning_seconds": 1, "completed_percent": "example", "contracted_weekly_hours": "example", "credit_target": "example", "credits_assigned": "example", "credits_completed": "example", "credits_in_progress": "example", "credits_pending": "example", "deviation_seconds": 1, "in_progress_percent": "example", "inspection_rating_average": "example", "inspections": 1, "pending_percent": "example", "percentage_worked": "example", "rooms_assigned": 1, "rooms_cleaned": 1, "rooms_dnd": 1, "self_rating_average": "example", "self_ratings": 1, "staff_member_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "standard_seconds": 1, "target_percent": "example", "time_worked_seconds": 1, "transition_seconds": 1 } ], "business_date": "2026-04-15", "property_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "summary": { "cleaning_seconds": 1, "completed_percent": "example", "credits_assigned": "example", "credits_completed": "example", "credits_in_progress": "example", "credits_pending": "example", "credits_unassigned": "example", "deviation_seconds": 1, "in_progress_percent": "example", "pending_percent": "example", "rooms": 1, "rooms_assigned": 1, "rooms_cleaned": 1, "rooms_dnd": 1, "rooms_inspected": 1, "rooms_pending": 1, "standard_seconds": 1, "tasks_unpriced": 1, "transition_seconds": 1 }}Headers
Section titled “Headers”Always no-store — live data.
Token does not hold the function’s grant — functions:hospitality.function.housekeeping_pacing:invoke (a housekeeping supervisor’s handset carries it; an attendant’s and a runner’s do not) or the catch-all functions:invoke — or the session (a desk’s or a handset’s) is bound to another property.
Structured error wrapper. Every non-2xx response from any Aerandil endpoint serialises to this shape; the HTTP status carries the failure class (4xx/5xx), the body adds a stable code for programmatic dispatch plus a human-readable message.
object
object
Stable, programmatic error code (e.g. unauthorized, forbidden, not_found, invalid_body, invalid_url, precondition_failed, no_secondary_key). Clients dispatch on code, not on the message (which may be localised or contextualised in future versions).
Request-id correlation handle echoed on the request-id response header — support teams correlate without scraping logs.
Human-readable explanation of the failure.
Per-error structured detail. The shape varies by code (e.g. forbidden_action carries {"action": "..."}; precondition_failed carries {"current_version": N}).
Examplegenerated
{ "error": { "code": "example", "instance_id": "example", "message": "example", "parameters": "example" }}No such property.
Structured error wrapper. Every non-2xx response from any Aerandil endpoint serialises to this shape; the HTTP status carries the failure class (4xx/5xx), the body adds a stable code for programmatic dispatch plus a human-readable message.
object
object
Stable, programmatic error code (e.g. unauthorized, forbidden, not_found, invalid_body, invalid_url, precondition_failed, no_secondary_key). Clients dispatch on code, not on the message (which may be localised or contextualised in future versions).
Request-id correlation handle echoed on the request-id response header — support teams correlate without scraping logs.
Human-readable explanation of the failure.
Per-error structured detail. The shape varies by code (e.g. forbidden_action carries {"action": "..."}; precondition_failed carries {"current_version": N}).
Examplegenerated
{ "error": { "code": "example", "instance_id": "example", "message": "example", "parameters": "example" }}Malformed business_date.
Structured error wrapper. Every non-2xx response from any Aerandil endpoint serialises to this shape; the HTTP status carries the failure class (4xx/5xx), the body adds a stable code for programmatic dispatch plus a human-readable message.
object
object
Stable, programmatic error code (e.g. unauthorized, forbidden, not_found, invalid_body, invalid_url, precondition_failed, no_secondary_key). Clients dispatch on code, not on the message (which may be localised or contextualised in future versions).
Request-id correlation handle echoed on the request-id response header — support teams correlate without scraping logs.
Human-readable explanation of the failure.
Per-error structured detail. The shape varies by code (e.g. forbidden_action carries {"action": "..."}; precondition_failed carries {"current_version": N}).
Examplegenerated
{ "error": { "code": "example", "instance_id": "example", "message": "example", "parameters": "example" }}