Restaurant Management System - API Documentation

Base URL: http://localhost:8000/api
Version: 1.0
Last Updated: April 08, 2026


Table of Contents

  1. Authentication
  2. Menu Management
  3. Floors & Tables
  4. Orders
  5. Kitchen Display System
  6. Reservations
  7. Offers & Discounts
  8. Customers (CRM)
  9. Loyalty Points
  10. Payments
  11. Inventory Management
  12. Suppliers & Purchases
  13. Financial Reports
  14. Expenses

Authentication

Login

POST /auth/login

Authenticate and get access token.

Request:

{
  "email": "user@example.com",
  "password": "password123"
}

Response (200):

{
  "message": "Login successful",
  "data": {
    "token": "token_here",
    "user": {
      "id": 1,
      "name": "John Doe",
      "email": "user@example.com",
      "roles": ["manager"]
    }
  }
}

Logout

POST /auth/logout

Invalidate current token.

Headers: Authorization: Bearer {token}

Response (200):

{
  "message": "Logout successful"
}

Get Current User

GET /auth/me

Response (200):

{
  "data": {
    "id": 1,
    "name": "John Doe",
    "email": "user@example.com",
    "branch_id": 1
  }
}

Get Permissions

GET /auth/permissions

Response (200):

{
  "data": {
    "permissions": ["read:orders", "write:orders"],
    "roles": ["manager"]
  }
}

Menu Management

Categories

List Categories

GET /categories?per_page=15&search=beverages

Response (200):

{
  "data": [
    {
      "id": 1,
      "name": "Beverages",
      "slug": "beverages",
      "description": "All drinks",
      "image_url": "https://...",
      "sort_order": 1,
      "status": "active",
      "items_count": 12,
      "created_at": "2026-03-30 10:00:00"
    }
  ],
  "pagination": {
    "current_page": 1,
    "total": 5
  }
}

Create Category

POST /categories

Required Roles: admin, manager

Request:

{
  "name": "Beverages",
  "description": "All drinks",
  "image_url": "https://...",
  "sort_order": 1,
  "status": "active"
}

Response (201):

{
  "message": "Category created successfully",
  "data": {
    "id": 5,
    "name": "Beverages",
    "slug": "beverages",
    "description": "All drinks",
    "image_url": "https://...",
    "sort_order": 1,
    "status": "active",
    "items_count": 0,
    "created_at": "2026-03-31 10:00:00"
  }
}

Get Category

GET /categories/{id}

Response (200):

{
  "data": {
    "id": 1,
    "name": "Beverages",
    "slug": "beverages",
    "items": [...]
  }
}

Update Category

PUT /categories/{id}

Request:

{
  "name": "Beverages Updated",
  "status": "active"
}

Response (200):

{
  "message": "Category updated successfully",
  "data": {...}
}

Delete Category

DELETE /categories/{id}

Response (200):

{
  "message": "Category deleted successfully"
}

Restore Category

POST /categories/{id}/restore

Response (200):

{
  "message": "Category restored successfully",
  "data": {...}
}

Get Categories with Items

GET /categories/with-items

Response (200):

{
  "data": [
    {
      "id": 1,
      "name": "Beverages",
      "items": [
        {
          "id": 10,
          "name": "Coffee",
          "price": 150,
          "status": "active"
        }
      ]
    }
  ]
}

Menu Items

List Menu Items

GET /menu-items?per_page=15&category=beverages&status=active&search=coffee

Query Parameters:

Response (200):

{
  "data": [
    {
      "id": 10,
      "name": "Espresso Coffee",
      "price": 150.00,
      "description": "Strong black coffee",
      "image_url": "https://...",
      "category": {
        "id": 1,
        "name": "Beverages"
      },
      "is_vegetarian": true,
      "is_vegan": true,
      "is_spicy": false,
      "preparation_time": 5,
      "status": "active",
      "variants": [
        {
          "id": 1,
          "name": "Size",
          "items": ["Small", "Medium", "Large"]
        }
      ],
      "created_at": "2026-03-30 10:00:00"
    }
  ],
  "pagination": {
    "current_page": 1,
    "total": 45
  }
}

Create Menu Item

POST /menu-items

Request:

{
  "category_id": 1,
  "name": "Cappuccino",
  "price": 200,
  "description": "Espresso with milk foam",
  "image_url": "https://...",
  "is_vegetarian": true,
  "is_vegan": false,
  "is_spicy": false,
  "preparation_time": 5,
  "status": "active"
}

Response (201):

