Saltar al contenido principal

Restaurant API – cURL Commands for Postman

This document provides a complete reference for the Restaurant module API endpoints, including cURL commands ready to import or use in Postman.

Module Overview​

The RestaurantModule (apps/backend/src/restaurant/restaurant.module.ts) exposes twelve controllers:

ControllerBase PathDescription
DiningController/Dining areas and dining tables
OrdersController/ordersOrders and order items
OrderBillsController/Order bills and bill payments
OrderGuestsController/orders/:orderId/guestsOrder guests (seats, aliases, allergies)
OrderPartyController/orders/:orderId/partyOrder party members (waiter, runner)
KitchenController/Kitchen stations, product assignments, print jobs
MenusController/Menus, menu items, location assignments
ProductModifiersController/Product modifier groups and modifiers
ExternalPlatformMappingsController/external-platform-mappingsExternal platform (e.g. delivery) SKU mappings
ReservationsController/reservationsTable reservations
WaitlistController/waitlist-entriesWaitlist entries
PriceRulesController/price-rulesTime/location-based price rules

Dependencies​

  • DatabaseModule – Data persistence
  • CashRegisterModule – Bill payment processing
  • FelModule – Electronic invoicing
  • FirebaseModule – Firebase authentication

Authentication​

All endpoints are protected by Firebase authentication:

  • Header: Authorization: Bearer <firebase-id-token>
  • Cookie: Firebase ID token can also be sent via cookie
  • AuthGuard is applied globally; a valid token is required for every request

Base URL​

  • Local: {{BASE_URL}}
  • Production: Replace with your deployed backend URL

Enum Reference​

OrderStatus​

draft, sent_to_kitchen, partially_served, served, paid, cancelled

OrderType​

dine_in, take_out, delivery_internal, delivery_third_party

OrderItemStatus​

pending, preparing, ready, served, cancelled

DiningTableStatus​

available, occupied, reserved, dirty

PrintJobStatus​

pending, sent, printed, failed

ReservationStatus​

pending, confirmed, seated, no_show, cancelled

WaitlistStatus​

waiting, notified, seated, no_show, cancelled


1. Dining Areas​

Create dining area​

curl -X POST '{{BASE_URL}}/dining-areas' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"businessId": "{{businessId}}",
"locationId": "{{locationId}}",
"name": "Main Floor"
}'

Optional body fields: isActive, createdBy

List dining areas​

curl -X GET '{{BASE_URL}}/dining-areas?businessId={{businessId}}&locationId={{locationId}}&isActive=true&page=1&size=20' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Query params: businessId, locationId, isActive, page, size

Get dining area by ID​

curl -X GET '{{BASE_URL}}/dining-areas/{areaId}' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Update dining area​

curl -X PATCH '{{BASE_URL}}/dining-areas/{areaId}' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"name": "Updated Name",
"isActive": true
}'

Delete dining area​

curl -X DELETE '{{BASE_URL}}/dining-areas/{areaId}' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

2. Dining Tables​

Create dining table​

curl -X POST '{{BASE_URL}}/dining-tables' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"businessId": "{{businessId}}",
"areaId": "{areaId}",
"tableNumber": "T1",
"capacity": 4,
"status": "available"
}'

Optional body fields: capacity, status, metadata, createdBy

List dining tables​

curl -X GET '{{BASE_URL}}/dining-tables?businessId={{businessId}}&locationId={{locationId}}&areaId={areaId}&status=available&page=1&size=20' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Query params: businessId, locationId, areaId, status, page, size

Get dining table by ID​

curl -X GET '{{BASE_URL}}/dining-tables/{tableId}' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Update dining table​

curl -X PATCH '{{BASE_URL}}/dining-tables/{tableId}' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"tableNumber": "T1-A",
"capacity": 6,
"status": "occupied"
}'

Optional body fields: areaId, tableNumber, capacity, status, metadata, updatedBy

Delete dining table​

curl -X DELETE '{{BASE_URL}}/dining-tables/{tableId}' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

3. Orders​

Create order​

curl -X POST '{{BASE_URL}}/orders' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"businessId": "{{businessId}}",
"locationId": "{{locationId}}",
"orderType": "dine_in",
"status": "draft",
"tableId": "{tableId}",
"waiterId": "{waiterId}"
}'

Optional body fields: orderType, status, tableId, waiterId, parentOrderId, createdBy

List orders (paginated)​

