en
Bookings›Rank technicians for a P0 emergency insert

Rank technicians for a P0 emergency insert

Returns the technicians who could take the emergency job at the requested start, ranked FASTEST-ARRIVAL first (arrival beats route efficiency for a P0). The response also carries a historical `crew_recommendation` (median crew size on comparable completed jobs + mandatory disclaimer — AC-2). Booked technicians are still candidates — each entry carries the displacement preview (which lower-priority jobs would be pushed, per day) that committing to them would cause; total_moves=0 means a free slot. P0 jobs are never displaced; P1 only by a P0. ETA is estimated from the technician's start location (no live GPS). `after_hours_override=true` — the coordinator has phoned the technician — drops the non-working-day rejection AND each candidate's working-hours/time-off feasibility check; an affected candidate carries a per-technician TIME_OFF_OVERLAP warning instead. This is THE phone list for an after-hours insert: it ranks even on a day with no working hours once the flag is set. Feed the chosen technician_id into emergency/preview + emergency/commit. 409 NEXT STEPS: EMERGENCY_RESCHEDULE_NOT_ELIGIBLE — the job cannot be emergency-inserted; `data.failed_precondition` names which (not_quoted | archived | completed | not_p0 | smart_assign_unavailable): fix the job state or use a normal confirm. EMERGENCY_RESCHEDULE_CREW_UNSUPPORTED — crew jobs cannot use the emergency flow (v1, `data.crew_size` = lead + buddies): staff via confirm/reassign instead. EMERGENCY_RESCHEDULE_MULTIDAY_UNSUPPORTED — either a confirmed multi-day job (`data.session_count`/`data.session_dates`; use the normal reassign flow) or a single visit longer than the structural span bound, in which case `data.reason=visit_too_long` + `data.blockers[0]` (visit_minutes/max_minutes) name it — no remedy but a shorter visit. EMERGENCY_RESCHEDULE_NO_WORKING_DAY — the chosen date has no working hours (`data.business_timezone`/`data.requested_weekday`): pick a working day, or set after_hours_override=true (the coordinator has phoned someone) to rank candidates anyway. EMERGENCY_RESCHEDULE_IN_PAST — start time already passed: pick a future time; `data` carries the timezone the naive start_at was read in (`business_timezone`) plus the instant it resolved to, so a start that looks future on the caller's own clock can be diagnosed without guessing.

Arguments

after_hours_overridebooleanbodyoptional
Place this P0 outside working hours / approved time-off — you have phoned the technician and they agreed. Drops the non-working-day rejection; the response then carries an AFTER_HOURS warning. Double-booking, service area, required skills and the lead-tier rule still reject.
emergency_job_idstringbodyrequired
ID of the P0 job to place.
limitintegerbodyoptional
Max candidates to return (default 5, max 10).
modeenumbodyrequired
Cascade mode each candidate's displacement preview assumes: overtime = displaced jobs stay same-day; next_day = overflow rolls to the next working day.
start_atstringbodyrequired
Desired start — business-local wall clock. Seconds may be omitted and a space may replace the T; an offset is accepted only when it agrees with the business timezone (a disagreeing one is refused with JOB_REQUEST_INVALID_INPUT rather than guessed). Must be in the future.
POST/v1/job-requests/emergency/candidates
curl -X POST "https://api.crisphive.com/v1/job-requests/emergency/candidates" \
  -H "Authorization: Bearer chsk_test_4eC8xQ9mZ2pL7Ka0rT" \
  -H "Content-Type: application/json" \
  -d '{
  "after_hours_override": true,
  "emergency_job_id": "9b2f6c3e-1a4d-4f0a-8f2e-7c5d1b3a9e01",
  "limit": 1,
  "mode": "overtime",
  "start_at": "2030-06-14T09:00:00"
}'
Request body
{
"after_hours_override": ,
"emergency_job_id": ,
"limit": ,
"mode": ,
"start_at":
}

Responses