{
  "message": "Menu item created successfully",
  "data": {
    "id": 11,
    "name": "Cappuccino",
    "price": 200.00,
    ...
  }
}

Update Menu Item

PUT /menu-items/{id}

Response (200):

{
  "message": "Menu item updated successfully",
  "data": {...}
}

Toggle Status

PATCH /menu-items/{id}/status

Response (200):

{
  "message": "Status updated successfully",
  "data": {...}
}

Get Menu Item Variants

GET /menu-items/{id}/variants

Response (200):

{
  "data": [
    {
      "id": 1,
      "name": "Size",
      "description": "Choose size",
      "price_modifier": 0,
      "is_required": true,
      "options": [
        {"id": 1, "name": "Small", "price_modifier": 0},
        {"id": 2, "name": "Medium", "price_modifier": 50},
        {"id": 3, "name": "Large", "price_modifier": 100}
      ]
    }
  ]
}

Add Variant

POST /menu-items/{id}/variants

Request:

{
  "name": "Temperature",
  "description": "Choose temperature",
  "price_modifier": 0,
  "is_required": false,
  "sort_order": 1,
  "status": "active",
  "options": [
    {"name": "Hot", "price_modifier": 0},
    {"name": "Iced", "price_modifier": 20}
  ]
}

Response (201):

{
  "message": "Variant added successfully",
  "data": {...}
}

Delete Variant

DELETE /menu-items/{id}/variants/{variantId}

Response (200):

{
  "message": "Variant deleted successfully"
}

Get Items by Category

GET /menu-items/category/{categoryId}

Response (200):

{
  "data": [...]
}

Floors & Tables

Floors

List Floors

GET /floors?per_page=15

Response (200):

{
  "data": [
    {
      "id": 1,
      "branch_id": 1,
      "name": "Ground Floor",
      "description": "Main dining area",
      "floor_number": 1,
      "tables_count": 12,
      "status": "active",
      "created_at": "2026-03-30 10:00:00"
    }
  ]
}

Create Floor

POST /floors

Request:

{
  "name": "First Floor",
  "description": "Private dining area",
  "floor_number": 2,
  "status": "active"
}

Response (201):

{
  "message": "Floor created successfully",
  "data": {...}
}

Get Floors with Tables

GET /floors/with-tables

Response (200):

{
  "data": [
    {
      "id": 1,
      "name": "Ground Floor",
      "tables": [
        {
          "id": 1,
          "name": "Table 1",
          "capacity": 4,
          "status": "available"
        }
      ]
    }
  ]
}

Tables

List Tables

GET /tables?per_page=20&status=available

Query Parameters:

Response (200):

{
  "data": [
    {
      "id": 1,
      "floor_id": 1,
      "floor_name": "Ground Floor",
      "name": "Table 1",
      "capacity": 4,
      "status": "available",
      "current_occupancy": 0,
      "qr_code_url": "https://...",
      "created_at": "2026-03-30 10:00:00"
    }
  ]
}

Create Table

POST /tables

Request:

{
  "floor_id": 1,
  "name": "Table 1",
  "capacity": 4,
  "status": "available"
}

Response (201):

{
  "message": "Table created successfully",
  "data": {...}
}

Get Available Tables

GET /tables/available

Response (200):

{
  "data": [...]
}

Get Occupied Tables

GET /tables/occupied

Response (200):

{
  "data": [...]
}

Update Table Status

PATCH /tables/{id}/status

Request:

{
  "status": "occupied"
}

Response (200):

{
  "message": "Table status updated successfully",
  "data": {...}
}

Get Tables by Floor

GET /tables/floor/{floorId}

Response (200):

{
  "data": [...]
}

Orders

List Orders

GET /orders?per_page=15&status=pending&from_date=2026-03-01&to_date=2026-03-31&search=101

Query Parameters:

Response (200):

{
  "data": [
    {
      "id": 101,
      "order_number": "ORD-2026-001",
      "branch_id": 1,
      "customer_name": "John Doe",
      "customer_phone": "9876543210",
      "order_type": "dine-in",
      "table_id": 1,
      "table_name": "Table 1",
      "status": "pending",
      "items_count": 3,
      "subtotal": 500.00,
      "discount": 50.00,
      "tax": 81.00,
      "total_amount": 531.00,
      "notes": "Extra spicy",
      "created_at": "2026-03-31 12:00:00",
      "updated_at": "2026-03-31 12:05:00"
    }
  ],
  "pagination": {
    "current_page": 1,
    "total": 42
  }
}

Create Order

POST /orders

Request:

