Skip to main content

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

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.