curl -X GET '{{BASE_URL}}/orders?businessId={{businessId}}&locationId={{locationId}}&status=draft&orderType=dine_in&tableId={tableId}&page=1&size=20&createdAtFrom=2026-01-01T00:00:00Z&createdAtTo=2026-12-31T23:59:59Z' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Query params: businessId, locationId, status, orderType, tableId, waiterId, createdAtFrom, createdAtTo, page, size

Get order by ID​

curl -X GET '{{BASE_URL}}/orders/{{orderId}}' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Update order​

curl -X PATCH '{{BASE_URL}}/orders/{{orderId}}' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"status": "sent_to_kitchen",
"tableId": "{tableId}"
}'

Optional body fields: locationId, orderType, status, tableId, waiterId, parentOrderId, updatedBy

Delete order​

curl -X DELETE '{{BASE_URL}}/orders/{{orderId}}' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Add order item​

curl -X POST '{{BASE_URL}}/orders/{{orderId}}/items' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"productId": "{{productId}}",
"quantity": 2,
"courseNumber": 1,
"notes": "No onions"
}'

Required: productId, quantity
Optional: courseNumber, modifiers, notes, status, createdBy

List order items​

curl -X GET '{{BASE_URL}}/orders/{{orderId}}/items' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Update order item​

curl -X PATCH '{{BASE_URL}}/orders/{{orderId}}/items/{{orderItemId}}' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"quantity": 3,
"status": "preparing"
}'

Optional body fields: productId, quantity, courseNumber, modifiers, notes, status

Delete order item​

curl -X DELETE '{{BASE_URL}}/orders/{{orderId}}/items/{{orderItemId}}' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Send order to kitchen​

curl -X POST '{{BASE_URL}}/orders/{{orderId}}/send-to-kitchen' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Void order item​

curl -X POST '{{BASE_URL}}/orders/{{orderId}}/items/{{orderItemId}}/void' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"reason": "Customer cancelled",
"voidedBy": "{{userId}}"
}'

Required: reason, voidedBy

Comp order item​

curl -X POST '{{BASE_URL}}/orders/{{orderId}}/items/{{orderItemId}}/comp' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"reason": "Manager comp",
"compedBy": "{{userId}}"
}'

Required: reason, compedBy

Fire order item​

curl -X POST '{{BASE_URL}}/orders/{{orderId}}/items/{{orderItemId}}/fire' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Fire order items by course​

curl -X POST '{{BASE_URL}}/orders/{{orderId}}/items/fire-course' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"courseNumber": 1
}'

Required: courseNumber (integer, min 1)

Collect payment (without bill)​

curl -X POST '{{BASE_URL}}/orders/{{orderId}}/collect-payment' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"amount": 25.50,
"paymentMethodId": "{{paymentMethodId}}",
"cashRegisterSessionId": "{sessionId}",
"safeId": "{safeId}"
}'

Required: amount, paymentMethodId
Optional: cashRegisterSessionId, safeId, createdBy


4. Order Guests​

List order guests​

curl -X GET '{{BASE_URL}}/orders/{{orderId}}/guests' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Add order guest​

curl -X POST '{{BASE_URL}}/orders/{{orderId}}/guests' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"seatNo": 1,
"guestAlias": "Guest 1",
"notes": "VIP",
"allergies": ["nuts"]
}'

Required: seatNo (integer, min 1)
Optional: guestAlias, notes, allergies (array)

Update order guest​

curl -X PATCH '{{BASE_URL}}/orders/{{orderId}}/guests/{guestId}' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"seatNo": 2,
"guestAlias": "Updated alias",
"notes": "Updated notes",
"allergies": ["gluten"]
}'

Optional body fields: seatNo, guestAlias, notes, allergies

Remove order guest​

curl -X DELETE '{{BASE_URL}}/orders/{{orderId}}/guests/{guestId}' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

5. Order Party​

List order party​

curl -X GET '{{BASE_URL}}/orders/{{orderId}}/party' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Assign party member​

curl -X POST '{{BASE_URL}}/orders/{{orderId}}/party' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"role": "waiter",
"userId": "{{userId}}"
}'

Required: role (string, max 50 chars), userId

Remove party member​

curl -X DELETE '{{BASE_URL}}/orders/{{orderId}}/party/{role}' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

6. Order Bills​

Create order bill​

curl -X POST '{{BASE_URL}}/order-bills' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"orderId": "{{orderId}}",
"tipAmount": 5.00,
"mappings": [
{
"orderItemId": "{orderItemId}",
"splitQuantity": 2
}
]
}'