{
  "customer_name": "John Doe",
  "customer_phone": "9876543210",
  "order_type": "dine-in",
  "table_id": 1,
  "items": [
    {
      "menu_item_id": 10,
      "quantity": 2,
      "notes": "Extra spicy",
      "variant_selections": {
        "size": "Large",
        "temperature": "Hot"
      }
    }
  ],
  "delivery_address": null,
  "special_requests": "No onions"
}

Response (201):

{
  "message": "Order created successfully",
  "data": {
    "id": 101,
    "order_number": "ORD-2026-001",
    "status": "pending",
    "items": [
      {
        "id": 1,
        "menu_item_name": "Cappuccino",
        "quantity": 2,
        "price": 200,
        "subtotal": 400,
        "notes": "Extra spicy"
      }
    ],
    "total_amount": 531.00
  }
}

Get Order Details

GET /orders/{id}/details

Response (200):

{
  "message": "Order details retrieved successfully",
  "data": {
    "order": {...},
    "items": [
      {
        "id": 1,
        "menu_item_id": 10,
        "menu_item_name": "Cappuccino",
        "quantity": 2,
        "price": 200.00,
        "subtotal": 400.00,
        "notes": "Extra spicy"
      }
    ]
  }
}

Update Order Status

PATCH /orders/{id}/status

Request:

{
  "status": "preparing"
}

Response (200):

{
  "message": "Order status updated successfully",
  "data": {...}
}

Get Pending Orders

GET /orders/pending

Response (200):

{
  "data": [...]
}

Get Orders by Status

GET /orders/status/{status}

Status Values: pending, preparing, ready, completed, cancelled

Response (200):

{
  "data": [...]
}

Get Orders by Date Range

GET /orders/by-date-range?from_date=2026-03-01&to_date=2026-03-31

Response (200):

{
  "data": [...]
}

Add Item to Order

POST /orders/{id}/add-item

Request:

{
  "menu_item_id": 10,
  "quantity": 1,
  "special_requests": "No sugar"
}

Response (200):

{
  "message": "Item added to order successfully",
  "data": {...}
}

Remove Item from Order

POST /orders/{id}/remove-item/{itemId}

Response (200):

{
  "message": "Item removed from order successfully",
  "data": {...}
}

Get Top Menu Items

GET /orders/top-menu-items?days=30&limit=10

Response (200):

{
  "message": "Top menu items retrieved successfully",
  "data": [
    {
      "menu_item_id": 10,
      "name": "Cappuccino",
      "total_orders": 156,
      "total_qty": 280,
      "revenue": 56000.00
    }
  ]
}

Get Order Summary

GET /orders/summary?days=7

Response (200):

{
  "message": "Order summary retrieved successfully",
  "data": {
    "total_orders": 42,
    "completed_orders": 40,
    "total_revenue": 21580.00,
    "average_order_value": 514.29,
    "most_popular_item": "Cappuccino"
  }
}

Kitchen Display System

Dashboard

GET /kitchen/dashboard

Response (200):

{
  "message": "Dashboard retrieved successfully",
  "data": {
    "pending_count": 3,
    "preparing_count": 5,
    "ready_count": 2,
    "pending_orders": [...],
    "preparing_orders": [...],
    "ready_orders": [...]
  }
}

Pending Orders (KOT)

GET /kitchen/pending

Kitchen orders to prepare (KOT).

Response (200):

{
  "data": [
    {
      "id": 101,
      "order_number": "ORD-2026-001",
      "table_name": "Table 1",
      "items": [
        {
          "id": 1,
          "name": "Cappuccino",
          "quantity": 2,
          "notes": "Extra spicy"
        }
      ],
      "created_at": "2026-03-31 12:00:00"
    }
  ]
}

Preparing Orders

GET /kitchen/preparing

Orders currently being prepared.

Response (200):

{
  "data": [...]
}

Ready Orders

GET /kitchen/ready

Orders ready for service/delivery.

Response (200):

{
  "data": [...]
}

Get Order Details

GET /kitchen/{id}

Response (200):

{
  "data": {
    "id": 101,
    "order_number": "ORD-2026-001",
    "items": [...],
    "notes": "Extra spicy",
    "created_at": "2026-03-31 12:00:00"
  }
}

Mark as Preparing

PATCH /kitchen/{id}/preparing

Response (200):

{
  "message": "Order marked as preparing",
  "data": {...}
}

Mark as Ready

PATCH /kitchen/{id}/ready

Response (200):

{
  "message": "Order marked as ready",
  "data": {...}
}

Reservations

List Reservations

