Demand Management
Demand is the bridge between a case and its allocations. Operators (or the policy's auto-approver) translate a passenger manifest into a rooms requested number and approve that request before any hotel search runs.
Why a separate step
Separating demand from the case gives ops a clean checkpoint:
- Scale sanity check — no allocation runs on a misread manifest that claims 8,000 rooms.
- Incremental intake — more passengers can be added later without re-touching the case.
- Compliance tracking — every approval is logged with who, when, why, and against which policy version.
Request types
Initial
First demand on a case. Sets the baseline.
curl -X POST https://us-central1.api.nexastudio.io/demand/case/$CASE_URN \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{ "type": "INITIAL", "roomsRequested": 75 }'
Incremental
Additional rooms on top of the already-approved baseline. Incrementals never reduce or invalidate existing reservations.
curl -X POST https://us-central1.api.nexastudio.io/demand/case/$CASE_URN \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{ "type": "INCREMENTAL", "roomsRequested": 15 }'
Approval flows
Auto-approval
If the active policy has autoApproveDemand: true and roomsRequested ≤ maxAutomaticRoomsPerWave, the demand moves straight to APPROVED and allocation is enqueued.
Incremental demand is still subject to incrementalRequiresApproval — set that to true in high-risk airports.
Manual approval
Otherwise, a supervisor approves with a reason:
curl -X POST https://us-central1.api.nexastudio.io/demand/$DEMAND_URN/approve \
-H "Authorization: Bearer $TOKEN" \
-d '{ "reason": "manifest validated against pax DCS" }'
Rejection is symmetric:
curl -X POST https://us-central1.api.nexastudio.io/demand/$DEMAND_URN/reject \
-H "Authorization: Bearer $TOKEN" \
-d '{ "reason": "duplicate of DMD-xxxxx" }'
State machine
REQUESTED → APPROVED → FULFILLED
↘ PARTIAL
↘ REJECTED
REQUESTED— created but no decision yet.APPROVED— decided; allocation job enqueued.FULFILLED— every requested room has a confirmed reservation.PARTIAL— some rooms booked, others failed (see the associated manual-review item).REJECTED— explicitly rejected by an operator or by a system policy (e.g. the airport is on a freeze).
Fulfillment tracking
For any case:
curl "https://us-central1.api.nexastudio.io/demand/case/$CASE_URN/summary" \
-H "Authorization: Bearer $TOKEN"
Returns:
{
"totalRequested": 90,
"totalApproved": 90,
"totalAllocated": 86,
"totalBooked": 84,
"shortfall": 6,
"shortfallReasons": [
{ "category": "ALLOCATION_FAILED", "groups": ["GRP-7"], "rooms": 4 },
{ "category": "BOOKING_FAILED", "groups": ["GRP-12"], "rooms": 2 }
]
}
This is what the Ops Console surfaces on the case dashboard.
Good practices
- Validate the manifest first. If passenger counts are off, reject and ask the airline to resend — don't approve with the wrong number.
- Prefer incremental over over-approval. If you're not sure whether 10 more passengers will arrive, let them come in as an incremental rather than padding the initial request.
- Document the reason. Audit reviews months later need to know why you approved a 400-room surge. Good reasons cite the manifest source and any comms that confirmed it.