Required: orderId
Optional: tipAmount, mappings (array of { orderItemId, splitQuantity })

List order bills by order​

curl -X GET '{{BASE_URL}}/order-bills?orderId={{orderId}}' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Get order bill by ID​

curl -X GET '{{BASE_URL}}/order-bills/{billId}' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Create payment for bill​

curl -X POST '{{BASE_URL}}/order-bills/{billId}/payments' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"amount": 25.50,
"paymentMethodId": "{{paymentMethodId}}",
"cashRegisterSessionId": "{sessionId}",
"safeId": "{safeId}"
}'

Required: amount, paymentMethodId
Optional: cashRegisterSessionId, safeId, createdBy


7. Kitchen Stations​

Create kitchen station​

curl -X POST '{{BASE_URL}}/kitchen-stations' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"businessId": "{{businessId}}",
"locationId": "{{locationId}}",
"name": "Main Grill",
"isActive": true
}'

Optional body fields: isActive, createdBy

List kitchen stations​

curl -X GET '{{BASE_URL}}/kitchen-stations?businessId={{businessId}}&locationId={{locationId}}&isActive=true&page=1&size=20' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Query params: businessId, locationId, isActive, page (default: 1), size (default: 20)

Update kitchen station​

curl -X PATCH '{{BASE_URL}}/kitchen-stations/{{kitchenStationId}}' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"name": "Updated Grill",
"isActive": true
}'

Heartbeat (keep station online)​

curl -X POST '{{BASE_URL}}/kitchen-stations/{{kitchenStationId}}/heartbeat' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Delete kitchen station​

curl -X DELETE '{{BASE_URL}}/kitchen-stations/{{kitchenStationId}}' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Kitchen station health​

curl -X GET '{{BASE_URL}}/kitchen-stations/health?locationId={{locationId}}&offlineThresholdSeconds=60' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Required: locationId
Optional: offlineThresholdSeconds (integer, default varies)


8. Product Station Assignments​

Create product station assignment​

curl -X POST '{{BASE_URL}}/product-station-assignments' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"businessId": "{{businessId}}",
"locationId": "{{locationId}}",
"stationId": "{{kitchenStationId}}",
"productId": "{{productId}}",
"priority": 1,
"isActive": true
}'

Required: businessId, locationId, stationId
Optional: productId, categoryId, priority, isActive, createdBy

List product station assignments​

curl -X GET '{{BASE_URL}}/product-station-assignments?businessId={{businessId}}&locationId={{locationId}}&stationId={{kitchenStationId}}&productId={{productId}}&categoryId={{categoryId}}&isActive=true' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Update product station assignment​

curl -X PATCH '{{BASE_URL}}/product-station-assignments/{{productStationAssignmentId}}' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"stationId": "{{kitchenStationId}}",
"productId": "{{productId}}",
"priority": 2,
"isActive": false
}'

Delete product station assignment​

curl -X DELETE '{{BASE_URL}}/product-station-assignments/{{productStationAssignmentId}}' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

8a. Send-to-Kitchen Configuration​

When sending an order to the kitchen, each order item must resolve to a kitchen station. If no station is found, the request fails with:

"No kitchen station assignment found for product {{productId}} and no DEFAULT_KITCHEN_STATION_ID configured for this location."

You can fix this in one of two ways:

Option 1: Product/Category Station Assignment​

Assign products or categories to kitchen stations. Use the endpoints in sections 7 and 8:

  1. Create a kitchen station (if none exists): POST /kitchen-stations
  2. Create a product station assignment: POST /product-station-assignments

Example — assign a product to a station:

curl -X POST '{{BASE_URL}}/product-station-assignments' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"businessId": "{{businessId}}",
"locationId": "{{locationId}}",
"stationId": "{{kitchenStationId}}",
"productId": "{{productId}}",
"isActive": true
}'

To assign by category instead, use categoryId instead of productId.

Option 2: Default Kitchen Station​

Configure a default station for the location so items without an assignment use it.

Step 1 — Ensure parameter catalog entry exists

curl -X GET '{{BASE_URL}}/parameters-catalog' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Look for code: "DEFAULT_KITCHEN_STATION_ID". If missing, create it:

curl -X POST '{{BASE_URL}}/parameters-catalog' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"code": "DEFAULT_KITCHEN_STATION_ID",
"name": "Default Kitchen Station ID",
"description": "Fallback kitchen station when no product/category assignment exists",
"dataType": "string",
"entityType": "location",
"isRequired": false,
"isActive": true
}'

Step 2 — Create entity parameter for the location

