Fire quote (FIXED action — business)
Sends the quote: sets quoted_at + duration cols, advances pending_action to confirm_booking. Status stays `booking`. job_duration_minutes may be omitted when the job's job type has a default_duration_minutes: the type's default duration and buffers are used (a buffer you send still wins). This is how an automation or voice agent schedules work it cannot size. Before writing, checks that the customer will see at least one slot: the same engine as the customer slot picker runs over the windows the customer asked for with THIS quote's duration (working hours, service areas, time-off, existing bookings, crew coverage). If no slot exists the quote is refused with 409 JOB_REQUEST_QUOTE_NOT_SCHEDULABLE; data.reason says why (outside_working_hours, requested_windows_passed, outside_service_area, off_shift, on_time_off, missing_required_skills, no_technician_available, ...) and data.blocked_by counts the roster per blocker. Send force=true to schedule it anyway after agreeing a time with the customer.
Arguments
curl -X POST "https://api.crisphive.com/v1/job-requests/9b2f6c3e-1a4d-4f0a-8f2e-7c5d1b3a9e01/quote" \ -H "Authorization: Bearer chsk_test_4eC8xQ9mZ2pL7Ka0rT" \ -H "Content-Type: application/json" \ -d '{ "crew": [ { "is_lead": true, "skill_ids": [ "9b2f6c3e-1a4d-4f0a-8f2e-7c5d1b3a9e01" ], "wrench_percent": 50 } ], "demobilization_minutes": 15, "force": false, "job_duration_minutes": 120, "mobilization_minutes": 15, "status_version": 1 }'