PoliciesReference
API Reference
Policy management API endpoints
Policy API Reference
This reference documents the API endpoints for policy management.
Base URL
/api/v1/policiesAuthentication
All endpoints require authentication via JWT token in the Authorization header:
Authorization: Bearer <token>Endpoints
Evaluate Policy
Evaluate a flight and/or hotel against the user's effective policy.
POST /api/v1/policies/evaluateRequest Body:
{
"flight": {
"originLocationId": "string",
"originCountryId": "string (optional)",
"destinationLocationId": "string",
"destinationCountryId": "string (optional)",
"isInternational": "boolean",
"departureDate": "string (ISO date)",
"price": "number",
"currency": "string",
"cabinClass": "string (ECONOMY, PREMIUM_ECONOMY, BUSINESS, FIRST)",
"stops": "number",
"durationHours": "number (optional)"
},
"hotel": {
"cityId": "string",
"countryId": "string (optional)",
"checkInDate": "string (ISO date)",
"checkOutDate": "string (ISO date)",
"pricePerNight": "number",
"currency": "string",
"starRating": "number (1-5)"
}
}Response:
{
"bookingMode": "DIRECT_BOOKING | REQUEST_ONLY | HYBRID",
"defaultAction": "ALLOW | WARN_AND_ALLOW | REQUIRE_APPROVAL | BLOCK",
"flightEvaluation": {
"compliant": "boolean",
"action": "ALLOW | WARN_AND_ALLOW | REQUIRE_APPROVAL | BLOCK",
"violations": [
{
"type": "PRICE | CABIN_CLASS | STOPS | ADVANCE_BOOKING",
"message": "string",
"limitValue": "number | string[]",
"actualValue": "number | string",
"excessAmount": "number (optional)"
}
]
},
"matchedFlightRule": {
"id": "string",
"maxPricePerPerson": "number",
"currency": "string",
"allowedCabinClasses": "string[]",
"maxStops": "number | null",
"advanceBookingDays": "number | null",
"originCityName": "string | null",
"originCountryName": "string | null",
"destinationCityName": "string | null",
"destinationCountryName": "string | null",
"isInternational": "boolean | null",
"action": "ALLOW | WARN_AND_ALLOW | REQUIRE_APPROVAL | BLOCK | null"
},
"hotelEvaluation": {
"compliant": "boolean",
"action": "ALLOW | WARN_AND_ALLOW | REQUIRE_APPROVAL | BLOCK",
"violations": [
{
"type": "PRICE | STAR_RATING | NIGHTS | ADVANCE_BOOKING",
"message": "string",
"limitValue": "number | string[]",
"actualValue": "number | string",
"excessAmount": "number (optional)"
}
]
},
"matchedHotelRule": {
"id": "string",
"maxPricePerNight": "number",
"currency": "string",
"allowedStarRatings": "number[]",
"maxNights": "number | null",
"advanceBookingDays": "number | null",
"cityName": "string | null",
"countryName": "string | null",
"action": "ALLOW | WARN_AND_ALLOW | REQUIRE_APPROVAL | BLOCK | null"
}
}List Policies
Get all policies for a company.
GET /api/v1/policies?companyId={companyId}Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| companyId | string | Filter by company |
| isActive | boolean | Filter by active status |
| isDefault | boolean | Filter by default status |
| page | number | Page number (default: 1) |
| limit | number | Items per page (default: 20) |
Response:
{
"data": [
{
"id": "string",
"name": "string",
"description": "string | null",
"companyId": "string",
"bookingMode": "DIRECT_BOOKING | REQUEST_ONLY | HYBRID",
"defaultAction": "ALLOW | WARN_AND_ALLOW | REQUIRE_APPROVAL | BLOCK",
"isDefault": "boolean",
"isActive": "boolean",
"createdAt": "string (ISO date)",
"updatedAt": "string (ISO date)"
}
],
"pagination": {
"page": "number",
"limit": "number",
"total": "number",
"totalPages": "number"
}
}Get Policy
Get a single policy with all rules.
GET /api/v1/policies/{policyId}Response:
{
"id": "string",
"name": "string",
"description": "string | null",
"companyId": "string",
"bookingMode": "DIRECT_BOOKING | REQUEST_ONLY | HYBRID",
"defaultAction": "ALLOW | WARN_AND_ALLOW | REQUIRE_APPROVAL | BLOCK",
"isDefault": "boolean",
"isActive": "boolean",
"flightRules": [
{
"id": "string",
"priority": "number",
"originCityId": "string | null",
"originCountryId": "string | null",
"destinationCityId": "string | null",
"destinationCountryId": "string | null",
"isInternational": "boolean | null",
"maxPricePerPerson": "number | null",
"currency": "string",
"allowedCabinClasses": "string[]",
"durationBudgetTiers": "DurationBudgetTier[] | null",
"durationCabinTiers": "DurationCabinTier[] | null",
"maxStops": "number | null",
"advanceBookingDays": "number | null",
"action": "ALLOW | WARN_AND_ALLOW | REQUIRE_APPROVAL | BLOCK | null"
}
],
"hotelRules": [
{
"id": "string",
"priority": "number",
"cityId": "string | null",
"countryId": "string | null",
"maxPricePerNight": "number | null",
"currency": "string",
"allowedStarRatings": "number[]",
"maxNights": "number | null",
"advanceBookingDays": "number | null",
"action": "ALLOW | WARN_AND_ALLOW | REQUIRE_APPROVAL | BLOCK | null"
}
],
"createdAt": "string (ISO date)",
"updatedAt": "string (ISO date)"
}Create Policy
Create a new policy.
POST /api/v1/policiesRequest Body:
{
"name": "string (required, 2-200 chars)",
"description": "string (optional)",
"companyId": "string (required)",
"bookingMode": "DIRECT_BOOKING | REQUEST_ONLY | HYBRID (required)",
"defaultAction": "ALLOW | WARN_AND_ALLOW | REQUIRE_APPROVAL | BLOCK (required)",
"isDefault": "boolean (optional, default: false)",
"isActive": "boolean (optional, default: true)"
}Update Policy
Update an existing policy.
PATCH /api/v1/policies/{policyId}Request Body:
{
"name": "string (optional)",
"description": "string (optional)",
"bookingMode": "DIRECT_BOOKING | REQUEST_ONLY | HYBRID (optional)",
"defaultAction": "ALLOW | WARN_AND_ALLOW | REQUIRE_APPROVAL | BLOCK (optional)",
"isDefault": "boolean (optional)",
"isActive": "boolean (optional)"
}Delete Policy
Soft-delete a policy.
DELETE /api/v1/policies/{policyId}Cannot delete the company default policy. Set another policy as default first.
Flight Rule Endpoints
Create Flight Rule
POST /api/v1/policies/{policyId}/flight-rulesUpdate Flight Rule
PATCH /api/v1/policies/{policyId}/flight-rules/{ruleId}Delete Flight Rule
DELETE /api/v1/policies/{policyId}/flight-rules/{ruleId}Hotel Rule Endpoints
Create Hotel Rule
POST /api/v1/policies/{policyId}/hotel-rulesUpdate Hotel Rule
PATCH /api/v1/policies/{policyId}/hotel-rules/{ruleId}Delete Hotel Rule
DELETE /api/v1/policies/{policyId}/hotel-rules/{ruleId}Assignment Endpoints
Assign Policy to Role
POST /api/v1/policies/{policyId}/role-assignmentsRequest Body:
{
"roleId": "string (required)"
}Assign Policy to User
POST /api/v1/policies/{policyId}/user-assignmentsRequest Body:
{
"userId": "string (required)",
"effectiveFrom": "string (ISO date, optional)",
"effectiveUntil": "string (ISO date, optional)"
}Remove Role Assignment
DELETE /api/v1/policies/{policyId}/role-assignments/{roleId}Remove User Assignment
DELETE /api/v1/policies/{policyId}/user-assignments/{userId}Types
DurationBudgetTier
type DurationBudgetTier = {
minHours: number;
maxHours: number | null;
maxPrice: number;
};DurationCabinTier
type DurationCabinTier = {
minHours: number;
maxHours: number | null;
classes: string[];
};PolicyAction
type PolicyAction = 'ALLOW' | 'WARN_AND_ALLOW' | 'REQUIRE_APPROVAL' | 'BLOCK';BookingMode
type BookingMode = 'DIRECT_BOOKING' | 'REQUEST_ONLY' | 'HYBRID';ViolationType
type ViolationType =
| 'PRICE'
| 'CABIN_CLASS'
| 'STOPS'
| 'ADVANCE_BOOKING'
| 'STAR_RATING'
| 'NIGHTS';Error Responses
400 Bad Request
{
"statusCode": 400,
"message": "Validation failed",
"errors": [
{
"field": "name",
"message": "Name must be between 2 and 200 characters"
}
]
}404 Not Found
{
"statusCode": 404,
"message": "Policy not found"
}403 Forbidden
{
"statusCode": 403,
"message": "Cannot delete company default policy"
}