GET /reservations?per_page=15&status=pending&from_date=2026-03-31

Query Parameters:

Response (200):

{
  "data": [
    {
      "id": 1,
      "customer_id": 1,
      "customer_name": "John Doe",
      "customer_phone": "9876543210",
      "table_id": 1,
      "table_name": "Table 1",
      "reservation_date": "2026-04-05",
      "reservation_time": "19:00",
      "guests_count": 4,
      "status": "confirmed",
      "special_requests": "Window seat preferred",
      "created_at": "2026-03-31 10:00:00",
      "checked_in_at": null
    }
  ]
}

Create Reservation

POST /reservations

Request:

{
  "customer_id": 1,
  "table_id": 1,
  "reservation_date": "2026-04-05",
  "reservation_time": "19:00",
  "guests_count": 4,
  "special_requests": "Window seat preferred"
}

Response (201):

{
  "message": "Reservation created successfully",
  "data": {...}
}

Get Upcoming Reservations

GET /reservations/upcoming?limit=10

Response (200):

{
  "data": [...]
}

Confirm Reservation

PATCH /reservations/{id}/confirm

Response (200):

{
  "message": "Reservation confirmed successfully",
  "data": {...}
}

Check-in Reservation

PATCH /reservations/{id}/check-in

Response (200):

{
  "message": "Reservation checked in successfully",
  "data": {
    ...
    "checked_in_at": "2026-04-05 19:05:00"
  }
}

Get Available Tables

GET /reservations/available-tables?date=2026-04-05&time=19:00&capacity=4

Response (200):

{
  "data": [
    {
      "id": 1,
      "name": "Table 1",
      "capacity": 4,
      "floor_name": "Ground Floor"
    }
  ]
}

Get Reservations Summary

GET /reservations/summary?date=2026-04-05

Response (200):

{
  "data": {
    "total_reservations": 12,
    "confirmed": 10,
    "pending": 2,
    "total_guests": 48
  }
}

Cancel Reservation

POST /reservations/{id}/cancel

Response (200):

{
  "message": "Reservation cancelled successfully",
  "data": {...}
}

Offers & Discounts

List Offers

GET /offers?per_page=15&status=active

Query Parameters:

Response (200):

{
  "data": [
    {
      "id": 1,
      "code": "SUMMER20",
      "title": "Summer Discount",
      "description": "20% off on all items",
      "discount_type": "percentage",
      "discount_value": 20,
      "start_date": "2026-03-01",
      "end_date": "2026-06-30",
      "minimum_order_amount": 500,
      "max_usage": 100,
      "usage_count": 45,
      "status": "active",
      "created_at": "2026-03-01 10:00:00"
    }
  ]
}

Create Offer

POST /offers

Request:

{
  "code": "SUMMER20",
  "title": "Summer Discount",
  "description": "20% off on all items",
  "discount_type": "percentage",
  "discount_value": 20,
  "start_date": "2026-03-01",
  "end_date": "2026-06-30",
  "minimum_order_amount": 500,
  "max_usage": 100,
  "status": "active"
}

Response (201):

{
  "message": "Offer created successfully",
  "data": {...}
}

Validate Offer Code

POST /offers/validate

Request:

{
  "code": "SUMMER20",
  "order_amount": 1000
}

Response (200):

{
  "success": true,
  "message": "Offer is valid",
  "data": {
    "code": "SUMMER20",
    "discount_value": 20,
    "discount_type": "percentage",
    "discount_amount": 200,
    "final_amount": 800
  }
}

Apply Offer

POST /offers/apply

Request:

{
  "code": "SUMMER20",
  "order_amount": 1000
}

Response (200):

{
  "message": "Offer applied successfully",
  "data": {
    "discount_amount": 200,
    "final_amount": 800
  }
}

Get Active Offers

GET /offers/active

Only active and valid offers.

Response (200):

{
  "data": [...]
}

Get Offer Statistics

GET /offers/{id}/statistics

Response (200):

{
  "data": {
    "total_usage": 45,
    "percentage_of_max": 45,
    "total_discount_given": 9000,
    "average_order_value": 1000
  }
}

Customers (CRM)

List Customers

GET /customers?per_page=15&search=john&tier=gold

Query Parameters:

Response (200):

{
  "data": [
    {
      "id": 1,
      "name": "John Doe",
      "email": "john@example.com",
      "phone": "9876543210",
      "address": "123 Main St",
      "city": "New York",
      "state": "NY",
      "postal_code": "10001",
      "date_of_birth": "1990-05-15",
      "gender": "male",
      "loyalty_points": 2500,
      "tier": "silver",
      "preferences": "Vegetarian options preferred",
      "status": "active",
      "created_at": "2026-01-15 10:00:00"
    }
  ],
  "pagination": {
    "current_page": 1,
    "total": 256
  }
}

