Policies
A policy is the set of rules Nexa uses to decide which hotels are acceptable for a given case. Policies are versioned, activated explicitly, and matched to cases by context (airport / airline / country).
Why policies exist
Without policy, allocation has no opinion — it will happily book a 2-star motel for a Business-class passenger, or a 5-star inner-city property for an Economy group. Policies encode the operator's preferences, budget caps, quality standards, and special requirements outside the code, so they can evolve without a deploy.
Authoring a policy
curl -X POST https://us-central1.api.nexastudio.io/policies \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "MAD — VIP tiers",
"context": { "airport": "MAD", "airline": "XX" },
"tiers": ["BUSINESS", "FIRST", "CREW"],
"constraints": {
"minStars": 4,
"maxDistanceKm": 15,
"maxNightlyRate": 350,
"requiredAmenities": ["24H_RECEPTION", "AIRPORT_SHUTTLE"],
"excludedChains": ["BUDGETCHAIN"]
},
"buffers": {
"lateCheckoutMinutes": 120,
"earlyCheckInMinutes": 60
},
"mode": "ON_DEMAND",
"autoApproveDemand": false
}'
Activating and deactivating
A policy in DRAFT has no effect. Activate it with:
curl -X POST https://us-central1.api.nexastudio.io/policies/$POLICY_URN/activate
Activation freezes the previous version of the same context (same airport/airline/tier set) to ARCHIVED. To roll back, reactivate the archived version.
Matching rules
When a case needs allocation, Nexa looks for the most-specific active policy that matches:
- Exact
airport + airline + tier. - Then
airport + tier. - Then
airline + tier. - Then global by
tier.
The first match wins. If no policy matches, the case lands in MANUAL_REVIEW with category POLICY_VIOLATION.
Constraint reference
| Constraint | Type | Notes |
|---|---|---|
minStars | 1–5 | Excludes unrated properties |
maxDistanceKm | number | Straight-line from airport coordinates |
maxNightlyRate | number (currency) | Currency is derived from policy context |
requiredAmenities | enum[] | Normalized amenity tags |
excludedChains | string[] | Provider-independent chain IDs |
acceptedPayments | enum[] | Default: GUARANTEE; enable CARD for airports that require it |
allowProviders | enum[] | Restrict to a provider subset (e.g. contracts-only) |
Operational flags
| Flag | Effect |
|---|---|
mode: BATCH | Waves run on a schedule to consolidate inventory queries |
mode: ON_DEMAND | Waves run the moment demand is approved |
autoApproveDemand | Skip the human checkpoint when roomsRequested ≤ maxAutomaticRoomsPerWave |
incrementalRequiresApproval | Force manual approval on incremental requests even when auto-approve is on |
consolidationWeight | 0.0–1.0 — how aggressively the scorer prefers fewer hotels |
Natural-language synthesis
Operators can describe a policy in plain English and have Nexa generate the structured payload using the policy synthesizer — a Nexa Trained Model on Google:
curl -X POST https://us-central1.api.nexastudio.io/policies/synthesize \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"description": "For MAD business and first class, 4+ star only, within 15 km, must have 24-hour reception and airport shuttle. No budget chains."
}'
The response is a policy draft with provenance (source: "ai", confidence, prompt). A supervisor still has to review and activate.
See AI policy synthesis for prompt tuning and confidence thresholds.
Auditing policy changes
Every create / update / activate / deactivate writes an audit entry:
curl https://us-central1.api.nexastudio.io/audit?entity=policy&entityUrn=$POLICY_URN
You will see actor, timestamp, reason, and a before/after snapshot for every field that changed.
Common patterns
- One policy per airport × tier is the most maintainable split. Avoid global policies.
- Lower tiers need looser distance caps — Economy can accept 30 km, Business rarely accepts more than 15 km.
- Keep
excludedChainsshort. PreferrequiredAmenitiesand stars — they are easier to reason about and survive inventory churn. - Don't auto-approve incremental demand unless your airline has a trusted operations team upstream. Set
incrementalRequiresApproval: trueas a safe default.