curl -X POST '{{BASE_URL}}/entity-parameters' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"parameterCatalogId": "{parameterCatalogId}",
"parameterValue": { "value": "{kitchenStationId}" },
"businessId": "{{businessId}}",
"entityType": "location",
"entityId": "{{locationId}}",
"isActive": true,
"createdBy": "{{userId}}"
}'

Required: parameterCatalogId (from step 1), parameterValue (object with value = station UUID), businessId, entityType, entityId (location UUID), isActive, createdBy

List entity parameters​

curl -X GET '{{BASE_URL}}/entity-parameters?businessId={{businessId}}' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

9. Print Jobs​

List print jobs​

curl -X GET '{{BASE_URL}}/print-jobs?status=pending&stationId={{kitchenStationId}}' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Query params: status, stationId

Kitchen print job history (PWA monitor)​

Recent jobs for a location (enriched with product, table, order number, modifiers). Firebase auth — used by Settings → WebSocket monitor → Kitchen tab.

curl -X GET '{{BASE_URL}}/print-jobs/history?locationId={{locationId}}&limit=20' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Required: locationId
Optional: limit (1–100, default 20)

See WebSocket monitor & print history for joined tables and column mapping.

Update print job status​

curl -X PATCH '{{BASE_URL}}/print-jobs/{printJobId}' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"status": "printed",
"lastError": null
}'

Required: status
Optional: lastError


10. Menus​

Create menu​

curl -X POST '{{BASE_URL}}/menus' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"businessId": "{{businessId}}",
"name": "Lunch Menu",
"isActive": true,
"availableFrom": "11:00",
"availableTo": "15:00"
}'

Required: businessId, name
Optional: isActive, availableFrom, availableTo, metadata, createdBy

List menus​

curl -X GET '{{BASE_URL}}/menus?businessId={{businessId}}&isActive=true&page=1&size=20' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Query params: businessId, isActive, page (default: 1), size (default: 20)

Get menu by ID​

curl -X GET '{{BASE_URL}}/menus/{menuId}' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Update menu​

curl -X PATCH '{{BASE_URL}}/menus/{menuId}' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"name": "Updated Menu",
"isActive": true,
"availableFrom": "10:00",
"availableTo": "22:00"
}'

Optional body fields: name, isActive, availableFrom, availableTo, metadata, updatedBy

Delete menu​

curl -X DELETE '{{BASE_URL}}/menus/{menuId}' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Create menu item​

curl -X POST '{{BASE_URL}}/menus/{{menuId}}/items' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"productId": "{{productId}}",
"sortOrder": 0,
"isAvailable": true,
"availableFrom": "11:00",
"availableTo": "22:00"
}'

Required: productId
Optional: sortOrder, isAvailable, availableFrom, availableTo, metadata, createdBy

List menu items​

curl -X GET '{{BASE_URL}}/menus/{{menuId}}/items?page=1&size=20' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Query params: page (default: 1), size (default: 20). Optional: available_at (ISO 8601) – when provided, returns only items available at that time (pagination ignored)

Get menu item by ID​

curl -X GET '{{BASE_URL}}/menus/{{menuId}}/items/{{menuItemId}}' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Update menu item​

curl -X PATCH '{{BASE_URL}}/menus/{{menuId}}/items/{{menuItemId}}' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"sortOrder": 1,
"isAvailable": true,
"availableFrom": "11:00",
"availableTo": "22:00"
}'

Optional body fields: sortOrder, isAvailable, availableFrom, availableTo, metadata, updatedBy

Delete menu item​

curl -X DELETE '{{BASE_URL}}/menus/{{menuId}}/items/{{menuItemId}}' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Assign menu to location​

curl -X POST '{{BASE_URL}}/locations/{{locationId}}/menus' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"menuId": "{menuId}"
}'

Required: menuId

Unassign menu from location​

curl -X DELETE '{{BASE_URL}}/locations/{{locationId}}/menus/{menuId}' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Get menus for location​

curl -X GET '{{BASE_URL}}/locations/{{locationId}}/menus' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Optional query: available=true – filter by availability at current time; available_at (ISO 8601) – availability at given time


11. Product Modifier Groups & Modifiers​

Create product modifier group​

curl -X POST '{{BASE_URL}}/product-modifier-groups' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"productId": "{{productId}}",
"businessId": "{{businessId}}",
"name": "Size",
"minSelection": 0,
"maxSelection": 1,
"sortOrder": 0
}'