Create Customer

POST /customers

Request:

{
  "name": "John Doe",
  "email": "john@example.com",
  "phone": "9876543210",
  "address": "123 Main St",
  "city": "New York",
  "state": "NY",
  "postal_code": "10001",
  "date_of_birth": "1990-05-15",
  "gender": "male",
  "preferences": "Vegetarian options preferred",
  "status": "active"
}

Response (201):

{
  "message": "Customer created successfully",
  "data": {...}
}

Get Customer

GET /customers/{id}

Response (200):

{
  "data": {...}
}

Update Customer

PUT /customers/{id}

Request:

{
  "name": "John Doe Updated",
  "preferences": "No spicy food"
}

Response (200):

{
  "message": "Customer updated successfully",
  "data": {...}
}

Search Customer

GET /customers/search?q=john

Response (200):

{
  "message": "Customers search results",
  "data": [...]
}

Get Customer by Phone

GET /customers/by-phone?phone=9876543210

Response (200):

{
  "data": {...}
}

Get Repeat Customers

GET /customers/repeat-customers?min_orders=2&limit=50

Customers with multiple orders.

Response (200):

{
  "message": "Repeat customers retrieved successfully",
  "data": [...]
}

Get Top Customers

GET /customers/top-customers?limit=20

Customers by spending.

Response (200):

{
  "message": "Top customers retrieved successfully",
  "data": [...]
}

Get Customers by Tier

GET /customers/tier/{tier}

Tier Values: bronze, silver, gold, vip

Response (200):

{
  "message": "Customers by tier retrieved successfully",
  "data": [...]
}

Get Customer Order History

GET /customers/{id}/orders?per_page=20

Response (200):

{
  "message": "Customer order history retrieved successfully",
  "data": [
    {
      "id": 101,
      "order_number": "ORD-2026-001",
      "total_amount": 531.00,
      "status": "completed",
      "created_at": "2026-03-30 12:00:00"
    }
  ]
}

Get Customer Payment History

GET /customers/{id}/payments?per_page=20

Response (200):

{
  "message": "Customer payment history retrieved successfully",
  "data": [
    {
      "id": 50,
      "amount": 531.00,
      "method": "card",
      "status": "completed",
      "paid_at": "2026-03-30 12:05:00"
    }
  ]
}

Get Customer Analytics

GET /customers/{id}/analytics

Response (200):

{
  "message": "Customer analytics retrieved successfully",
  "data": {
    "total_orders": 25,
    "total_spent": 12825.00,
    "average_order_value": 513.00,
    "first_order_date": "2026-01-15",
    "last_order_date": "2026-03-30",
    "items_ordered": 156
  }
}

Loyalty Points

List Loyalty Transactions

GET /loyalty?per_page=15&customer_id=1

Query Parameters:

Response (200):

{
  "message": "Loyalty transactions retrieved successfully",
  "data": [
    {
      "id": 1,
      "customer_id": 1,
      "customer_name": "John Doe",
      "order_id": 101,
      "payment_id": null,
      "points": 531,
      "type": "earn",
      "reason": "Order completed",
      "description": "Earned 531 points from order #101",
      "available_balance": 2531,
      "processed_at": "2026-03-30 12:05:00"
    }
  ],
  "pagination": {
    "current_page": 1,
    "total": 42
  }
}

Redeem Points

POST /loyalty/redeem

Request:

{
  "customer_id": 1,
  "points": 500,
  "reason": "Redeemed for discount"
}

Response (201):

{
  "message": "Points redeemed successfully",
  "data": {
    "transaction": {
      "id": 2,
      "points": -500,
      "type": "redeem",
      "available_balance": 2031
    },
    "new_balance": 2031,
    "tier": "silver"
  }
}

Adjust Points (Admin)

POST /loyalty/adjust

Request:

{
  "customer_id": 1,
  "adjustment": 100,
  "reason": "Promotional adjustment"
}

Response (201):

{
  "message": "Points adjusted successfully",
  "data": {
    "transaction": {...},
    "new_balance": 2131,
    "tier": "silver"
  }
}

Get Loyalty Summary

GET /loyalty/{customerId}/summary

Response (200):

