API Endpoints Reference
Complete reference for all Pricing Engine API endpoints.
Base URLs
- Staging:
https://price-engine.hh-engineering.my.id - Local:
http://localhost:3001
Authentication
All Partner API endpoints require JWT Bearer token:
Authorization: Bearer {jwt_token}
Get token from HH-Server /api/partner/v1/sign_in endpoint.
Restaurant Context
Partner API requires restaurant context via:
X-Restaurant-Idheader (recommended)restaurant_idquery parameter
Partner API (/api/partner/v1/*)
Pricing Rules
List Pricing Rules
GET /api/partner/v1/pricing_rules
Headers:
Authorization: Bearer tokenX-Restaurant-Id: Restaurant ID (optional for list)
Query Parameters:
restaurant_id(String, optional): Filter by restaurantactive(Boolean, optional): Filter by active statusname(String, optional): Search by namepriority(Integer, optional): Filter by priority
Response: 200 OK
{
"data": [...],
"meta": { "total": 10 }
}
Get Pricing Rule
GET /api/partner/v1/pricing_rules/:id
Response: 200 OK
Create Pricing Rule
POST /api/partner/v1/pricing_rules
Headers:
X-Restaurant-Id: Required
Request Body:
{
"pricing_rule": {
"name": "Weekend Special",
"rule_type": "specific_date_time",
"priority": 10,
"active": false,
"requires_approval": false,
"start_date": "2025-01-01",
"is_no_end_date": true,
"apply_to_all_packages": true,
"date_time_conditions_attributes": [
{
"date_type": "day_time_of_week",
"days_of_week": [0, 6],
"action_type": "increase",
"value_type": "percentage",
"value": 1000,
"condition_items_attributes": [
{
"start_time": "11:00",
"end_time": "14:00"
}
]
}
]
}
}
Response: 201 Created
Update Pricing Rule
PATCH /api/partner/v1/pricing_rules/:id
Request Body: Same as create
Response: 200 OK
Delete Pricing Rule
DELETE /api/partner/v1/pricing_rules/:id
Response: 204 No Content
Activate Pricing Rule
PATCH /api/partner/v1/pricing_rules/:id/activate
Response: 200 OK
Deactivate Pricing Rule
PATCH /api/partner/v1/pricing_rules/:id/deactivate
Response: 200 OK
Clone Pricing Rule
POST /api/partner/v1/pricing_rules/:id/clone
Response: 201 Created
Global Pricing Settings
Get Global Setting
GET /api/partner/v1/global_pricing_setting
Headers:
X-Restaurant-Id: Required
Response: 200 OK
{
"id": 1,
"restaurant_id": "123",
"price_increase_limit_type": "percentage",
"price_increase_limit_value": 5000,
"price_decrease_limit_type": "percentage",
"price_decrease_limit_value": 5000,
"created_at": "2025-01-01T00:00:00Z",
"updated_at": "2025-01-01T00:00:00Z"
}
Note: Auto-creates with defaults if not exists
Update Global Setting
PATCH /api/partner/v1/global_pricing_setting
Headers:
X-Restaurant-Id: Required
Request Body:
{
"global_pricing_setting": {
"price_increase_limit_type": "percentage",
"price_increase_limit_value": 2500,
"price_decrease_limit_type": "fixed_amount",
"price_decrease_limit_value": 10000
}
}
Response: 200 OK
Price History
List Price History
GET /api/partner/v1/pricing_rule_histories
Query Parameters:
pricing_rule_id(Integer, optional): Filter by ruleaction(String, optional): Filter by action type
Response: 200 OK
Get History Entry
GET /api/partner/v1/pricing_rule_histories/:id
Response: 200 OK
Undo Price Change
POST /api/partner/v1/pricing_rule_histories/:id/undo
Response: 200 OK
Public API V1 (/api/v1/*)
No authentication required. These endpoints are designed for the booking system to query pricing modifiers.
All endpoints use ModifierService.for_restaurant(restaurant_id) as their data bank, returning pre-filtered modifiers that are:
- Active (
active: true) - Approved (
rule_status: 'approved')
Date filtering differs by endpoint:
GET /api/v1/packages_pricing_rules/:restaurant_idreturns rules that are not expired (end_date >= today OR is_no_end_date). Upcoming rules (start_date > today) are included so the overview shows every rule that will eventually apply.POST /api/v1/get_available_rules_by_date,POST /api/v1/get_available_rules_by_time, andPOST /api/v1/verify_active_rulesreturn rules that are valid for the queried date/time (start_date <= date <= end_date, matching day-of-week and time slot).
Get Packages Pricing Rules
GET /api/v1/packages_pricing_rules/:restaurant_id
Get all active pricing modifiers for a restaurant. Used by booking UI to display pricing adjustments on package cards.
Response: 200 OK
{
"success": true,
"data": [
{
"id": "uuid",
"name": "Weekend Surge",
"action_type": "increase",
"value_type": "percentage",
"value": 1500,
"priority": 10,
"package_ids": ["pkg_1", "pkg_2"],
"apply_to_all_packages": false,
"date_type": "day_of_week",
"days_of_week": [0, 6],
"condition_items": [...]
}
],
"meta": {
"count": 3,
"queried_at": "2025-06-15T10:30:00Z"
}
}
Get Available Rules by Date
POST /api/v1/get_available_rules_by_date
Filter modifiers applicable to a specific date.
Request Body:
{
"restaurant_id": "uuid",
"date": "2025-06-15",
"package_ids": ["pkg_123", "pkg_456"]
}
Response: 200 OK
{
"success": true,
"data": [...],
"meta": {
"date": "2025-06-15",
"day_of_week": 6,
"count": 1
}
}
Get Available Rules by Time
POST /api/v1/get_available_rules_by_time
Filter modifiers applicable to a specific date AND time.
Request Body:
{
"restaurant_id": "uuid",
"date": "2025-06-15",
"time": "19:30",
"package_ids": ["pkg_123"]
}
Response: 200 OK
{
"success": true,
"data": [...],
"meta": {
"date": "2025-06-15",
"time": "19:30",
"day_of_week": 6,
"count": 1
}
}
Verify Active Rules
POST /api/v1/verify_active_rules
Verify pricing rules are still active and valid at reservation time. Validates rule applicability, activity status, and value matching.
Request Body:
{
"restaurant_id": "uuid",
"date": "2026-01-30",
"time": "19:00",
"packages": [
{
"id": "4578",
"pricing_rules": {
"id": 2732,
"action_type": "decrease",
"value_type": "percentage",
"value": 500
}
}
]
}
Validation Checks:
- Rule exists and is active
- Rule applies to the package (apply_to_all OR package in rule’s list)
- Rule is active on the date/day of week/time
- Rule values match (action_type, value_type, value)
Response (All Valid): 200 OK
{
"success": true,
"valid": true,
"results": [
{
"package_id": "4578",
"rule_id": 2732,
"valid": true,
"reason": null,
"current_values": {
"action_type": "decrease",
"value_type": "percentage",
"value": 500
}
}
],
"message": null
}
Response (Invalid): 422 Unprocessable Content
{
"success": false,
"valid": false,
"results": [
{
"package_id": "4578",
"rule_id": 2732,
"valid": false,
"reason": "values_changed",
"message": "Rule values have been updated",
"changes": [
{"field": "value", "expected": 500, "actual": 1000}
],
"current_values": {
"action_type": "decrease",
"value_type": "percentage",
"value": 1000
}
}
],
"message": "One or more pricing rules are no longer valid"
}
Invalid Reasons:
rule_not_found- Rule not found or deactivatednot_applicable_to_package- Rule doesn’t apply to packagenot_active_on_date- Rule not active on datenot_active_on_day- Rule not active on day of weeknot_active_at_time- Rule not active at timevalues_changed- Rule values have changed
Get Modifier History
POST /api/v1/get_modifier_history
Get history/audit trail for applied modifiers.
Request Body:
{
"restaurant_id": "uuid",
"modifier_ids": ["modifier_uuid_1"],
"booking_id": "booking_123"
}
Response: 200 OK
{
"success": true,
"data": [
{
"id": "modifier_uuid_1",
"name": "Weekend Surge",
"pricing_rule_id": "rule_uuid",
"history": [...]
}
],
"meta": {
"count": 1,
"queried_at": "2025-06-15T10:35:00Z"
}
}
Internal API (/api/internal/v1/*)
Active Price Modifier Definitions
GET /api/internal/v1/price_modifiers
Returns active, current-or-future denormalized modifier definitions for trusted
server-to-server pricing evaluators. It requires X-Internal-Api-Key and a
required restaurant_ids query parameter (single, comma-separated, or array).
The endpoint returns evaluation data and deterministic priority order; it does
not calculate a price.
See Internal Active Price Modifiers API for the selection rules, full response contract, and consumer evaluation guidance.
Token Sync
Authentication: X-Internal-Api-Key header
Login (Cache Token)
POST /api/internal/v1/auth/login
Logout (Invalidate Token)
POST /api/internal/v1/auth/logout
Refresh Token
POST /api/internal/v1/auth/refresh
Force Invalidate
POST /api/internal/v1/auth/invalidate
Health & Status
Health Check
GET /up
Response: 200 OK
Detailed Health
GET /health
Response: 200 OK
Error Responses
400 Bad Request
Missing required parameters or invalid format
401 Unauthorized
Missing or invalid JWT token
403 Forbidden
User doesn’t have access to the restaurant
404 Not Found
Resource not found
422 Unprocessable Entity
Validation errors
{
"errors": ["Validation error messages"]
}
500 Internal Server Error
Server error