Required: productId, businessId, name
Optional: minSelection (0–100), maxSelection (1–100), sortOrder, createdBy

List product modifier groups​

curl -X GET '{{BASE_URL}}/product-modifier-groups?productId={{productId}}&businessId={{businessId}}' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Query params: productId, businessId

List modifiers by group​

curl -X GET '{{BASE_URL}}/product-modifier-groups/{groupId}/modifiers' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Get modifier group by ID​

curl -X GET '{{BASE_URL}}/product-modifier-groups/{groupId}' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Update modifier group​

curl -X PATCH '{{BASE_URL}}/product-modifier-groups/{groupId}' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"name": "Updated Size",
"minSelection": 1,
"maxSelection": 2,
"sortOrder": 1
}'

Optional body fields: name, minSelection, maxSelection, sortOrder, updatedBy

Delete modifier group​

curl -X DELETE '{{BASE_URL}}/product-modifier-groups/{groupId}' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Create product modifier​

curl -X POST '{{BASE_URL}}/product-modifiers' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"groupId": "{groupId}",
"name": "Large",
"priceAdjustment": 2.50,
"sortOrder": 0
}'

Required: groupId, name
Optional: priceAdjustment, sortOrder, createdBy

Get modifier by ID​

curl -X GET '{{BASE_URL}}/product-modifiers/{modifierId}' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Update product modifier​

curl -X PATCH '{{BASE_URL}}/product-modifiers/{modifierId}' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"name": "Extra Large",
"priceAdjustment": 3.00,
"sortOrder": 1
}'

Optional body fields: name, priceAdjustment, sortOrder, updatedBy

Delete product modifier​

curl -X DELETE '{{BASE_URL}}/product-modifiers/{modifierId}' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

12. External Platform Mappings​

Create external platform mapping​

curl -X POST '{{BASE_URL}}/external-platform-mappings' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"businessId": "{{businessId}}",
"productId": "{{productId}}",
"platformCode": "uber_eats",
"externalSku": "EXT-001",
"externalName": "Product Name on Platform"
}'

Required: businessId, productId, platformCode (max 50 chars)
Optional: externalSku, externalName, metadata

List external platform mappings​

curl -X GET '{{BASE_URL}}/external-platform-mappings?businessId={{businessId}}&productId={{productId}}' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Query params: businessId, productId

Get mapping by ID​

curl -X GET '{{BASE_URL}}/external-platform-mappings/{mappingId}' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Update external platform mapping​

curl -X PATCH '{{BASE_URL}}/external-platform-mappings/{mappingId}' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"externalSku": "EXT-002",
"externalName": "Updated Name"
}'

Optional body fields: externalSku, externalName, metadata

Delete external platform mapping​

curl -X DELETE '{{BASE_URL}}/external-platform-mappings/{mappingId}' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

13. Reservations​

Create reservation​

curl -X POST '{{BASE_URL}}/reservations' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"businessId": "{{businessId}}",
"locationId": "{{locationId}}",
"reservedAt": "2026-02-20T19:00:00.000Z",
"partySize": 4,
"customerId": "{customerId}",
"tableId": "{tableId}",
"status": "confirmed",
"notes": "Window table preferred"
}'

Required: businessId, locationId, reservedAt (ISO 8601), partySize (min 1)
Optional: customerId, tableId, status, notes, createdBy

List reservations​

curl -X GET '{{BASE_URL}}/reservations?businessId={{businessId}}&locationId={{locationId}}&status=pending&reservedAtFrom=2026-02-19T00:00:00Z&reservedAtTo=2026-02-20T23:59:59Z&page=1&size=20' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Query params: businessId, locationId, status, reservedAtFrom (ISO 8601), reservedAtTo (ISO 8601), page (default: 1), size (default: 20)

Get reservation by ID​

curl -X GET '{{BASE_URL}}/reservations/{reservationId}' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Update reservation​

curl -X PATCH '{{BASE_URL}}/reservations/{reservationId}' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"reservedAt": "2026-02-20T20:00:00.000Z",
"partySize": 6,
"status": "confirmed",
"notes": "Birthday party"
}'

Optional body fields: reservedAt, partySize, customerId, tableId, status, notes, updatedBy

Delete reservation​

curl -X DELETE '{{BASE_URL}}/reservations/{reservationId}' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

14. Waitlist Entries​

Create waitlist entry​