{
  "message": "Loyalty summary retrieved successfully",
  "data": {
    "customer_id": 1,
    "current_balance": 2131,
    "tier": "silver",
    "total_earned": 3000,
    "total_redeemed": 900,
    "total_adjusted": 31,
    "transaction_count": 25
  }
}

Get Transactions by Type

GET /loyalty/{customerId}/type/{type}

Type Values: earn, redeem, adjust, expire

Response (200):

{
  "message": "Loyalty transactions retrieved successfully",
  "data": [...]
}

Get Customer Loyalty Details

GET /loyalty/customer/{customerId}

Response (200):

{
  "message": "Customer loyalty details retrieved successfully",
  "data": {
    "customer": {...},
    "loyalty_summary": {...}
  }
}

Payments

List Payments

GET /payments?per_page=15&status=completed&method=card&from_date=2026-03-01&to_date=2026-03-31

Query Parameters:

Response (200):

{
  "data": [
    {
      "id": 50,
      "order_id": 101,
      "customer_id": 1,
      "customer_name": "John Doe",
      "amount": 531.00,
      "method": "card",
      "status": "completed",
      "transaction_id": "TXN-12345",
      "reference_number": "REF-12345",
      "paid_at": "2026-03-30 12:05:00",
      "payment_method_name": "Credit Card",
      "created_at": "2026-03-30 12:00:00"
    }
  ],
  "pagination": {
    "current_page": 1,
    "total": 156
  }
}

Record Payment

POST /payments

Request:

{
  "order_id": 101,
  "amount": 531.00,
  "payment_method_id": 1,
  "transaction_id": "TXN-12345",
  "reference_number": "REF-12345",
  "notes": "Payment for order #101"
}

Response (201):

{
  "message": "Payment processed successfully",
  "data": {...}
}

Get Payment by Order

GET /payments/order/{orderId}/summary

Response (200):

{
  "data": {
    "order_id": 101,
    "order_total": 531.00,
    "total_paid": 531.00,
    "remaining_amount": 0,
    "payment_status": "completed",
    "payment_count": 1,
    "payments": [...]
  }
}

Get Customer Payments

GET /payments?customer_id=1

Response (200):

{
  "data": [...]
}

Get Payments by Method

GET /payments?method=card&per_page=20

Response (200):

{
  "data": [...]
}

Get Payments by Status

GET /payments?status=completed&per_page=20

Response (200):

{
  "data": [...]
}

Refund Payment

POST /payments/{id}/refund

Request:

{
  "reason": "Customer request"
}

Response (201):

{
  "message": "Payment refunded successfully",
  "data": {
    "original_payment": {...},
    "refund_payment": {...}
  }
}

Get Payment Summary

GET /payments/summary?days=7

Response (200):

{
  "data": {
    "total_revenue": 25000.00,
    "completed_count": 45,
    "average_transaction": 555.56,
    "revenue_by_method": [
      {
        "method": "Card",
        "total": 15000,
        "count": 30
      }
    ]
  }
}

Inventory Management

List Inventory Items

GET /inventory?per_page=15&search=flour&low_stock=true

Query Parameters:

Response (200):

{
  "data": [
    {
      "id": 1,
      "name": "Flour",
      "description": "All-purpose flour",
      "current_stock": 50,
      "minimum_stock": 100,
      "unit": "kg",
      "unit_price": 50.00,
      "stock_value": 2500.00,
      "reorder_level": 100,
      "supplier_id": 1,
      "status": "low_stock",
      "last_updated": "2026-03-31 10:00:00"
    }
  ]
}

Add Inventory

POST /inventory

Request:

{
  "name": "Flour",
  "description": "All-purpose flour",
  "current_stock": 500,
  "minimum_stock": 100,
  "unit": "kg",
  "unit_price": 50.00,
  "reorder_level": 100,
  "supplier_id": 1,
  "status": "in_stock"
}

Response (201):

{
  "message": "Inventory item added successfully",
  "data": {...}
}

Get Low Stock Items

GET /inventory/low-stock

Response (200):

{
  "data": [...]
}

Get Out of Stock Items

GET /inventory/out-of-stock

Response (200):

{
  "data": [...]
}

Update Inventory

PUT /inventory/{id}

Request:

{
  "current_stock": 300,
  "unit_price": 55.00
}

Response (200):

{
  "message": "Inventory updated successfully",
  "data": {...}
}

Get Inventory Summary

GET /inventory/summary

Response (200):

{
  "data": {
    "total_items": 45,
    "in_stock": 40,
    "low_stock": 4,
    "out_of_stock": 1,
    "total_value": 125000.00
  }
}

Suppliers & Purchases