curl -X POST '{{BASE_URL}}/waitlist-entries' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"businessId": "{{businessId}}",
"locationId": "{{locationId}}",
"partySize": 2,
"notifyPhone": "+1234567890",
"notifyEmail": "guest@example.com",
"estimatedWaitMinutes": 15,
"status": "waiting",
"notes": "High chair needed"
}'

Required: businessId, locationId, partySize (min 1)
Optional: notifyPhone, notifyEmail, estimatedWaitMinutes, status, notes, createdBy

List waitlist entries​

curl -X GET '{{BASE_URL}}/waitlist-entries?businessId={{businessId}}&locationId={{locationId}}&status=waiting&page=1&size=20' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Query params: businessId, locationId, status, page (default: 1), size (default: 20)

Get waitlist entry by ID​

curl -X GET '{{BASE_URL}}/waitlist-entries/{entryId}' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Update waitlist entry​

curl -X PATCH '{{BASE_URL}}/waitlist-entries/{entryId}' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"partySize": 3,
"status": "notified",
"estimatedWaitMinutes": 10,
"notes": "Updated notes"
}'

Optional body fields: partySize, notifyPhone, notifyEmail, estimatedWaitMinutes, status, notes

Delete waitlist entry​

curl -X DELETE '{{BASE_URL}}/waitlist-entries/{entryId}' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

15. Price Rules​

Create price rule​

curl -X POST '{{BASE_URL}}/price-rules' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"businessId": "{{businessId}}",
"locationId": "{{locationId}}",
"diningAreaId": "{diningAreaId}",
"name": "Happy Hour",
"dayOfWeek": [1, 2, 3, 4, 5],
"startTime": "16:00",
"endTime": "18:00",
"discountType": "percentage",
"discountValue": 20,
"productIds": ["{{productId}}"],
"categoryIds": ["{{categoryId}}"],
"isActive": true
}'

Required: businessId, name, discountType, discountValue
Optional: locationId, diningAreaId, dayOfWeek (0–6 array), startTime, endTime, productIds, categoryIds, isActive, createdBy

List price rules​

curl -X GET '{{BASE_URL}}/price-rules?businessId={{businessId}}&locationId={{locationId}}&diningAreaId={{diningAreaId}}&isActive=true&page=1&size=20' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Query params: businessId, locationId, diningAreaId, isActive, page (default: 1), size (default: 20)

Get price rule by ID​

curl -X GET '{{BASE_URL}}/price-rules/{ruleId}' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Update price rule​

curl -X PATCH '{{BASE_URL}}/price-rules/{ruleId}' \
-H 'Authorization: Bearer {{ID_TOKEN}}' \
-H 'Content-Type: application/json' \
-d '{
"name": "Updated Happy Hour",
"discountValue": 25,
"isActive": false
}'

Optional body fields: name, dayOfWeek, startTime, endTime, discountType, discountValue, productIds, categoryIds, isActive

Delete price rule​

curl -X DELETE '{{BASE_URL}}/price-rules/{ruleId}' \
-H 'Authorization: Bearer {{ID_TOKEN}}'

Postman Setup​

Environment variables​

Create a Postman environment with:

VariableExampleDescription
BASE_URLhttp://localhost:4000Backend base URL
ID_TOKENeyJhbGc...Firebase ID token
businessIduuidBusiness UUID
locationIduuidLocation UUID
areaIduuidDining area UUID
tableIduuidDining table UUID
orderIduuidOrder UUID
orderItemIduuidOrder item UUID
menuItemIduuidMenu item UUID
guestIduuidOrder guest UUID
productIduuidProduct UUID
categoryIduuidProduct category UUID
menuIduuidMenu UUID
groupIduuidModifier group UUID
modifierIduuidProduct modifier UUID
kitchenStationIduuidKitchen station UUID
productStationAssignmentIduuidProduct station assignment UUID
printJobIduuidPrint job UUID
parameterCatalogIduuidParameter catalog entry UUID
billIduuidOrder bill UUID
paymentMethodIduuidPayment method UUID
sessionIduuidCash register session UUID
userIduuidUser UUID
reservationIduuidReservation UUID
entryIduuidWaitlist entry UUID
mappingIduuidExternal platform mapping UUID
ruleIduuidPrice rule UUID

Usage in Postman​

  • URL: {{BASE_URL}}/orders
  • Headers: Authorization: Bearer {{ID_TOKEN}}

Obtaining a token​

  1. Sign in via the app’s auth flow.
  2. Copy the Firebase ID token from:
    • DevTools → Application → Cookies
    • Or the Authorization header of a logged-in request
  3. Use a Firebase client SDK to call getIdToken() on the current user.