List Suppliers

GET /suppliers?per_page=15&status=active

Response (200):

{
  "data": [
    {
      "id": 1,
      "name": "Fresh Produce Co",
      "contact_person": "Mr. Smith",
      "email": "supplier@example.com",
      "phone": "9876543210",
      "address": "123 Supplier St",
      "city": "Chicago",
      "payment_terms": "Net 30",
      "status": "active",
      "created_at": "2026-01-01 10:00:00"
    }
  ]
}

Create Supplier

POST /suppliers

Request:

{
  "name": "Fresh Produce Co",
  "contact_person": "Mr. Smith",
  "email": "supplier@example.com",
  "phone": "9876543210",
  "address": "123 Supplier St",
  "city": "Chicago",
  "payment_terms": "Net 30",
  "status": "active"
}

Response (201):

{
  "message": "Supplier created successfully",
  "data": {...}
}

List Purchases

GET /purchases?per_page=15&status=pending&from_date=2026-03-01&to_date=2026-03-31

Query Parameters:

Response (200):

{
  "data": [
    {
      "id": 1,
      "purchase_number": "PO-2026-001",
      "supplier_id": 1,
      "supplier_name": "Fresh Produce Co",
      "items_count": 5,
      "total_amount": 5000.00,
      "status": "pending",
      "expected_delivery": "2026-04-05",
      "created_at": "2026-03-31 10:00:00"
    }
  ]
}

Create Purchase Order

POST /purchases

Request:

{
  "supplier_id": 1,
  "items": [
    {
      "inventory_item_id": 1,
      "quantity": 100,
      "unit_price": 50.00
    }
  ],
  "expected_delivery": "2026-04-05",
  "notes": "Urgent order"
}

Response (201):

{
  "message": "Purchase order created successfully",
  "data": {...}
}

Get Pending Purchases

GET /purchases/pending

Response (200):

{
  "data": [...]
}

Confirm Purchase Order

POST /purchases/{id}/confirm

Response (200):

{
  "message": "Purchase order confirmed successfully",
  "data": {...}
}

Get Purchases by Supplier

GET /purchases/by-supplier/{supplierId}

Response (200):

{
  "data": [...]
}

Financial Reports

Profit & Loss Summary

GET /financial-reports/profit-and-loss?from_date=2026-03-01&to_date=2026-03-31

Response (200):

{
  "message": "Profit & Loss summary retrieved successfully",
  "data": {
    "period": {
      "from_date": "2026-03-01",
      "to_date": "2026-03-31"
    },
    "revenue": {
      "total": 125000.00,
      "formatted": "₹125000.00"
    },
    "expenses": {
      "total": 45000.00,
      "formatted": "₹45000.00"
    },
    "net_profit": {
      "total": 80000.00,
      "formatted": "₹80000.00"
    },
    "profit_margin": 64.00,
    "status": "profitable"
  }
}

Revenue by Payment Method

GET /financial-reports/revenue-by-method?from_date=2026-03-01&to_date=2026-03-31

Response (200):

{
  "message": "Revenue by payment method retrieved successfully",
  "data": [
    {
      "method": "Card",
      "total": 75000.00,
      "count": 150,
      "percentage": 60.00
    },
    {
      "method": "Cash",
      "total": 50000.00,
      "count": 100,
      "percentage": 40.00
    }
  ]
}

Daily Financial Summary

GET /financial-reports/daily-summary?date=2026-03-31

Response (200):

{
  "message": "Daily financial summary retrieved successfully",
  "data": {
    "date": "2026-03-31",
    "revenue": {
      "total": 5000.00,
      "formatted": "₹5000.00"
    },
    "expenses": {
      "total": 1500.00,
      "formatted": "₹1500.00"
    },
    "net_profit": {
      "total": 3500.00,
      "formatted": "₹3500.00"
    }
  }
}

Monthly Financial Summary

GET /financial-reports/monthly-summary?year=2026&month=3

Response (200):

{
  "message": "Monthly financial summary retrieved successfully",
  "data": {
    ...same as profit-and-loss...
  }
}

Branch-wise Profit Comparison (Admin Only)

GET /financial-reports/branch-comparison?from_date=2026-03-01&to_date=2026-03-31

Response (200):

{
  "message": "Branch-wise profit comparison retrieved successfully",
  "data": [
    {
      "branch_id": 1,
      "branch_name": "Main Branch",
      "revenue": 125000.00,
      "expenses": 45000.00,
      "net_profit": 80000.00,
      "profit_margin": 64.00
    }
  ]
}

Financial Dashboard

GET /financial-reports/dashboard?from_date=2026-03-01&to_date=2026-03-31

Complete financial overview.

Response (200):

{
  "message": "Financial dashboard retrieved successfully",
  "data": {
    "profit_and_loss": {...},
    "revenue_by_method": [...],
    "expense_summary": {
      "total_expenses": 45000.00,
      "formatted_total": "₹45000.00",
      "by_category": [
        {
          "category": "Salaries",
          "total": 20000.00,
          "count": 1
        }
      ]
    }
  }
}

Total Revenue

GET /financial-reports/total-revenue?from_date=2026-03-01&to_date=2026-03-31

Response (200):

{
  "message": "Total revenue retrieved successfully",
  "data": {
    "total": 125000.00,
    "formatted": "₹125000.00"
  }
}

Expense Summary

GET /financial-reports/expense-summary?from_date=2026-03-01&to_date=2026-03-31

Response (200):

{
  "message": "Expense summary retrieved successfully",
  "data": {
    "total_expenses": 45000.00,
    "formatted_total": "₹45000.00",
    "by_category": [
      {
        "category": "Salaries",
        "total": 20000.00,
        "count": 1
      },
      {
        "category": "Utilities",
        "total": 15000.00,
        "count": 3
      },
      {
        "category": "Rent",
        "total": 10000.00,
        "count": 1
      }
    ],
    "category_count": 3
  }
}

Expenses

List Expenses

GET /expenses?per_page=15&category=utilities&from_date=2026-03-01&to_date=2026-03-31

Query Parameters:

Response (200):

{
  "message": "Expenses retrieved successfully",
  "data": [
    {
      "id": 1,
      "branch_id": 1,
      "category": {
        "id": 1,
        "name": "Utilities",
        "slug": "utilities"
      },
      "title": "March Electricity Bill",
      "amount": 5000.00,
      "expense_date": "2026-03-31",
      "notes": "Monthly electricity",
      "receipt_url": "https://...",
      "created_by": "John Doe",
      "updated_by": null,
      "created_at": "2026-03-31 10:00:00"
    }
  ],
  "pagination": {
    "current_page": 1,
    "total": 45
  }
}

Add Expense

POST /expenses

Request:

{
  "expense_category_id": 1,
  "title": "March Electricity Bill",
  "amount": 5000,
  "expense_date": "2026-03-31",
  "notes": "Monthly electricity",
  "receipt_url": "https://..."
}

Response (201):

{
  "message": "Expense created successfully",
  "data": {...}
}

Update Expense

PUT /expenses/{id}

Request:

{
  "amount": 5200,
  "notes": "Updated electricity bill"
}

Response (200):

{
  "message": "Expense updated successfully",
  "data": {...}
}

Delete Expense

DELETE /expenses/{id}

Response (200):

{
  "message": "Expense deleted successfully"
}

Get Expense Summary

GET /expenses/summary?from_date=2026-03-01&to_date=2026-03-31

Response (200):

{
  "message": "Expense summary retrieved successfully",
  "data": {
    "total_expenses": 45000.00,
    "breakdown_by_category": [
      {
        "category": "Salaries",
        "total": 20000.00,
        "count": 1
      }
    ],
    "category_count": 5
  }
}

Get Daily Expense Totals

GET /expenses/daily-totals?from_date=2026-03-01&to_date=2026-03-31

Response (200):

{
  "message": "Daily expense totals retrieved successfully",
  "data": [
    {
      "date": "2026-03-31",
      "total": 1500.00
    }
  ]
}

Get Expenses by Category

GET /expenses/category/{category}?from_date=2026-03-01&to_date=2026-03-31

Response (200):

{
  "message": "Expenses by category retrieved successfully",
  "data": [...]
}

Error Responses

All endpoints may return the following error responses:

400 Bad Request

{
  "message": "Validation failed",
  "errors": {
    "email": ["Email field is required"],
    "amount": ["Amount must be greater than 0"]
  }
}

401 Unauthorized

{
  "message": "Unauthorized - Please login first"
}

403 Forbidden

{
  "message": "Forbidden - You don't have permission to access this resource"
}

404 Not Found

{
  "message": "Resource not found"
}

422 Unprocessable Entity

{
  "message": "Error processing request",
  "errors": {
    "field": ["Error message"]
  }
}

500 Internal Server Error

{
  "message": "Internal server error",
  "error": "Error details"
}

Rate Limiting


Support

For API support, contact: api-support@restaurant-rms.com


Version 1.0 | Last Updated: March 31, 2026