Dinlr Online Order API

1. Authorization

The Dinlr Online Order API allows authorization using the OAuth 2.0 standard. Currently, we only support the Authorization Code Grant.

1.1 OAuth 2.0

Before starting, create a Dinlr application. To do this follow the steps below:

Step 1. Register as a Partner

If you have not done this yet, register a partner account here: https://partners.dinlr.com

Step 2. Create a Dinlr Application

Once you sign in you can click on "Apps" located at the side menu, which will show you a list of your Applications. Now you are ready to create your first app.

As a result, this process will give you the client_id and the client_secret which are used to identify your applications and are therefore, required to complete the authorization process.

redirect_uri is the URL where you want to redirect the users after they authorize the client.

1.2 Connecting your application to a Dinlr Account

Implement the following steps to connect your application to a Dinlr account.

Step 1. Requesting Authorization Code

The restaurant needs to authorize your application to access their data. Send them the following URL so that they can authorize your application


https://backoffice.dinlr.com/oauth/authorize?client_id={client_id}&redirect_uri={redirect_uri}&state={state}

The redirect_uri must be identical to one of the Application Redirect URI.

Once the restaurant has authorized the application, Dinlr will send an authorization code and the restaurant id to the Redirect URI you set up with your application.


Successful Authorization Response
{redirect_uri}?code={code}&restaurant_id={restaurant_id}&state={state}

Declined Access Response
{redirect_uri}?error=access_denied

Before you proceed, make sure your application performs the following security checks. If any of the checks fails, your application must reject the request with an error, and must not proceed further.

  • Ensure the provided state is the same one that your application provided to Dinlr during Step 1. Requesting Authorization Code.

If all security check pass, the authorization code can be exchanged once for an access and a refresh token.

Step 2. Requesting an Access and a Refresh Token

Once you have the authorization code, your application can now request an access token and a refresh token.

The following data should be sent as "application/x-www-form-urlencoded" encoded body of a POST request.


POST Request
https://api.dinlr.com/v1/{restaurant_id}/oauth/token

Parameters
  • code
  • client_id
  • client_secret
  • grant_type - this is always authorization_code

Response
{
    "access_token": "{access_token}",
    "token_type": "bearer",
    "expires_in": 1209600,
    "refresh_token": "{refresh_token}"
}

Step 3. Using Access Token to access Dinlr Online Order API

Your application can use the received access token to interact with the Dinlr API on behalf of the restaurant by providing the access token in an Authorization header.


GET Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/restaurant

Header
Authorization: Bearer {access_token}

Step 4. Refreshing the Access Token

When the access token expires, your application can request a new access token using the refresh token received in Step 2. Requesting an Access and a Refresh Token.


POST Request
https://api.dinlr.com/v1/{restaurant_id}/oauth/token

Parameters
  • refresh_token
  • client_id
  • client_secret
  • grant_type - when refreshing tokens it should be refresh_token

Response
{
    "access_token": "{access_token}",
    "token_type": "bearer",
    "expires_in": 1209600,
    "refresh_token": "{refresh_token}"
}

1.3 Dinlr API Rate Limit

To ensure our platform remains stable and fair for everyone, some API endpoints are rate-limited.

Rate limit is set at per app per restaurant level. Multiple locations within the same restaurant share the same rate limits. Past the limit, the API will return a 429 Too Many Requests error.


API Endpoint Rate Limits
2.2 Retrieve all Locations GET ../locations 1 request/minute
2.3 Retrieve all Dining Options GET ../dining-options 10 request/minute
2.4 Retrieve all Payment Methods GET ../payments 10 request/minute
2.5 Retrieve all Charges GET ../charges 10 request/minute
3.1 Retrieve all Floorplans GET ../floorplans 10 request/minute
4.1 Retrieve all Items GET ../items 10 request/minute
4.2 Retrieve all Modifiers GET ../modifiers 10 request/minute
4.3 Retrieve all Categories GET ../categories 10 request/minute
5.1 Retrieve all Discounts GET ../discounts 10 request/minute
5.2 Retrieve all Promotions GET ../promotions 10 request/minute
6.1 Retrieve all Vouchers GET ../vouchers 10 requests/minute
6.4 Search Voucher GET ../vouchers/search 60 requests/minute
6.5 View Voucher GET ../vouchers/{voucher_id} 60 requests/minute
7.1 Retrieve all Menus GET ../menu 10 request/minute
8.1 Retrieve all Customers GET ../customers 10 requests/minute
8.4 Search Customers GET ../customers/search 60 requests/minute
8.5 View Customer GET ../customers/{customer_id} 60 requests/minute
8.6 Retrieve all Customer Groups GET ../customer-groups 10 request/minute
9.1 Retrieve all Loyalty Programs GET ../loyalty/programs 10 request/minute
9.2 Retrieve all Rewards GET ../loyalty/{loyalty_program_id}/rewards 10 request/minute
9.3 Retrieve all Members GET ../loyalty/{loyalty_program_id}/members 10 requests/minute
9.4 View Member GET ../loyalty/{loyalty_program_id}/members/{member_id} 60 requests/minute
9.7 Search Loyalty Transactions GET ../loyalty/{loyalty_program_id}/transactions/search 20 requests/minute
10.1 Retrieve Customer Store Credit GET ../store-credit/customers/{customer_id} 60 requests/minute
10.3 Search Store Credit Transactions GET ../store-credit/transactions/search 20 requests/minute
12.1 List Order GET ../orders?location_id={location_id} 10 requests/minute
12.2 View Order GET ../orders/{order_id} 30 requests/minute
13.1 Retrieve all Experiences GET ../experiences 10 request/minute
13.2 Retrieve all Table Sections GET ../table-sections 10 request/minute
13.5 List Reservation GET ../reservations?location_id={location_id} 10 requests/minute
13.6 View Reservation GET ../reservations/{reservation_id} 30 requests/minute
14.1 Retrieve all Materials GET ../materials 10 request/minute
14.2 Get Stock Level of all Materials GET ../material-stocks?location_id={location_id} 10 requests/minute
14.3 Retrieve all Stock Takes GET ../stock-takes?location_id={location_id} 10 requests/minute

Avoiding Rate Limit Errors

Design your app with best practices in mind is the best way to avoid throttling errors. For example, you can stagger API requests in queue and do other processing tasks while waiting for the next queued job to run. Consider the following best practices when designing your app:

  • Optimize your code to only get the data that your app requires.
  • Use caching for data that your app uses often.
  • Regulate the rate of your requests for smoother distribution.
  • Include code that catches errors. If you ignore these errors and keep trying to make requests, then your app won't be able to gracefully recover.
  • Your code should stop making additional API requests until enough time has passed to retry. The recommended backoff time is one second.

2. Restaurant Settings

2.1 View Restaurant

Returns details for the restaurant.


GET Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/restaurant

Header
Authorization: Bearer {access_token}

Response
{
    "data": {
        "id": "{restaurant_id}",
        "name": "Amber Burger House",
        "currency": "USD", - ISO currency code
        "updated_at": "2018-03-08T13:00:00+08:00"
    }
}

2.2 Retrieve all Locations

Returns a list of all locations of the restaurant.


GET Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/locations

URL Parameters
  • limit - Return up to this many results per page (default: 50) (max: 200)
  • page - Return a specific page of results (default: 1)
  • update_at_min - Show locations last updated after date (Remember to escape + sign with %2B, because + is not allowed to be used in URL)

Header
Authorization: Bearer {access_token}

Response
{
    "data": [
        {
            "id": "{location_id}",
            "name": "Chinatown",
            "updated_at": "2018-03-08T13:00:00+08:00"
        },
        {
            "id": "{location_id}",
            "name": "New York",
            "updated_at": "2018-03-08T13:00:00+08:00"
        },
        {
            "id": "{location_id}",
            "name": "Pop-up Event",
            "updated_at": "2018-03-08T13:00:00+08:00"
        }
    ]
}

2.3 Retrieve all Dining Options

Returns a list of all dining options of the location.


GET Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/dining-options?location_id={location_id}

URL Parameters
  • location_id
  • limit - Return up to this many results per page (default: 50) (max: 200)
  • page - Return a specific page of results (default: 1)
  • update_at_min - Show dining options last updated after date (Remember to escape + sign with %2B, because + is not allowed to be used in URL)

Header
Authorization: Bearer {access_token}

Response
{
    "data": [
        {
            "id": "{dining_option_id}",
            "name": "Dine-in",
            "sort": 0,
            "updated_at": "2018-03-08T13:00:00+08:00"
        },
        {
            "id": "{dining_option_id}",
            "name": "Takeaway",
            "sort": 1,
            "updated_at": "2018-03-08T13:00:00+08:00"
        },
        {
            "id": "{dining_option_id}",
            "name": "Delivery",
            "sort": 2,
            "updated_at": "2018-03-08T13:00:00+08:00"
        }
    ]
}

2.4 Retrieve all Payment Methods

Returns a list of all payment methods of the location.


GET Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/payments?location_id={location_id}

URL Parameters
  • location_id
  • limit - Return up to this many results per page (default: 50) (max: 200)
  • page - Return a specific page of results (default: 1)
  • update_at_min - Show payment methods last updated after date (Remember to escape + sign with %2B, because + is not allowed to be used in URL)

Header
Authorization: Bearer {access_token}

Response
{
    "data": [
        {
            "id": "{payment_id}",
            "name": "Cash",
            "sort": 0,
            "updated_at": "2018-03-08T13:00:00+08:00",
            "payment_inputs": [ - list of additional inputs for this payment method
            ]
        },
        {
            "id": "{payment_id}",
            "name": "Credit Card",
            "sort": 1,
            "updated_at": "2018-03-08T13:00:00+08:00",
            "payment_inputs": [
                {
                    "id": "{payment_input_id}",
                    "name": "Card Last 4 Digit",
                    "sort": 0
                }
            ]
        },
        {
            "id": "{payment_id}",
            "name": "Voucher",
            "sort": 2,
            "updated_at": "2018-03-08T13:00:00+08:00",
            "payment_inputs": [
                {
                    "id": "{payment_input_id}",
                    "name": "Voucher No",
                    "sort": 0
                },
                {
                    "id": "{dining_option_id}",
                    "name": "Voucher Color Code",
                    "sort": 1
                }
            ]
        }
    ]
}

2.5 Retrieve all Charges

Returns a list of all charges of the location.


GET Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/charges?location_id={location_id}

URL Parameters
  • location_id
  • limit - Return up to this many results per page (default: 50) (max: 200)
  • page - Return a specific page of results (default: 1)
  • update_at_min - Show charges last updated after date (Remember to escape + sign with %2B, because + is not allowed to be used in URL)

Header
Authorization: Bearer {access_token}

Response
{
    "data": [
        {
            "id": "{charge_id}",
            "name": "Service Charge",
            "updated_at": "2018-03-08T13:00:00+08:00",
            "dining_options": [ - list of dining options that apply this charge
                {
                    "id": "{dining_option_id}"
                },
                {
                    "id": "{dining_option_id}"
                }
            ]
        },
        {
            "id": "{charge_id}",
            "name": "Takeaway Charge",
            "updated_at": "2018-03-08T13:00:00+08:00",
            "dining_options": [ - list of dining options that apply this charge
                {
                    "id": "{dining_option_id}"
                }
            ]
        },
        {
            "id": "{charge_id}",
            "name": "Delivery Fee",
            "updated_at": "2018-03-08T13:00:00+08:00",
            "dining_options": [ - list of dining options that apply this charge
                {
                    "id": "{dining_option_id}"
                },
                {
                    "id": "{dining_option_id}"
                },
                {
                    "id": "{dining_option_id}"
                }
            ]
        }
    ]
}

2.6 Retrieve Restaurant Settings (Depreciated)

This endpoint has been depreciated, these data will be accessible from their new endpoints.


GET Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/get-settings

Header
Authorization: Bearer {access_token}

Response
{
    "data": {
        "locations": [ (Depreciated) (Location data moved to 2.2 Retrieve all Locations)
            {
                "id": "{location_id}",
                "name": "Chinatown"
            },
            {
                "id": "{location_id}",
                "name": "New York"
            }
        ],
        "dining_options": [ (Depreciated) (Dining option data moved to 2.3 Retrieve all Dining Options)
            {
                "id": "{dining_option_id}",
                "name": "Dine-in",
                "sort": 0
            },
            {
                "id": "{dining_option_id}",
                "name": "Takeaway",
                "sort": 1
            },
            {
                "id": "{dining_option_id}",
                "name": "Delivery",
                "sort": 2
            }
        ],
        "payments": [ (Depreciated) (Payment data moved to 2.4 Retrieve all Payment Methods)
            {
                "id": "{payment_id}",
                "name": "Cash",
                "sort": 0
            },
            {
                "id": "{payment_id}",
                "name": "Visa",
                "sort": 1
            },
            {
                "id": "{payment_id}",
                "name": "Mastercard",
                "sort": 2
            }
        ],
        "categories": [ (Depreciated) (Category data moved to 4.3 Retrieve all Categories)
            {
                "id": "{category_id}",
                "name": "Food",
                "sub_categories": [
                    {
                        "id": "{category_id}",
                        "name": "Burger"
                    },
                    {
                        "id": "{category_id}",
                        "name": "Sides"
                    }
                ]
            },
            {
                "id": "{category_id}",
                "name": "Drinks",
                "sub_categories": [
                ]
            }
        ],
        "modifiers": [ (Depreciated) (Modifier data moved to 4.2 Retrieve all Modifiers)
            {
                "id": "{modifier_id}",
                "name": "Ice Level",
                "min_selection": 0, - null represents optional
                "max_selection": 1, - null represents unlimited
                "sort": 0,
                "modifier_options": [
                    {
                        "id": "{modifier_option_id}",
                        "name": "No Ice",
                        "price": 1,
                        "max_qty": 1,
                        "default_selected": false,
                        "show_in_menu": true,
                        "sort": 0
                    },
                    {
                        "id": "{modifier_option_id}",
                        "name": "Less Ice",
                        "price": 0.5,
                        "max_qty": 1,
                        "default_selected": false,
                        "show_in_menu": true,
                        "sort": 1
                    },
                    {
                        "id": "{modifier_option_id}",
                        "name": "More Ice",
                        "price": 0,
                        "max_qty": 1,
                        "default_selected": false,
                        "show_in_menu": true,
                        "sort": 2
                    }
                ]
            },
            {
                "id": "{modifier_id}",
                "name": "Steak Doneness",
                "min_selection": 1, - null represents optional
                "max_selection": 1, - null represents unlimited
                "sort": 1,
                "modifier_options": [
                    {
                        "id": "{modifier_option_id}",
                        "name": "Medium Rare",
                        "price": 0,
                        "max_qty": 1,
                        "default_selected": true,
                        "show_in_menu": true,
                        "sort": 0
                    },
                    {
                        "id": "{modifier_option_id}",
                        "name": "Medium",
                        "price": 0,
                        "max_qty": 1,
                        "default_selected": false,
                        "show_in_menu": true,
                        "sort": 1
                    },
                    {
                        "id": "{modifier_option_id}",
                        "name": "Well Done",
                        "price": 0,
                        "max_qty": 1,
                        "default_selected": false,
                        "show_in_menu": true,
                        "sort": 2
                    }
                ]
            }
        ],
        "charges": [ (Depreciated) (Charge data moved to 2.5 Retrieve all Charges)
            {
                "id": "{charge_id}",
                "name": "Service Charge",
                "dining_options": [ - list of dining options that apply this charge
                    "{dining_option_id}",
                    "{dining_option_id}"
                ]
            },
            {
                "id": "{charge_id}",
                "name": "Takeaway Charge",
                "dining_options": [ - list of dining options that apply this charge
                    "{dining_option_id}"
                ]
            },
            {
                "id": "{charge_id}",
                "name": "Delivery Fee",
                "dining_options": [ - list of dining options that apply this charge
                    "{dining_option_id}"
                ]
            }
        ],
        "customer_groups": [ (Depreciated) (Customer group data moved to 8.5 Retrieve all Customer Groups)
            {
                "id": "{customer_group_id}",
                "name": "Bronze Member"
            },
            {
                "id": "{customer_group_id}",
                "name": "Gold Member"
            },
            {
                "id": "{customer_group_id}",
                "name": "VVIP"
            }
        ]
    }
}

3. Floorplans

3.1 Retrieve all Floorplans

Returns a list of all floorplans of the location.


GET Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/floorplans?location_id={location_id}

URL Parameters
  • location_id
  • limit - Return up to this many results per page (default: 50) (max: 200)
  • page - Return a specific page of results (default: 1)
  • update_at_min - Show floorplans last updated after date (Remember to escape + sign with %2B, because + is not allowed to be used in URL)

Header
Authorization: Bearer {access_token}

Response
{
    "data": [
        {
            "id": "{floorplan_id}",
            "name": "Main Dining Hall",
            "sort": 0,
            "updated_at": "2018-03-08T13:00:00+08:00",
            "objects": [
                {
                    "id": "{object_id}",
                    "name": "Table 1",
                    "pax": 4
                },
                {
                    "id": "{object_id}",
                    "name": "Table 2",
                    "pax": 4
                },
                {
                    "id": "{object_id}",
                    "name": "Bar Seat 1",
                    "pax": 1
                }
            ]
        },
        {
            "id": "{floorplan_id}",
            "name": "Balcony",
            "sort": 1,
            "updated_at": "2018-03-08T13:00:00+08:00",
            "objects": [
                {
                    "id": "{object_id}",
                    "name": "B10",
                    "pax": 2
                },
                {
                    "id": "{object_id}",
                    "name": "B11",
                    "pax": 2
                },
                {
                    "id": "{object_id}",
                    "name": "B12",
                    "pax": 2
                }
            ]
        }
    ]
}

4. Items

4.1 Retrieve all Items

Returns a list of all items of the location.


GET Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/items?location_id={location_id}

URL Parameters
  • location_id
  • limit - Return up to this many results per page (default: 50) (max: 200)
  • page - Return a specific page of results (default: 1)
  • update_at_min - Show items last updated after date (Remember to escape + sign with %2B, because + is not allowed to be used in URL)

Header
Authorization: Bearer {access_token}

Response
{
    "data": [
        {
            "id": "{item_id}",
            "item_no": "A1",
            "name": "Chargrilled Chicken Burger",
            "description": "Grilled chicken with BBQ sauce", - optional, max 100 characters
            "image": "https://cdn.dinlr.com/......jpg", - optional
            "category": "{category_id}",
            "updated_at": "2018-03-08T13:00:00+08:00",
            "variants": [
                {
                    "id": "{variant_id}",
                    "name": "Regular",
                    "sku": "CKREG",
                    "summary": null,
                    "price": 9.5,
                    "show_in_menu": true,
                    "sort": 0
                },
                {
                    "id": "{variant_id}",
                    "name": "Large",
                    "sku": "CKLAR",
                    "summary": "Good for 2-3 pax",
                    "price": 12.5,
                    "show_in_menu": true,
                    "sort": 1
                },
                {
                    "id": "{variant_id}",
                    "name": "Open Price",
                    "sku": null,
                    "summary": null,
                    "show_in_menu": false,
                    "sort": 2
                }
            ],
            "modifiers": [
                {
                    "id": "{modifier_id}"
                },
                {
                    "id": "{modifier_id}"
                }
            ]
        },
        {
            "id": "{item_id}",
            "item_no": null,
            "name": "Cheesecake",
            "description": null,
            "image": null,
            "category": "{category_id}",
            "updated_at": "2018-03-08T13:00:00+08:00",
            "variants": [
                {
                    "id": "{variant_id}",
                    "name": "Blueberry",
                    "sku": "CCBLUE",
                    "summary": "Fresh from Australia",
                    "price": 3.5,
                    "show_in_menu": true,
                    "sort": 0
                },
                {
                    "id": "{variant_id}",
                    "name": Oreo,
                    "sku": "CCOREO",
                    "summary": null,
                    "price": 4.5,
                    "show_in_menu": true,
                    "sort": 1
                }
            ],
            "modifiers": [
            ]
        }
    ]
}

4.2 Retrieve all Modifiers

Returns a list of all modifiers of the location.


GET Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/modifiers?location_id={location_id}

URL Parameters
  • location_id
  • limit - Return up to this many results per page (default: 50) (max: 200)
  • page - Return a specific page of results (default: 1)
  • update_at_min - Show modifiers last updated after date (Remember to escape + sign with %2B, because + is not allowed to be used in URL)

Header
Authorization: Bearer {access_token}

Response
{
    "data": [
        {
            "id": "{modifier_id}",
            "name": "Ice Level",
            "min_selection": 0, - null represents optional
            "max_selection": 1, - null represents unlimited
            "sort": 0,
            "updated_at": "2018-03-08T13:00:00+08:00",
            "modifier_options": [
                {
                    "id": "{modifier_option_id}",
                    "name": "No Ice",
                    "sku": null,
                    "summary": null,
                    "price": 1,
                    "max_qty": 1,
                    "default_selected": false,
                    "show_in_menu": true,
                    "sort": 0
                },
                {
                    "id": "{modifier_option_id}",
                    "name": "Less Ice",
                    "sku": "LESICE",
                    "summary": null,
                    "price": 0.5,
                    "max_qty": 1,
                    "default_selected": false,
                    "show_in_menu": true,
                    "sort": 1
                },
                {
                    "id": "{modifier_option_id}",
                    "name": "More Ice",
                    "sku": "MORICE",
                    "summary": "Filled to brim",
                    "price": 0,
                    "max_qty": 1,
                    "default_selected": false,
                    "show_in_menu": true,
                    "sort": 2
                }
            ]
        },
        {
            "id": "{modifier_id}",
            "name": "Steak Doneness",
            "min_selection": 1, - null represents optional
            "max_selection": 1, - null represents unlimited
            "sort": 1,
            "updated_at": "2018-03-08T13:00:00+08:00",
            "modifier_options": [
                {
                    "id": "{modifier_option_id}",
                    "name": "Medium Rare",
                    "sku": null,
                    "summary": null,
                    "price": 0,
                    "max_qty": 1,
                    "default_selected": true,
                    "show_in_menu": true,
                    "sort": 0
                },
                {
                    "id": "{modifier_option_id}",
                    "name": "Medium",
                    "sku": null,
                    "summary": "Recommended",
                    "price": 0,
                    "max_qty": 1,
                    "default_selected": false,
                    "show_in_menu": true,
                    "sort": 1
                },
                {
                    "id": "{modifier_option_id}",
                    "name": "Well Done",
                    "sku": null,
                    "summary": "Not Recommended",
                    "price": 0,
                    "max_qty": 1,
                    "default_selected": false,
                    "show_in_menu": true,
                    "sort": 2
                }
            ]
        }
    ]
}

4.3 Retrieve all Categories

Returns a list of all categories of the restaurant.


GET Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/categories

URL Parameters
  • limit - Return up to this many results per page (default: 50) (max: 200)
  • page - Return a specific page of results (default: 1)
  • update_at_min - Show modifiers last updated after date (Remember to escape + sign with %2B, because + is not allowed to be used in URL)

Header
Authorization: Bearer {access_token}

Response
{
    "data": [
        {
            "id": "{category_id}",
            "name": "Food",
            "parent_category": "{category_id}",
            "updated_at": "2018-03-08T13:00:00+08:00"
        },
        {
            "id": "{category_id}",
            "name": "Sides",
            "parent_category": "{category_id}",
            "updated_at": "2018-03-08T13:00:00+08:00"
        },
        {
            "id": "{category_id}",
            "name": "Drinks",
            "parent_category": "{category_id}",
            "updated_at": "2018-03-08T13:00:00+08:00"
        }
    ]
}

5. Discounts & Promotions

5.1 Retrieve all Discounts

Returns a list of all discounts of the location.


GET Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/discounts?location_id={location_id}

URL Parameters
  • location_id
  • limit - Return up to this many results per page (default: 50) (max: 200)
  • page - Return a specific page of results (default: 1)
  • update_at_min - Show discounts last updated after date (Remember to escape + sign with %2B, because + is not allowed to be used in URL)

Header
Authorization: Bearer {access_token}

Response
{
    "data": [
        {
            "id": "{discount_id}",
            "name": "Staff Discount",
            "type": "percent", - Can be either "percent" or "price" discount
            "stackable": false,
            "manufacturer_discount": false, - Manufacturer discount will be applied after charges and taxes
            "value": 30, - Since discount type is percent, it is 30% discount. If value is null, it means it is an open discount and value can be custom defined.
            "max_value": 5.50, - Max discount applicable is $5.50. If value is null, it means there's no limit to the discount applicable.
            "updated_at": "2018-03-08T13:00:00+08:00"
        },
        {
            "id": "{discount_id}",
            "name": "VIP Discount",
            "type": "percent",
            "stackable": true,
            "manufacturer_discount": false,
            "value": 15,
            "max_value": null,
            "updated_at": "2018-03-08T13:00:00+08:00"
        },
        {
            "id": "{discount_id}",
            "name": "First-Timer Discount",
            "type": "price",
            "stackable": true,
            "manufacturer_discount": true,
            "value": 15, - Since discount type is price, it is a $15 discount
            "max_value": null,
            "updated_at": "2018-03-08T13:00:00+08:00"
        },
        {
            "id": "{discount_id}",
            "name": "Open Discount",
            "type": "price",
            "stackable": false,
            "manufacturer_discount": false,
            "value": null, - Open discount, value can be defined later during 11.1 Cart Summary, 11.2 Place Order or 12.3 Update Order
            "max_value": null,
            "updated_at": "2018-03-08T13:00:00+08:00"
        }
    ]
}

5.2 Retrieve all Promotions

Returns a list of all promotions of the location.


GET Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/promotions?location_id={location_id}

URL Parameters
  • location_id
  • limit - Return up to this many results per page (default: 50) (max: 200)
  • page - Return a specific page of results (default: 1)
  • update_at_min - Show promotions last updated after date (Remember to escape + sign with %2B, because + is not allowed to be used in URL)

Header
Authorization: Bearer {access_token}

Response
{
    "data": [
        {
            "id": "{promotion_id}",
            "name": "Buy 1 Get 1 Bread Free",
            "summary": "Fill your tummies, buy any of our bakery and get 1 free all day long!",
            "type": "auto", - Can be either "auto" or "voucher" promotion
            "start_date": "2020-07-10T06:00:00+00:00", - ISO 8601 date
            "end_date": "2020-07-10T06:30:00+00:00", - optional, ISO 8601 date
            "updated_at": "2018-03-08T13:00:00+08:00"
        },
        {
            "id": "{promotion_id}",
            "name": "30% Off Sides During Lunch",
            "summary": "All sides will be 10% off during lunch hours (12pm-3pm)",
            "type": "auto",
            "start_date": "2020-07-10T06:00:00+00:00",
            "end_date": null, - null represents no end date
            "updated_at": "2018-03-08T13:00:00+08:00"
        },
        {
            "id": "{promotion_id}",
            "name": "10% Off Mains",
            "summary": "10% off mains for voucher user only",
            "type": "voucher",
            "start_date": "2020-07-10T06:00:00+00:00",
            "end_date": "2020-07-10T06:30:00+00:00",
            "updated_at": "2018-03-08T13:00:00+08:00"
        }
    ]
}

6. Vouchers

6.1 Retrieve all Vouchers

Returns a list of all vouchers of the restaurant.


GET Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/vouchers

URL Parameters
  • limit - Return up to this many results per page (default: 50) (max: 200)
  • page - Return a specific page of results (default: 1)
  • update_at_min - Show vouchers last updated after date (Remember to escape + sign with %2B, because + is not allowed to be used in URL)

Header
Authorization: Bearer {access_token}

Response
{
    "data": [
        {
            "id": "{voucher_id}",
            "voucher_code": "XMAS20", - alphanumeric, no spaces, max 50 characters, unique
            "applicable": null,
            "type": "discount", - Can be either "discount" or "promotion" voucher
            "discount": "{discount_id}",
            "promotion": null,
            "customer": null,
            "redeemed": 0,
            "max_redemptions": null, - null represents unlimited
            "start_date": "2020-07-10T06:00:00+00:00", - ISO 8601 date
            "end_date": "2020-07-10T06:30:00+00:00", - optional, ISO 8601 date
            "updated_at": "2018-03-08T13:00:00+08:00"
        },
        {
            "id": "{voucher_id}",
            "voucher_code": "1FOR1DRINK",
            "applicable": null,
            "type": "promotion",
            "discount": null,
            "promotion": "{promotion_id}",
            "customer": null,
            "redeemed": 187,
            "max_redemptions": 200,
            "start_date": "2020-07-10T06:00:00+00:00",
            "end_date": null, - null represents no end date
            "updated_at": "2018-03-08T13:00:00+08:00"
        },
        {
            "id": "{voucher_id}",
            "voucher_code": "F82FENQ2",
            "applicable": "customer",
            "type": "promotion",
            "discount": null,
            "promotion": "{promotion_id}",
            "customer": "{customer_id}",
            "redeemed": 1,
            "max_redemptions": 1,
            "start_date": "2020-07-10T06:00:00+00:00",
            "end_date": "2020-07-10T06:30:00+00:00",
            "updated_at": "2018-03-08T13:00:00+08:00"
        }
    ]
}

6.2 Create Voucher

Creates a new voucher for the restaurant.


POST Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/vouchers

Header
Authorization: Bearer {access_token}

Parameters
{
    "voucher_code": "XMAS20",
    "applicable": null, - optional, can be "customer" voucher (Customer voucher can only be used by that specific customer)
    "type": "discount",
    "discount": "{discount_id}", - optional, only required if type is discount
    "promotion": "{promotion_id}", - optional, only required if type is promotion
    "customer": "{customer_id}", - optional, only required if applicable is customer
    "max_redemptions": 1, - optional
    "start_date": "2020-07-10T06:00:00+00:00", - ISO 8601 date
    "end_date": "2020-07-10T06:30:00+00:00", - optional, ISO 8601 date
}

Response
Same response as 6.5 View Voucher

6.3 Update Voucher

Updates a voucher of the restaurant.


PUT Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/vouchers/{voucher_id}

Header
Authorization: Bearer {access_token}

Parameters
{
    "voucher_code": "XMAS20",
    "applicable": null, - optional, can be "customer" voucher (Customer voucher can only be used by that specific customer)
    "type": "discount",
    "discount": "{discount_id}", - optional, only required if type is discount
    "promotion": "{promotion_id}", - optional, only required if type is promotion
    "customer": "{customer_id}", - optional, only required if applicable is customer
    "max_redemptions": 1, - optional
    "start_date": "2020-07-10T06:00:00+00:00", - ISO 8601 date
    "end_date": "2020-07-10T06:30:00+00:00", - optional, ISO 8601 date
}

Response
Same response as 6.5 View Voucher

6.4 Search Voucher

Searches for vouchers of the restaurant.


GET Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/vouchers/search

URL Parameters
  • voucher_code - Show vouchers associated with the voucher code
  • customer_id - Show vouchers associated with the customer
  • limit - Return up to this many results per page (default: 50) (max: 200)
  • page - Return a specific page of results (default: 1)
  • update_at_min - Show vouchers last updated after date (Remember to escape + sign with %2B, because + is not allowed to be used in URL)

Header
Authorization: Bearer {access_token}

Response
Same response as 6.1 Retrieve all Vouchers

6.5 View Voucher

Returns details for a single voucher of the restaurant.


GET Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/vouchers/{voucher_id}

Header
Authorization: Bearer {access_token}

Response
{
    "data": {
        "id": "{voucher_id}",
        "voucher_code": "XMAS20",
        "applicable": null,
        "type": "discount",
        "discount": "{discount_id}", - optional
        "promotion": "{promotion_id}", - optional
        "customer": "{customer_id}", - optional
        "redeemed": 0,
        "max_redemptions": 1, - null represents unlimited
        "start_date": "2020-07-10T06:00:00+00:00", - ISO 8601 date
        "end_date": "2020-07-10T06:30:00+00:00", - optional, ISO 8601 date
        "updated_at": "2018-03-08T13:00:00+08:00"
    }
}

7. Online Menu

7.1 Retrieve all Menus

Returns a list of all menus of the location including the item data.


GET Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/menu?location_id={location_id}

Header
Authorization: Bearer {access_token}

Response
{
    "data": {
        "menus": [
            {
                "id": "{menu_id}",
                "name": "All-Day Promotion Menu",
                "sort": 0,
                "items": [
                    {
                        "id": "{item_id}",
                        "item_no": "A1",
                        "name": "Chargrilled Chicken Burger",
                        "description": "Grilled chicken with BBQ sauce", - optional, max 100 characters
                        "sort": 0,
                        "image": "https://cdn.dinlr.com/......jpg", - optional
                        "category": "{category_id}",
                        "variants": [
                            {
                                "id": "{variant_id}",
                                "name": "Regular",
                                "sku": "CKREG",
                                "summary": null,
                                "price": 9.5,
                                "show_in_menu": true,
                                "sort": 0
                            },
                            {
                                "id": "{variant_id}",
                                "name": "Large",
                                "sku": "CKLAR",
                                "summary": "Good for 2-3 pax",
                                "price": 12.5,
                                "show_in_menu": true,
                                "sort": 1
                            },
                            {
                                "id": "{variant_id}",
                                "name": "Open Price",
                                "sku": null,
                                "summary": null,
                                "show_in_menu": false,
                                "sort": 2
                            }
                        ],
                        "modifiers": [
                            {
                                "id": "{modifier_id}"
                            }
                        ]
                    },
                    {
                        "id": "{item_id}",
                        "item_no": null,
                        "name": "Cheesecake",
                        "description": null,
                        "sort": 1,
                        "image": null,
                        "category": "{category_id}",
                        "variants": [
                            {
                                "id": "{variant_id}",
                                "name": "Blueberry",
                                "sku": "CCBLUE",
                                "summary": "Fresh from Australia",
                                "price": 3.5,
                                "show_in_menu": true,
                                "sort": 0
                            },
                            {
                                "id": "{variant_id}",
                                "name": "Oreo",
                                "sku": "CCOREO",
                                "summary": null,
                                "price": 4.5,
                                "show_in_menu": true,
                                "sort": 1
                            }
                        ],
                        "modifiers": [
                        ]
                    }
                ],
                "times": [
                    {
                        "day": "Monday",
                        "start_time": "11:00",
                        "end_time": "22:00"
                    },
                    {
                        "day": "Tuesday",
                        "start_time": "11:00",
                        "end_time": "22:00"
                    },
                    {
                        "day": "Wednesday",
                        "start_time": "11:00",
                        "end_time": "22:00"
                    },
                    {
                        "day": "Thursday",
                        "start_time": "11:00",
                        "end_time": "22:00"
                    },
                    {
                        "day": "Friday",
                        "start_time": "11:00",
                        "end_time": "23:30"
                    },
                    {
                        "day": "Saturday",
                        "start_time": "11:00",
                        "end_time": "23:30"
                    },
                    {
                        "day": "Sunday",
                        "start_time": "11:00",
                        "end_time": "23:30"
                    }
                ]
            }
        ]
    }
}

8. Customers

8.1 Retrieve all Customers

Returns a list of all customers of the restaurant.


GET Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/customers

URL Parameters
  • limit - Return up to this many results per page (default: 50) (max: 200)
  • page - Return a specific page of results (default: 1)
  • update_at_min - Show customers last updated after date (Remember to escape + sign with %2B, because + is not allowed to be used in URL)

Header
Authorization: Bearer {access_token}

Response
{
    "data": [
        {
            "id": "{customer_id}",
            "reference": "A144516982", - optional, max 50 characters
            "first_name": "Mark", - optional, max 50 characters
            "last_name": "Clinton", - optional, max 50 characters
            "company_name": "Dinlr", - optional, max 50 characters
            "email": "[email protected]", - optional, max 50 characters
            "phone": "+6511221122", - optional, max 50 characters
            "dob": "1960-06-22", - optional, format is YYYY-mm-dd
            "gender": "M", - optional
            "address1": "10 Kaki Bukit Ave 4", - optional, max 100 characters
            "address2": "#05-73", - optional, max 100 characters
            "city": "Singapore", - optional, max 100 characters
            "country": "SG", - optional, Alpha-2 country code
            "postal": "415874", - optional, max 50 characters
            "notes": "Allergic to peanuts", - optional, max 200 characters
            "marketing_consent_email": true,
            "marketing_consent_text": true,
            "marketing_consent_phone": false,
            "customer_group": "{customer_group_id}",
            "updated_at": "2018-03-08T13:00:00+08:00"
        },
        {
            "id": "{customer_id}",
            "reference": null,
            "first_name": "Jamie",
            "last_name": null,
            "company_name": null,
            "email": "[email protected]",
            "phone": null,
            "dob": null,
            "gender": "F",
            "address1": null,
            "address2": null,
            "city": null,
            "country": null,
            "postal": null,
            "notes": null,
            "marketing_consent_email": false,
            "marketing_consent_text": false,
            "marketing_consent_phone": false,
            "customer_group": "{customer_group_id}",
            "updated_at": "2018-03-08T13:00:00+08:00"
        }
    ]
}

8.2 Create Customer

Creates a new customer for the restaurant.

To create a new customer, you must provide at least one of the following values in your request:

  • reference
  • first_name
  • last_name


POST Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/customers

Header
Authorization: Bearer {access_token}

Parameters
{
    "reference": "A144516982", - optional, max 50 characters
    "first_name": "Mark", - optional, max 50 characters
    "last_name": "Clinton", - optional, max 50 characters
    "company_name": "Dinlr", - optional, max 50 characters
    "email": "[email protected]", - optional, max 50 characters
    "phone": "+6511221122", - optional, max 50 characters
    "dob": "1960-06-22", - optional, format is YYYY-mm-dd
    "gender": "F", - optional
    "address1": "10 Kaki Bukit Ave 4", - optional, max 100 characters
    "address2": "#05-73", - optional, max 100 characters
    "city": "Singapore", - optional, max 100 characters
    "country": "SG", - optional, Alpha-2 country code
    "postal": "415874", - optional, max 50 characters
    "notes": "Allergic to peanuts", - optional, max 200 characters
    "marketing_consent_email": true,
    "marketing_consent_text": true,
    "marketing_consent_phone": false,
    "customer_group": "{customer_group_id}"
}

Response
Same response as 8.5 View Customer

8.3 Update Customer

Updates a customer profile of the restaurant.


PUT Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/customers/{customer_id}

Header
Authorization: Bearer {access_token}

Parameters
{
    "reference": "A144516982", - optional, max 50 characters
    "first_name": "Mark", - optional, max 50 characters
    "last_name": "Clinton", - optional, max 50 characters
    "company_name": "Dinlr", - optional, max 50 characters
    "email": "[email protected]", - optional, max 50 characters
    "phone": "+6511221122", - optional, max 50 characters
    "dob": "1960-06-22", - optional, format is YYYY-mm-dd
    "gender": "F", - optional
    "address1": "10 Kaki Bukit Ave 4", - optional, max 100 characters
    "address2": "#05-73", - optional, max 100 characters
    "city": "Singapore", - optional, max 100 characters
    "country": "SG", - optional, Alpha-2 country code
    "postal": "415874", - optional, max 50 characters
    "notes": "Allergic to peanuts", - optional, max 200 characters
    "marketing_consent_email": true,
    "marketing_consent_text": false,
    "marketing_consent_phone": false,
    "customer_group": "{customer_group_id}"
}

Response
Same response as 8.5 View Customer

8.4 Search Customers

Searches for customers of the restaurant.


GET Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/customers/search

URL Parameters
  • email - Show customers associated with the email
  • phone - Show customers associated with the phone
  • limit - Return up to this many results per page (default: 50) (max: 200)
  • page - Return a specific page of results (default: 1)
  • update_at_min - Show customers last updated after date (Remember to escape + sign with %2B, because + is not allowed to be used in URL)

Header
Authorization: Bearer {access_token}

Response
Same response as 8.1 Retrieve all Customers

8.5 View Customer

Returns details for a single customer of the restaurant.


GET Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/customers/{customer_id}

Header
Authorization: Bearer {access_token}

Response
{
    "data": {
        "id": "{customer_id}",
        "reference": "A144516982", - optional, max 50 characters
        "first_name": "Mark", - optional, max 50 characters
        "last_name": "Clinton", - optional, max 50 characters
        "company_name": "Dinlr", - optional, max 50 characters
        "email": "[email protected]", - optional, max 50 characters
        "phone": "+6511221122", - optional, max 50 characters
        "dob": "1960-06-22", - optional, format is YYYY-mm-dd
        "gender": "M", - optional
        "address1": "10 Kaki Bukit Ave 4", - optional, max 100 characters
        "address2": "#05-73", - optional, max 100 characters
        "city": "Singapore", - optional, max 100 characters
        "country": "SG", - optional, Alpha-2 country code
        "postal": "415874", - optional, max 50 characters
        "notes": "Allergic to peanuts", - optional, max 200 characters
        "marketing_consent_email": true,
        "marketing_consent_text": false,
        "marketing_consent_phone": false,
        "customer_group": "{customer_group_id}",
        "updated_at": "2018-03-08T13:00:00+08:00"
    }
}

8.6 Retrieve all Customer Groups

Returns a list of all customer groups of the restaurant.


GET Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/customer-groups

URL Parameters
  • limit - Return up to this many results per page (default: 50) (max: 200)
  • page - Return a specific page of results (default: 1)
  • update_at_min - Show customer groups last updated after date (Remember to escape + sign with %2B, because + is not allowed to be used in URL)

Header
Authorization: Bearer {access_token}

Response
{
    "data": [
        {
            "id": "{customer_group_id}",
            "name": "Bronze Member",
            "updated_at": "2018-03-08T13:00:00+08:00"
        },
        {
            "id": "{customer_group_id}",
            "name": "Gold Member",
            "updated_at": "2018-03-08T13:00:00+08:00"
        },
        {
            "id": "{customer_group_id}",
            "name": "Friends & Family",
            "updated_at": "2018-03-08T13:00:00+08:00"
        }
    ]
}

9. Loyalty

*Requires Dinlr Loyalty subscription

9.1 Retrieve all Loyalty Programs

Returns a list of all loyalty programs of the restaurant.


GET Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/loyalty/programs

URL Parameters
  • limit - Return up to this many results per page (default: 50) (max: 200)
  • page - Return a specific page of results (default: 1)
  • update_at_min - Show loyalty programs last updated after date (Remember to escape + sign with %2B, because + is not allowed to be used in URL)

Header
Authorization: Bearer {access_token}

Response
{
    "data": [
        {
            "id": "{loyalty_program_id}",
            "name": "SteakaStar",
            "term_single": "Star",
            "term_plural": "Stars",
            "updated_at": "2018-03-08T13:00:00+08:00"
        },
        {
            "id": "{loyalty_program_id}",
            "name": "Coffee Card",
            "term_single": "Stamp",
            "term_plural": "Stamps",
            "updated_at": "2018-03-08T13:00:00+08:00"
        }
    ]
}

9.2 Retrieve all Rewards

Returns a list of all rewards in the loyalty program of the restaurant.


GET Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/loyalty/{loyalty_program_id}/rewards

Header
Authorization: Bearer {access_token}

Response
{
    "data": [
        {
            "id": "{loyalty_program_reward_id}",
            "point": 500,
            "name": "$15 Off Entire Bill"
        },
        {
            "id": "{loyalty_program_reward_id}",
            "point": 300,
            "name": "Free Heineken Pint"
        }
    ]
}

9.3 Retrieve all Members

Returns a list of all members in the loyalty program of the restaurant.


GET Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/loyalty/{loyalty_program_id}/members

URL Parameters
  • limit - Return up to this many results per page (default: 50) (max: 200)
  • page - Return a specific page of results (default: 1)
  • update_at_min - Show members last updated after date (Remember to escape + sign with %2B, because + is not allowed to be used in URL)

Header
Authorization: Bearer {access_token}

Response
{
    "data": [
        {
            "id": "{member_id}",
            "point": 132,
            "customer": "{customer_id}",
            "updated_at": "2018-03-08T13:00:00+08:00"
        },
        {
            "id": "{member_id}",
            "point": 0,
            "customer": "{customer_id}",
            "updated_at": "2018-03-08T13:00:00+08:00"
        }
    ]
}

9.4 View Member

Returns details for a single member in the loyalty program of the restaurant.


GET Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/loyalty/{loyalty_program_id}/members/{member_id}

Header
Authorization: Bearer {access_token}

Response
{
    "data": {
        "id": "{member_id}",
        "point": 132,
        "customer": "{customer_id}",
        "updated_at": "2018-03-08T13:00:00+08:00"
    }
}

9.5 Enrol Member

Creates a new member in the loyalty program of the restaurant.

To create a new member, you must provide a mapping with the customer_id of the member.


POST Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/loyalty/{loyalty_program_id}/members

Header
Authorization: Bearer {access_token}

Parameters
{
    "customer": "{customer_id}"
}

Response
Same response as 9.4 View Member

9.6 Create Loyalty Transactions

Adds points to or subtracts points from a member in the loyalty program of the restaurant.


POST Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/loyalty/{loyalty_program_id}/transactions

Header
Authorization: Bearer {access_token}

Parameters
{
    "member": "{member_id}",
    "location": "{location_id}", - optional
    "points": 10,
    "notes": "Complimentary points", - optional, max 200 characters
}

Response
{
    "data": {
        "id": "{loyalty_program_transaction_id}",
        "member": "{member_id}",
        "location": "{location_id}", - optional
        "order": "{order_id}", - optional
        "point": 10,
        "notes": "Complimentary points", - optional, max 200 characters
        "created_at": "2018-03-08T13:00:00+08:00"
    }
}

9.7 Search Loyalty Transactions

Searches for transactions for the loyalty program of the restaurant.

Search results are sorted by created_at in descending order.


GET Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/loyalty/{loyalty_program_id}/transactions/search

URL Parameters
  • location_id - Show transactions associated with the location
  • order_id - Show transactions associated with the order
  • member_id - Show transactions associated with the member
  • app_id - Show transactions associated with the app (Set as current to show orders placed by the app currently calling the API)
  • limit - Return up to this many results per page (default: 50) (max: 200)
  • page - Return a specific page of results (default: 1)
  • create_at_min - Show transactions last created after date (Remember to escape + sign with %2B, because + is not allowed to be used in URL)

Header
Authorization: Bearer {access_token}

Response
{
    "data": [
        {
            "id": "{loyalty_program_transaction_id}",
            "member": "{member_id}",
            "location": "{location_id}", - optional
            "order": "{order_id}", - optional
            "point": 15,
            "notes": "Bonus points", - optional, max 200 characters
            "created_at": "2018-03-08T13:00:00+08:00"
        },
        {
            "id": "{loyalty_program_transaction_id}",
            "member": "{member_id}",
            "point": -10,
            "created_at": "2018-03-08T13:00:00+08:00"
        }
    ]
}

10. Store Credit

10.1 Retrieve Customer Store Credit

Returns store credit for a single customer of the restaurant.


GET Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/store-credit/customers/{customer_id}

Header
Authorization: Bearer {access_token}

Response
{
    "data": {
        "id": "{customer_id}",
        "store_credit": 132,
        "updated_at": "2018-03-08T13:00:00+08:00"
    }
}

10.2 Create Store Credit Transaction

Adds store credit to or subtracts store credit from a customer of the restaurant.


POST Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/store-credit/transactions

Header
Authorization: Bearer {access_token}

Parameters
{
    "customer": "{customer_id}",
    "location": "{location_id}", - optional
    "amount": 100.99,
    "notes": "Customer Service Recovery Credit", - optional, max 200 characters
}

Response
{
    "data": {
        "id": "{store_credit_transaction_id}",
        "customer": "{customer_id}",
        "location": "{location_id}", - optional
        "order": "{order_id}", - optional
        "amount": 100.99,
        "notes": "Customer Service Recovery Credit", - optional, max 200 characters
        "created_at": "2018-03-08T13:00:00+08:00"
    }
}

10.3 Search Store Credit Transactions

Searches for store credit transactions of the restaurant.

Search results are sorted by created_at in descending order.


GET Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/store-credit/transactions/search

URL Parameters
  • location_id - Show transactions associated with the location
  • order_id - Show transactions associated with the order
  • customer_id - Show transactions associated with the customer
  • app_id - Show transactions associated with the app (Set as current to show orders placed by the app currently calling the API)
  • limit - Return up to this many results per page (default: 50) (max: 200)
  • page - Return a specific page of results (default: 1)
  • create_at_min - Show transactions last created after date (Remember to escape + sign with %2B, because + is not allowed to be used in URL)

Header
Authorization: Bearer {access_token}

Response
{
    "data": [
        {
            "id": "{store_credit_transaction_id}",
            "customer": "{customer_id}",
            "location": "{location_id}", - optional
            "order": "{order_id}", - optional
            "amount": 100.99,
            "notes": "Customer Service Recovery Credit", - optional, max 200 characters
            "created_at": "2018-03-08T13:00:00+08:00"
        },
        {
            "id": "{store_credit_transaction_id}",
            "customer": "{customer_id}",
            "amount": -10,
            "created_at": "2018-03-08T13:00:00+08:00"
        }
    ]
}

10.4 Top Up Store Credit

Top up store credit to a customer of the restaurant.

Store credit transaction will be created automatically after topping up to reflect the transaction.


POST Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/store-credit/topups

Header
Authorization: Bearer {access_token}

Parameters
{
    "customer": "{customer_id}",
    "location": "{location_id}", - optional
    "topup_no": "T399009", - optional, alphanumeric, no spaces, max 10 characters, unique
    "topup_amount": 200.50,
    "payment": "{payment_id}",
    "payment_amount": 180.50
}

Response
{
    "data": {
        "id": "{store_credit_topup_id}",
        "customer": "{customer_id}",
        "location": "{location_id}",
        "topup_no": "T399009",
        "topup_amount": 200.50,
        "payment": "{payment_id}",
        "payment_amount": 180.50,
        "created_at": "2018-03-08T13:00:00+08:00"
    }
}

11. Place Order

11.1 Cart Summary

Preview order pricing without creating an order.


POST Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/cart/calculate

Header
Authorization: Bearer {access_token}

Parameters
{
    "location": "{location_id}",
    "items": [
        {
            "cart_item_key": "1", - optional, will not be stored, only used as a reference to the items in response
            "item": "{item_id}",
            "qty": 2,
            "notes": "Add Jalapeno", - optional, max 200 characters
            "variant": "{variant_id}",
            "price": "99.99", - optional, only include this variable for open price variant, only works on variant with no defined value
            "modifier_options": [
                {
                    "modifier_option": "{modifier_option_id}",
                    "qty": 2 - optional, default 1
                },
                {
                    "modifier_option": "{modifier_option_id}"
                }
            ],
            "discounts": [ - Item-based discount
                {
                    "discount": "{discount_id}",
                    "value": 10 - optional, only include this variable for open discount, only works on discount with no defined value
                },
                {
                    "discount": "{discount_id}"
                }
            ]
        },
        {
            "item": "{item_id}",
            "qty": 1,
            "variant": "{variant_id}"
        },
        {  - Open item
            "name": "Open Item", - Open item do not require item_id and can be created on-demand
            "qty": 1,
            "price": "199.99" - required for open item, no variant and modifier option allowed for open item
        },
        {  - Item with unit-based variant
            "item": "{item_id}",
            "qty_unit": 0.998,
            "variant": "{variant_id}" - Unit-based variant
        }
    ],
    "charges": [ - optional, only include this variable to set custom charge amount
        {
            "charge": "{charge_id}", - please make sure that this charge is applicable for the selected dining option
            "amount": 8
        }
    ],
    "discounts": [ - Order wide discount
        {
            "discount": "{discount_id}",
            "value": 10, - optional, only include this variable for open discount, only works on discount with no defined value
        },
        {
            "discount": "{discount_id}"
        }
    ],
    "payments": [
        {
            "payment": "{payment_id}",
            "receipt_no": "BC928K", - optional, alphanumeric, no spaces, max 10 characters, unique but can use current order no
            "amount": 25.55,
            "payment_inputs": [ - optional, only include this variable for payment with additional inputs
                {
                    "payment_input": "{payment_input_id}",
                    "value": "Bee San"
                },
                {
                    "payment_input": "{payment_input_id}",
                    "value": "129893322"
                }
            ]
        },
        {
            "payment": "{payment_id}",
            "receipt_no": "VOK992",
            "amount": 4.45
        }
    ],
    "refunds": [
        {
            "refund_no": "RF988D", - optional, alphanumeric, no spaces, max 10 characters, unique
            "refund_payments": [
                {
                    "payment": "{payment_id}",
                    "amount": 5.00,
                },
                {
                    "payment": "{payment_id}",
                    "amount": 1.00,
                }
            ]
        },
        {
            "refund_payments": [
                {
                    "payment": "{payment_id}",
                    "amount": 1.55
                }
            ]
        },
    ],
    "objects": [
        {
            "object": "{object_id}",
            "pax": 3
        }
    ],
    "loyalty_program_rewards": [
        {
            "loyalty_program_reward": "{loyalty_program_reward_id}"
        }
    ],
    "vouchers": [ - optional, only include this variable to use voucher discount/promotion
        {
            "voucher": "{voucher_id}"
        }
    ],
    "order_info": {
        "dining_option": "{dining_option_id}", - optional
        "order_no": "BC928K", - optional, alphanumeric, no spaces, max 10 characters, unique
        "order_ticket": "C23", - optional, max 50 characters
        "pax": 3, - optional, default 1
        "status": "pending", - optional, default "pending", can be either "pending" or "pending_payment"
        "notes": "Self-collect at 3.30pm later", - optional, max 200 characters
        "customer": "{customer_id}", - optional
        "first_name": "Mark", - optional, max 50 characters
        "last_name": "Clinton", - optional, max 50 characters
        "email": "[email protected]", - optional, max 50 characters
        "phone": "+6511221122", - optional, max 50 characters
        "timeslot": "{timeslot_id}", - optional, for pre-orders
        "timeslot_start": "2020-07-10T06:00:00+00:00", - optional, ISO 8601 date, for pre-orders
        "timeslot_end": "2020-07-10T06:30:00+00:00", - optional, ISO 8601 date, for pre-orders
        "delivery_zone": "{delivery_zone_id}", - optional, for delivery orders
        "address1": "10 Kaki Bukit Ave 4", - optional, max 100 characters, delivery address
        "address2": "#05-73", - optional, max 100 characters, delivery address
        "city": "Singapore", - optional, max 100 characters, delivery address
        "country": "SG", - optional, Alpha-2 country code, delivery address
        "postal": "415874", - optional, max 50 characters, delivery address
        "address_lat": 1.3383981, - optional, delivery address latitute
        "address_lng": 103.9059644, - optional, delivery address longitude
        "order_at": "2020-07-10T05:00:00+00:00" - optional, ISO 8601 date, for pre-orders, the date which this order will show up in kitchen printer and KDS
    }
}

Response
{
    "data": {
        "subtotal": 15.54,
        "total": 10.54,
        "financial_status": "paid", - Can be either "pending", "partially_paid", "paid", "partially_refunded", "refunded" or "voided"
        "items": [
            {
                "item": "{item_id}",
                "price_per": 10.3,
                "qty": 2,
                "price": 20.6,
                "variant": "{variant_id}",
                "variant_price": 9.5,
                "sort": 0,
                "modifier_options": [
                    {
                        "modifier_option": "{modifier_option_id}",
                        "price_per": 0.5,
                        "qty": 1,
                        "price": 0.5
                    },
                    {
                        "modifier_option": "{modifier_option_id}",
                        "price_per": 0.15,
                        "qty": 2,
                        "price": 0.3
                    }
                ],
                "discounts": [
                    {
                        "discount": "{discount_id}",
                        "amount": 2.06
                    },
                    {
                        "discount": "{discount_id}",
                        "amount": 1
                    },
                    {
                        "discount": "{discount_id}", - Discount applied via voucher
                        "voucher": "{voucher_id}",
                        "amount": 1
                    },
                    {
                        "promotion": "{promotion_id}", - Promotion discount applied via voucher
                        "voucher": "{voucher_id}",
                        "amount": 1
                    },
                    {
                        "promotion": "{promotion_id}", - Promotion discount applied automatically
                        "amount": 1
                    }
                ]
            },
            {
                "cart_item_key": "98",
                "item": "{item_id}",
                "price_per": 10,
                "qty": 1,
                "price": 10,
                "variant": "{variant_id}",
                "variant_price": 10,
                "sort": 1,
                "modifier_options": [
                ],
                "discounts": [
                ]
            },
            {
                "item": "{item_id}",
                "price_per": 32.6,
                "qty": 4,
                "qty_unit": 0.988
                "price": 130.4,
                "variant": "{variant_id}",
                "variant_price": 32.6,
                "sort": 2,
                "modifier_options": [
                ],
                "discounts": [
                ]
            }
        ],
        "discounts": [
            {
                "discount": "{discount_id}",
                "amount": 10,
            },
            {
                "discount": "{discount_id}",
                "amount": 2,
            },
            {
                "discount": "{discount_id}", - Discount applied via voucher
                "voucher": "{voucher_id}",
                "amount": 3,
            },
            {
                "promotion": "{promotion_id}", - Promotion discount applied via voucher
                "voucher": "{voucher_id}",
                "amount": 3,
            },
            {
                "promotion": "{promotion_id}", - Promotion discount applied automatically
                "amount": 3,
            }
        ],
        "charges": [
            {
                "charge": "{charge_id}",
                "amount": 8,
                "name": "Delivery Fee"
            }
        ],
        "taxes": [
            {
                "tax": "{tax_id}",
                "amount": 2,
                "name": "Government Tax",
                "inclusive": false
            }
        ],
        "manufacturer_discounts": [
            {
                "discount": "{discount_id}",
                "amount": 5,
            },
            {
                "discount": "{discount_id}",
                "amount": 10,
            },
            {
                "discount": "{discount_id}", - Discount applied via voucher
                "voucher": "{voucher_id}",
                "amount": 3,
            },
            {
                "promotion": "{promotion_id}", - Promotion discount applied via voucher
                "voucher": "{voucher_id}",
                "amount": 3,
            },
            {
                "promotion": "{promotion_id}", - Promotion discount applied automatically
                "amount": 3,
            }
        ],
        "payments": [
            {
                "payment": "{payment_id}",
                "amount": 25.55,
                "payment_inputs": [
                    {
                        "payment_input": "{payment_input_id}",
                        "value": "Bee San"
                    },
                    {
                        "payment_input": "{payment_input_id}",
                        "value": "129893322"
                    }
                ]
            },
            {
                "payment": "{payment_id}",
                "amount": 4.45,
                "payment_inputs": [
                ]
            }
        ],
        "refunds": [
            {
                "amount": 30.99,
                "refund_payments": [
                    {
                        "payment": "{payment_id}",
                        "amount": 10.99
                    },
                    {
                        "payment": "{payment_id}",
                        "amount": 20.00
                    }
                ]
            },
            {
                "amount": 1.99,
                "refund_payments": [
                    {
                        "payment": "{payment_id}",
                        "amount": 1.99
                    }
                ]
            }
        ],
        "objects": [
            {
                "object": "{object_id}",
                "pax": 4
            }
        ],
        "vouchers": [
            {
                "voucher": "{voucher_id}"
            }
        ]
    }
}

11.2 Place Order

Creates a new order that can include information about items for purchase and settings to apply to the order.


POST Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/cart/submit

Header
Authorization: Bearer {access_token}

Parameters
Same parameters as 11.1 Cart Summary

Response
Same response as 12.2 View Order

12. Manage Order

12.1 List Order

Returns a list of all orders of the location.


GET Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/orders?location_id={location_id}

Header
Authorization: Bearer {access_token}

URL Parameters
  • location_id
  • app_id - Show orders placed by a certain app. (Set as current to show orders placed by the app currently calling the API)
  • ids - Show orders specified by a comma-separated list of order IDs
  • order_no - Show orders with specific order no only
  • customer_id - Show orders associated with the customer
  • detail - Show order details. (Set as all for full order details similar to 12.2 View Order)
  • limit - Return up to this many results per page (default: 50) (max: 200) (max: 100, if detail = all)
  • page - Return a specific page of results (default: 1)
  • update_at_min - Show orders last updated after date (Remember to escape + sign with %2B, because + is not allowed to be used in URL)
  • create_at_min - Show orders created at or after date (Remember to escape + sign with %2B, because + is not allowed to be used in URL) - Used together with create_at_max, maximum date range: 32 days
  • create_at_max - Show orders created at or before date (Remember to escape + sign with %2B, because + is not allowed to be used in URL) - Used together with create_at_min, maximum date range: 32 days

Response
{
    "data": [
        {  - If detail != all
            "id": "{order_id}",
            "customer": "{customer_id}",
            "order_no": "BC928K",
            "order_ticket": "C23",
            "dining_option": "{dining_option_id}",
            "subtotal": "71.42",
            "total": "79.06",
            "rounding": "-0.01",
            "paid": "79.05",
            "status": "open", - Can be either "pending", "open", "closed", "cancelled", "pending_payment" or "cancelled_payment"
            "financial_status": "paid", - Can be either "pending", "partially_paid", "paid", "partially_refunded", "refunded" or "voided"
            "kitchen_status": null, - Can be either null, "fulfilled" or "partial"
            "expedite_status": null, - Can be either null, "expedited" or "partial"
            "updated_at": "2018-03-08T13:00:00+08:00",
            "created_at": "2018-03-08T13:00:00+08:00",
            "objects": [
                {
                    "object": "{object_id}",
                    "name": "T8"
                },
                {
                    "object": "{object_id}",
                    "name": "T9"
                }
            ]
        },
        {  - If detail = all
            "id": "{order_id}",
            "customer": "{customer_id}",
            "order_no": "AF920F",
            "order_ticket": "C22",
            "dining_option": "{dining_option_id}",
            "dining_option_name": "Takeaway",
            ...... Same response as 12.2 View Order
        }
    ]
}

12.2 View Order

Returns details for a single order of the restaurant.


GET Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/orders/{order_id}

Header
Authorization: Bearer {access_token}

Response
{
    "data": {
        "id": "{order_id}",
        "customer": "{customer_id}",
        "order_no": "BC928K",
        "order_ticket": "C23",
        "dining_option": "{dining_option_id}",
        "dining_option_name": "Dine-in",
        "pax": 4,
        "subtotal": 8.00,
        "total": 10.55,
        "rounding": 0.00,
        "paid": 7.55,
        "status": "open", - Can be either "pending", "open", "closed", "cancelled", "pending_payment" or "cancelled_payment"
        "financial_status": "partially_refunded", - Can be either "pending", "partially_paid", "paid", "partially_refunded", "refunded" or "voided"
        "kitchen_status": null, - Can be either null, "fulfilled" or "partial"
        "expedite_status": null, - Can be either null, "expedited" or "partial"
        "notes": null, - optional, max 200 characters
        "void_reason": null, - optional, max 200 characters
        "updated_at": "2018-03-08T13:00:00+08:00",
        "created_at": "2018-03-08T13:00:00+08:00",
        "objects": [
            {
                "object": "{object_id}",
                "name": "T8"
            },
            {
                "object": "{object_id}",
                "name": "T9"
            }
        ],
        "items": [
            {
                "id": "{order_item_id}",
                "item": "{item_id}",
                "item_no": "A3",
                "name": "Cheesecake",
                "price_per": 10.3,
                "qty": 2,
                "price": 20.6,
                "notes": null, - optional, max 200 characters
                "variant": "{variant_id}",
                "variant_name": "Slice",
                "variant_price": 9.5,
                "sort": 0,
                "modifier_options": [
                    {
                        "modifier_option": "{modifier_option_id}",
                        "name": "Add Cookie",
                        "price_per": 0.5,
                        "qty": 1,
                        "price": 0.5
                    },
                    {
                        "modifier_option": "{modifier_option_id}",
                        "name": "Espresso Sprinkle",
                        "price_per": 0.15,
                        "qty": 2,
                        "price": 0.3
                    }
                ],
                "discounts": [
                    {
                        "discount": "{discount_id}",
                        "name": "Member Discount",
                        "amount": 6.18
                    },
                    {
                        "discount": "{discount_id}", - Discount applied via voucher
                        "voucher": "{voucher_id}",
                        "name": "Birthday Cake Voucher",
                        "amount": 3
                    },
                    {
                        "promotion": "{promotion_id}", - Promotion discount applied via voucher
                        "voucher": "{voucher_id}",
                        "name": "Cake 10% Off Voucher",
                        "amount": 3
                    },
                    {
                        "promotion": "{promotion_id}", - Promotion discount applied automatically
                        "name": "Buy 1 Free 1 Cake",
                        "amount": 3
                    },
                    {
                        "loyalty_program_reward": "{loyalty_program_reward_id}", - Loyalty reward discount applied due to redemption
                        "amount": 3
                    }
                ]
            },
            {
                "id": "{order_item_id}",
                "item": "{item_id}",
                "item_no": null,
                "name": "Latte",
                "price_per": 10,
                "qty": 1,
                "price": 10,
                "notes": null,
                "variant": "{variant_id}",
                "variant_name": "Iced",
                "variant_price": 10,
                "sort": 1,
                "modifier_options": [
                ],
                "discounts": [
                ]
            }
        ],
        "discounts": [
            {
                "discount": "{discount_id}",
                "name": "Off-Peak Discount",
                "amount": 8
            },
            {
                "discount": "{discount_id}", - Discount applied via voucher
                "voucher": "{voucher_id}",
                "name": "Birthday Voucher",
                "amount": 3
            },
            {
                "promotion": "{promotion_id}", - Promotion discount applied via voucher
                "voucher": "{voucher_id}",
                "name": "Store $3 Off Voucher",
                "amount": 3
            },
            {
                "promotion": "{promotion_id}", - Promotion discount applied automatically
                "name": "Launch Promo 15% Off",
                "amount": 3
            },
            {
                "loyalty_program_reward": "{loyalty_program_reward_id}", - Loyalty reward discount applied due to redemption
                "amount": 3
            }
        ],
        "charges": [
            {
                "charge": "{charge_id}",
                "name": "Service Charge",
                "amount": 0.64
            }
        ],
        "taxes": [
            {
                "tax": "{tax_id}",
                "name": "GST",
                "amount": 0.49,
                "inclusive": false
            }
        ],
        "manufacturer_discounts": [
            {
                "discount": "{discount_id}",
                "name": "Mall Discount",
                "amount": 5
            },
            {
                "discount": "{discount_id}", - Discount applied via voucher
                "voucher": "{voucher_id}",
                "name": "Birthday Voucher",
                "amount": 3
            },
            {
                "promotion": "{promotion_id}", - Promotion discount applied via voucher
                "voucher": "{voucher_id}",
                "name": "Store $3 Off Voucher",
                "amount": 3
            },
            {
                "promotion": "{promotion_id}", - Promotion discount applied automatically
                "name": "Launch Promo 15% Off",
                "amount": 3
            },
            {
                "loyalty_program_reward": "{loyalty_program_reward_id}", - Loyalty reward discount applied due to redemption
                "amount": 3
            }
        ],
        "loyalty_program_rewards": [
            {
                "loyalty_program_reward": "{loyalty_program_reward_id}",
                "point": 500
            }
        ],
        "vouchers": [
            {
                "voucher": "{voucher_id}",
                "voucher_code": "XMAS10"
            }
        ],
        "payments": [
            {
                "id": "{receipt_id}",
                "payment": "{payment_id}",
                "payment_name": "Mastercard",
                "receipt_no": "BC928K",
                "amount": 2.55,
                "created_at": "2018-03-08T13:00:00+08:00",
                "payment_inputs": [
                    {
                        "payment_input": "{payment_input_id}",
                        "value": "Bee San"
                    },
                    {
                        "payment_input": "{payment_input_id}",
                        "value": "129893322"
                    }
                ]
            },
            {
                "id": "{receipt_id}",
                "payment": "{payment_id}",
                "payment_name": "Cash",
                "receipt_no": "99K0092",
                "amount": 5.55,
                "created_at": "2018-03-08T13:00:00+08:00",
                "payment_inputs": [
                ]
            }
        ],
        "refunds": [
            {
                "id": "{refund_id}",
                "refund_no": "RFN069A",
                "amount": 0.55,
                "created_at": "2018-03-08T13:00:00+08:00",
                "refund_payments": [
                    {
                        "payment": "{payment_id}",
                        "payment_name": "Mastercard",
                        "amount": 0.30
                    },
                    {
                        "payment": "{payment_id}",
                        "payment_name": "Cash",
                        "amount": 0.25
                    }
                ]
            }
        ]
    }
}

12.3 Update Order

Updates an open order by adding, replacing, or deleting fields.


PUT Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/orders/{order_id}

Header
Authorization: Bearer {access_token}

Parameters
{
    "items": [
        {
            "id": "{order_item_id}", - *NOTE* Use order item id to retain the item’s kitchen and expedite status, or it will act as a new item
            "item": "{item_id}",
            "qty": 2,
            "notes": "Add Jalapeno", - optional, max 200 characters
            "variant": "{variant_id}",
            "price": "99.99", - optional, only include this variable for open price variant, only works on variant with no defined value
            "modifier_options": [
                {
                    "modifier_option": "{modifier_option_id}",
                    "qty": 2 - optional, default 1
                },
                {
                    "modifier_option": "{modifier_option_id}"
                }
            ],
            "discounts": [ - Item-based discount
                {
                    "discount": "{discount_id}",
                    "value": 10 - optional, only include this variable for open discount, only works on discount with no defined value
                },
                {
                    "discount": "{discount_id}"
                }
            ]
        },
        {
            "id": "{order_item_id}",
            "item": "{item_id}",
            "qty": 1,
            "variant": "{variant_id}"
        },
        { - Item with no id variable will act as a new item
            "item": "{item_id}",
            "qty": 1,
            "variant": "{variant_id}"
        },
        {  - Open item
            "name": "Open Item", - Open item do not require item_id and can be created on-demand
            "qty": 1,
            "price": "199.99" - required for open item, no variant and modifier option allowed for open item
        },
        {  - Item with unit-based variant
            "item": "{item_id}",
            "qty_unit": 0.998,
            "variant": "{variant_id}" - Unit-based variant
        }
    ],
    "charges": [ - optional, only include this variable to set custom charge amount
        {
            "charge": "{charge_id}", - please make sure that this charge is applicable for the selected dining option
            "amount": 8
        }
    ],
    "discounts": [ - Order wide discount
        {
            "discount": "{discount _id}",
            "value": 10, - optional, only include this variable for open discount, only works on discount with no defined value
        },
        {
            "discount": "{discount _id}"
        }
     ],
    "payments": [ - *NOTE* ONLY include new payment, DO NOT INCLUDE existing/previous payments, leave empty if there is no new payment (Reason: Dinlr does not allow amendment of payment once it is recorded)
        {
            "payment": "{payment_id}",
            "receipt_no": "BC928K", - optional, alphanumeric, no spaces, max 10 characters, unique but can use current order no
            "amount": 25.55,
            "payment_inputs": [ - optional, only include this variable for payment with additional inputs
                {
                    "payment_input": "{payment_input_id}",
                    "value": "Bee San"
                },
                {
                    "payment_input": "{payment_input_id}",
                    "value": "129893322"
                }
            ]
        },
        {
            "payment": "{payment_id}",
            "receipt_no": "VOK992",
            "amount": 4.45
        }
    ],
    "objects": [
        {
            "object": "{object_id}",
            "pax": 3
        }
    ],
    "loyalty_program_rewards": [
        {
            "loyalty_program_reward": "{loyalty_program_reward_id}"
        }
    ],
    "vouchers": [ - optional, only include this variable to use voucher discount/promotion
        {
            "voucher": "{voucher_id}"
        }
    ],
    "order_info": {
        "dining_option": "{dining_option_id}", - optional
        "order_no": "BC928K", - optional, alphanumeric, no spaces, max 10 characters, unique, leave empty to use previous order_no
        "order_ticket": "C23", - optional, max 50 characters, leave empty to use previous order_ticket
        "pax": 3, - optional, leave empty to use previous pax
        "status": "pending", - optional, leave empty to use previous status
        "notes": "Self-collect at 3.30pm later", - optional, max 200 characters
        "customer": "{customer_id}", - optional
        "first_name": "Mark", - optional, max 50 characters
        "last_name": "Clinton", - optional, max 50 characters
        "email": "[email protected]", - optional, max 50 characters
        "phone": "+6511221122", - optional, max 50 characters
        "timeslot": "{timeslot_id}", - optional, for pre-orders
        "timeslot_start": "2020-07-10T06:00:00+00:00", - optional, ISO 8601 date, for pre-orders
        "timeslot_end": "2020-07-10T06:30:00+00:00", - optional, ISO 8601 date, for pre-orders
        "delivery_zone": "{delivery_zone_id}", - optional, for delivery orders
        "address1": "10 Kaki Bukit Ave 4", - optional, max 100 characters, delivery address
        "address2": "#05-73", - optional, max 100 characters, delivery address
        "city": "Singapore", - optional, max 100 characters, delivery address
        "country": "SG", - optional, Alpha-2 country code, delivery address
        "postal": "415874", - optional, max 50 characters, delivery address
        "address_lat": 1.3383981, - optional, delivery address latitute
        "address_lng": 103.9059644, - optional, delivery address longitude
        "order_at": "2020-07-10T05:00:00+00:00" - optional, ISO 8601 date, for pre-orders, the date which this order will show up in kitchen printer and KDS, leave empty to use previous order_at
    }
}

Response
Same response as 12.2 View Order

12.4 Create Order Payment

Creates a new payment for the order.


POST Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/orders/{order_id}/payments

Header
Authorization: Bearer {access_token}

Parameters
{
    "payment": "{payment_id}",
    "receipt_no": "BC928K", - optional, alphanumeric, no spaces, max 10 characters, unique but can use current order no
    "amount": 25.55,
    "payment_inputs": [ - optional, only include this variable for payment with additional inputs
        {
            "payment_input": "{payment_input_id}",
            "value": "Bee San"
        },
        {
            "payment_input": "{payment_input_id}",
            "value": "129893322"
        }
    ]
}

Response
Same response as 12.2 View Order

12.5 Create Order Refund

Creates a new refund for the order.


POST Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/orders/{order_id}/refunds

Header
Authorization: Bearer {access_token}

Parameters
{
    "refund_no": "RF988D", - optional, alphanumeric, no spaces, max 10 characters, unique
    "refund_payments": [
        {
            "payment": "{payment_id}",
            "amount": 5.00
        },
        {
            "payment": "{payment_id}",
            "amount": 1.00
        }
    ]
}

Response
Same response as 12.2 View Order

12.6 Change Order Status

Updates an order status.

Only specific status can be changed based on the current order status:

  1. Pending Order Pending Payment or Cancel
  2. Pending Payment Order Pending or Cancel
  3. Open Order Close or Cancel
  4. Closed Order Open or Cancel
  5. Cancelled Order Non-changeable


POST Request

Closes an order.


https://api.dinlr.com/v1/{restaurant_id}/onlineorder/orders/{order_id}/close

Re-opens an order.


https://api.dinlr.com/v1/{restaurant_id}/onlineorder/orders/{order_id}/open

Cancels an order. Cannot be performed on orders with transactions (payments or refunds).


https://api.dinlr.com/v1/{restaurant_id}/onlineorder/orders/{order_id}/cancel

Set order as pending.


https://api.dinlr.com/v1/{restaurant_id}/onlineorder/orders/{order_id}/pending

Set order as pending payment (Waiting for payment).


https://api.dinlr.com/v1/{restaurant_id}/onlineorder/orders/{order_id}/pending_payment

Header
Authorization: Bearer {access_token}

Response
Same response as 12.2 View Order

12.7 Change Order Item Kitchen Status

*Requires Dinlr KDS subscription

Updates an order item kitchen status.

3-steps order item kitchen status progression: Default Pending (In Preparation) Fulfilled (Ready)

2-steps order item kitchen status progression: Default Fulfilled (Ready)


POST Request

Set order item kitchen status as pending (in preparation).


https://api.dinlr.com/v1/{restaurant_id}/onlineorder/orders/{order_id}/order_items/{order_item_id}/kitchen/pending

Set order item kitchen status as fulfilled (ready).


https://api.dinlr.com/v1/{restaurant_id}/onlineorder/orders/{order_id}/order_items/{order_item_id}/kitchen/fulfill

Set order item kitchen status as default.


https://api.dinlr.com/v1/{restaurant_id}/onlineorder/orders/{order_id}/order_items/{order_item_id}/kitchen/default

Header
Authorization: Bearer {access_token}

Response
HTTP/1.1 204 No Content

12.8 Change Order Item Expedite Status

*Requires Dinlr KDS subscription

Updates an order item expedite status.

3-steps order item expedite status progression: Default Pending (On The Way) Expedited (Served)

2-steps order item expedite status progression: Default Expedited (Served)


POST Request

Set order item expedite status as pending (on the way).


https://api.dinlr.com/v1/{restaurant_id}/onlineorder/orders/{order_id}/order_items/{order_item_id}/expedite/pending

Set order item expedite status as expedited (served).


https://api.dinlr.com/v1/{restaurant_id}/onlineorder/orders/{order_id}/order_items/{order_item_id}/expedite/expedite

Set order item expedite status as default.


https://api.dinlr.com/v1/{restaurant_id}/onlineorder/orders/{order_id}/order_items/{order_item_id}/expedite/default

Header
Authorization: Bearer {access_token}

Response
HTTP/1.1 204 No Content

13. Reservations

*Requires Dinlr Reservation subscription

13.1 Retrieve all Experiences

Returns a list of all experiences of the location.


GET Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/experiences?location_id={location_id}

URL Parameters
  • location_id
  • limit - Return up to this many results per page (default: 50) (max: 200)
  • page - Return a specific page of results (default: 1)
  • update_at_min - Show experiences last updated after date (Remember to escape + sign with %2B, because + is not allowed to be used in URL)

Header
Authorization: Bearer {access_token}

Response
{
    "data": [
        {
            "id": "{experience_id}",
            "name": "Indoor Dining",
            "sort": 0,
            "updated_at": "2018-03-08T13:00:00+08:00"
        },
        {
            "id": "{experience_id}",
            "name": "Outdoor Dining",
            "sort": 1,
            "updated_at": "2018-03-08T13:00:00+08:00"
        },
        {
            "id": "{experience_id}",
            "name": "VIP Room",
            "sort": 2,
            "updated_at": "2018-03-08T13:00:00+08:00"
        }
    ]
}

13.2 Retrieve all Table Sections

Returns a list of all table sections of the location.


GET Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/table-sections?location_id={location_id}

URL Parameters
  • location_id
  • limit - Return up to this many results per page (default: 50) (max: 200)
  • page - Return a specific page of results (default: 1)
  • update_at_min - Show table sections last updated after date (Remember to escape + sign with %2B, because + is not allowed to be used in URL)

Header
Authorization: Bearer {access_token}

Response
{
    "data": [
        {
            "id": "{table_section_id}",
            "name": "VIP Rooms",
            "updated_at": "2018-03-08T13:00:00+08:00"
        },
        {
            "id": "{table_section_id}",
            "name": "Indoor",
            "updated_at": "2018-03-08T13:00:00+08:00"
        },
        {
            "id": "{table_section_id}",
            "name": "Outdoor",
            "updated_at": "2018-03-08T13:00:00+08:00"
        }
    ]
}

13.3 Get Available Reservation Times

Returns a list of all available reservation times and services on a specific date for the location.


GET Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/services?location_id={location_id}&date={date}&adult={adult}&children={children}

URL Parameters
  • location_id
  • date - Date for reservation, format is YYYY-mm-dd
  • adult
  • children

Header
Authorization: Bearer {access_token}

Response
{
    "data": [
        {
            "id": "{service_id}",
            "name": "Lunch Session",
            "experience": "{experience_id}",
            "table_section": "{table_section_id}",
            "available_times": [
                {
                    "time": "2020-07-10T06:00:00+00:00", - ISO 8601 date
                },
                {
                    "time": "2020-07-10T06:00:00+00:00",
                },
                {
                    "time": "2020-07-10T06:00:00+00:00",
                }
            ]
        },
        {
            "id": "{service_id}",
            "name": "Dinner Session",
            "experience": "{experience_id}",
            "table_section": "{table_section_id}",
            "available_times": [
                {
                    "time": "2020-07-10T06:00:00+00:00",
                },
                {
                    "time": "2020-07-10T06:00:00+00:00",
                }
            ]
        },
        {
            "id": "{service_id}",
            "name": "VIP Dinner Session",
            "experience": "{experience_id}",
            "table_section": "{table_section_id}",
            "available_times": [
                {
                    "time": "2020-07-10T06:00:00+00:00",
                }
            ]
        }
    ]
}

13.4 Book a Reservation

Books a new reservation for the location.


POST Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/reservations

Header
Authorization: Bearer {access_token}

Parameters
{
    "location": "{location_id}",
    "objects": [
        {
            "object": "{object_id}",
            "pax": 3
        }
    ],
    "reservation_info": {
        "customer": "{customer_id}", - optional
        "reservation_no": "BC928K", - optional, alphanumeric, no spaces, max 10 characters, unique
        "reservation_time": "2020-07-10T06:00:00+00:00", - ISO 8601 date
        "service": "{service_id}",
        "first_name": "Mark", - optional, max 50 characters
        "last_name": "Clinton", - optional, max 50 characters
        "email": "[email protected]", - optional, max 50 characters
        "phone": "+6511221122", - optional, max 50 characters
        "pax": 3, - sum of adult and children
        "adult": 2,
        "children": 1,
        "status": "booked", - optional, default "booked" for no-deposit and "pending_payment" for deposit reservation, can be either "booked" or "pending_payment"
        "confirm_by": null, - optional, can be either "restaurant" or "customer"
        "notes": "It's my mum birthday" - optional, max 200 characters
    }
}

Response
Same response as 13.6 View Reservation

13.5 List Reservation

Returns a list of all reservations of the location.


GET Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/reservations?location_id={location_id}

Header
Authorization: Bearer {access_token}

URL Parameters
  • location_id
  • app_id - Show reservations booked by a certain app. (Set as current to show reservations booked by the app currently calling the API)
  • reservation_no - Show reservations with specific reservation no only
  • limit - Return up to this many results per page (default: 50) (max: 200)
  • page - Return a specific page of results (default: 1)
  • update_at_min - Show reservations last updated after date (Remember to escape + sign with %2B, because + is not allowed to be used in URL)

Response
{
    "data": [
        {
            "id": "{reservation_id}",
            "customer": "{customer_id}",
            "reservation_no": "LFO2983",
            "reservation_time": "2020-07-10T06:00:00+00:00", - ISO 8601 date
            "service": "{service_id}",
            "experience": "{experience_id}",
            "table_section": "{table_section_id}",
            "pax": 3,
            "adult": 2,
            "children": 1,
            "total_deposit": 50.00,
            "status": "booked", - Can be either "booked", "arrived", "seated", "completed", "no_show", "cancelled", "pending_payment" or "cancelled_payment"
            "confirm_by": null, - Can be either null, "restaurant" or "customer"
            "updated_at": "2018-03-08T13:00:00+08:00",
            "created_at": "2018-03-08T13:00:00+08:00",
            "objects": [
                {
                    "object": "{object_id}",
                    "name": "T8"
                },
                {
                    "object": "{object_id}",
                    "name": "T9"
                }
            ]
        },
        {
            "id": "{reservation_id}",
            "customer": "{customer_id}",
            "reservation_no": "QF2F20",
            "reservation_time": "2020-07-10T06:00:00+00:00",
            "service": "{service_id}",
            "experience": "{experience_id}",
            "table_section": "{table_section_id}",
            "pax": 2,
            "adult": 2,
            "children": 0,
            "total_deposit": 0.00,
            "status": "no_show",
            "confirm_by": "customer",
            "updated_at": "2018-03-08T13:00:00+08:00",
            "created_at": "2018-03-08T13:00:00+08:00",
            "objects": [
                {
                    "object": "{object_id}",
                    "name": "VIP10"
                }
            ]
        }
    ]
}

13.6 View Reservation

Returns details for a single reservation of the restaurant.


GET Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/reservations/{reservation_id}

Header
Authorization: Bearer {access_token}

Response
{
    "data": {
        "id": "{reservation_id}",
        "customer": "{customer_id}",
        "reservation_no": "LFO2983",
        "reservation_time": "2020-07-10T06:00:00+00:00", - ISO 8601 date
        "service": "{service_id}",
        "service_name": "Lunch",
        "experience": "{experience_id}",
        "experience_name": "Indoor Dining",
        "table_section": "{table_section_id}",
        "table_section_name": "Indoor",
        "pax": 4,
        "adult": 3,
        "children": 1,
        "total_deposit": 100.00,
        "status": "pending_payment", - Can be either "booked", "arrived", "seated", "completed", "no_show", "cancelled", "pending_payment" or "cancelled_payment"
        "confirm_by": null, - Can be either null, "restaurant" or "customer"
        "notes": null, - optional, max 200 characters
        "cancel_reason": null, - optional, max 200 characters
        "updated_at": "2018-03-08T13:00:00+08:00",
        "created_at": "2018-03-08T13:00:00+08:00",
        "objects": [
            {
                "object": "{object_id}",
                "name": "18"
            },
            {
                "object": "{object_id}",
                "name": "VIP9"
            }
        ]
    }
}

13.7 Update Reservation

Updates a reservation by adding, replacing, or deleting fields.


PUT Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/reservations/{reservation_id}

Header
Authorization: Bearer {access_token}

Parameters
{
    "objects": [
        {
            "object": "{object_id}",
            "pax": 3
        }
    ],
    "reservation_info": {
        "customer": "{customer_id}", - optional
        "reservation_no": "BC928K", - optional, alphanumeric, no spaces, max 10 characters, unique
        "reservation_time": "2020-07-10T06:00:00+00:00", - ISO 8601 date
        "service": "{service_id}",
        "first_name": "Mark", - optional, max 50 characters
        "last_name": "Clinton", - optional, max 50 characters
        "email": "[email protected]", - optional, max 50 characters
        "phone": "+6511221122", - optional, max 50 characters
        "pax": 3, - sum of adult and children
        "adult": 2,
        "children": 1,
        "status": "booked", - optional, default "booked" for no-deposit and "pending_payment" for deposit reservation, can be either "booked" or "pending_payment"
        "confirm_by": null, - optional, can be either "restaurant" or "customer"
        "notes": "It's my mum birthday" - optional, max 200 characters
    }
}

Response
Same response as 13.6 View Reservation

14. Inventory

14.1 Retrieve all Materials

Returns a list of all materials of the location.


GET Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/materials?location_id={location_id}

URL Parameters
  • location_id
  • limit - Return up to this many results per page (default: 50) (max: 200)
  • page - Return a specific page of results (default: 1)
  • update_at_min - Show materials last updated after date (Remember to escape + sign with %2B, because + is not allowed to be used in URL)

Header
Authorization: Bearer {access_token}

Response
{
    "data": [
        {
            "id": "{material_id}",
            "name": "Angus Beef Patty",
            "sku": null,
            "unit": "pc",
            "updated_at": "2018-03-08T13:00:00+08:00"
        },
        {
            "id": "{material_id}",
            "name": "Tiger Beer",
            "sku": "10248763192",
            "unit": "litre",
            "updated_at": "2018-03-08T13:00:00+08:00"
        },
        {
            "id": "{material_id}",
            "name": "Coca Cola",
            "sku": "10248763432",
            "unit": "can",
            "updated_at": "2018-03-08T13:00:00+08:00"
        }
    ]
}

14.2 Get Stock Level of all Materials

Returns current stock level of all amterials of the location.


GET Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/material-stocks?location_id={location_id}

URL Parameters
  • location_id
  • limit - Return up to this many results per page (default: 50) (max: 200)
  • page - Return a specific page of results (default: 1)

Header
Authorization: Bearer {access_token}

Response
{
    "data": [
        {
            "material": "{material_id}",
            "qty": 30,
            "updated_at": "2018-03-08T13:00:00+08:00"
        },
        {
            "material": "{material_id}",
            "qty": 10.252,
            "updated_at": "2018-03-08T13:00:00+08:00"
        },
        {
            "material": "{material_id}",
            "qty": 30.01,
            "updated_at": "2018-03-08T13:00:00+08:00"
        }
    ]
}

14.3 Retrieve all Stock Takes

Returns a list of all stock takes of the location.


GET Request
https://api.dinlr.com/v1/{restaurant_id}/onlineorder/stock-takes?location_id={location_id}

URL Parameters
  • location_id
  • limit - Return up to this many results per page (default: 50) (max: 200)
  • page - Return a specific page of results (default: 1)
  • update_at_min - Show materials last updated after date (Remember to escape + sign with %2B, because + is not allowed to be used in URL)

Header
Authorization: Bearer {access_token}

Response
{
    "data": [
        {
            "id": "{stock_take_id}",
            "notes": null, - optional, max 200 characters
            "start_date": "2018-03-08T13:00:00+08:00", - ISO 8601 date
            "end_date": null, - optional, ISO 8601 date, if value is null, it means the stock take is currently ongoing
            "updated_at": "2018-03-08T15:00:00+08:00",
            "materials": [
            ]
        },
        {
            "id": "{stock_take_id}",
            "notes": "Egg shortage due to cracks",
            "start_date": "2018-03-08T13:00:00+08:00",
            "end_date": "2018-03-08T15:00:00+08:00",
            "updated_at": "2018-03-08T15:00:00+08:00",
            "materials": [
                {
                    "material": "{material_id}",
                    "counted": 54
                },
                {
                    "material": "{material_id}",
                    "counted": 32.133
                },
                {
                    "material": "{material_id}",
                    "counted": 3.5
                }
            ]
        },
        {
            "id": "{stock_take_id}",
            "notes": null,
            "start_date": "2018-03-08T13:00:00+08:00",
            "end_date": "2018-03-08T15:00:00+08:00",
            "updated_at": "2018-03-08T15:00:00+08:00",
            "materials": [
                {
                    "material": "{material_id}",
                    "counted": 3
                },
                {
                    "material": "{material_id}",
                    "counted": 1.66
                }
            ]
        }
    ]
}

15. Webhooks

15.1 Creating Webhooks

To start receiving webhook events in your app, create webhook endpoint in your partner account by following the steps below:

Step 1. Login Partner Account

Login using your partner account here: https://partners.dinlr.com

Step 2. List App Webhooks

Once you sign in you can click on "Apps" located at the side menu and click on "Webhooks" for the app that you will be creating the webhook for.

Step 3. Create Webhook

Click on "Create Webhook", add your endpoint URL and select all the events that you want to receive in your endpoint.

15.2 Secure Your Webhooks

After confirming your webhook endpoint connection works as expected, secure the connection by implementing these webhook best practices.

  • Ignore duplicates: Webhook endpoints might occassionally receive the same event more than once. Guard against duplicated event receipts by making your event processing idempotent. One way of doing this is logging the events you’ve processed, and then not processing already-logged events.
  • Listen to specific event types: Configure your webhook endpoints to receive only the types of events required by your integration.
  • Use HTTPS endpoint: Using HTTPS URL for your webhook endpoint will allow Dinlr to validate that the connection to your server is secure before sending your webhook data.
  • Quickly return a 2xx response: Dinlr has implemented a five-second timeout period for each request to a webhook. To avoid timeouts and errors, your webhook endpoint must quickly return a successful status code (2xx) prior to any complex logic that could cause a timeout.
  • Retry behavior: Dinlr attempts to deliver a given event to your webhook endpoint for up to 19 times over the next 40 minutes. If there are 19 consecutive failures, then the event will be automatically paused. If there are more than 20 events with 19 consecutive failures, the webhook will be automatically disabled and can only be resumed from your partner account.
  • Prevent replay attacks: Dinlr utilizes a timestamp in the X-Dinlr-Signature header, prefixed by t=, that you can use to reject the webhook if the timestamp in the signature header is too old based on the tolerance zone.
  • Verify event signatures: Dinlr signs webhook events it sends to your endpoints by including a signature in each event's X-Dinlr-Signature header. You must verify each event received at your endpoint, please refer to 15.3 Verifying Webhook Signatures.

15.3 Verifying Webhook Signatures

The X-Dinlr-Signature header included in each signed event contains a timestamp and one signature that you must verify. The timestamp is prefixed by t=, and the signature is prefixed by v1=.

Dinlr generates signatures using a hash-based message authentication code (HMAC) with SHA-256 algorithm.


Example Webhook Header
X-Dinlr-Signature: t=1704132000,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd

Before you respond to a webhook, you need to verify that the webhook was sent from Dinlr. You can verify the webhook by calculating a digital signature using the timestamp, webhook request body and your webhook's signing secret.

Step 1. Extract timestamp and signature from the header

Split the X-Dinlr-Signature header using the , character as the separator to get a list of elements. Then split each element using the = character as the separator to get a prefix and value pair.

Step 2. Prepare the signed_payload string

The signed_payload string is created by concatenating:

  • The timestamp (as a string)
  • The character .
  • The webhook request body

Example: signed_payload = 1704132000.{"id":"abcdefg","object":"order",...}

Step 3. Determine the expected signature

Compute an HMAC with the SHA256 hash function. Use the webhook's signing secret as the key, and use the signed_payload string as the message.

Computation: HMAC_HASH('sha256', signing_secret, signed_payload)

Step 4. Compare the signatures

Compare the signature in the header to the expected signature. For an equality match, compute the difference between the current timestamp and the received timestamp, then decide if the difference is within your tolerance.

15.4 Incoming Webhook Event

Listen for events on your webhook URL when certain actions are completed.

Each event contains both top-level restaurant and location attributes used to identify the restaurant and location that the webhook belongs to.


Webhook Event Header
X-Dinlr-Signature: t={timestamp},v1={signature}

Webhook Event Payload
{
    "id": "{event_id}",
    "object": "order", - Refer to 15.5 Topics of Webhook Events
    "topic": "order.created", - Refer to 15.5 Topics of Webhook Events
    "restaurant": "{restaurant_id}",
    "location": "{location_id}", - optional, only required if object is order
    "created_at": "2020-07-10T06:00:00+00:00", - ISO 8601 date, date at which the event was created (Different from signature timestamp and the object creation date)
    "data": {
        ...object data...
    }
}

15.5 Topics of Webhook Events

This is a list of all the topics of events that your Dinlr app can subscribe to. We may add more at any time, so in developing and maintaining your code, you should not assume that only these topics exist.

Operational Topics


Topic Object Event
order.created order Occurs whenever an order is created.
order.deleted order Occurs whenever an order is deleted.
order.updated order Occurs whenever an order is edited.
customer.created customer Occurs whenever a customer is created.
customer.deleted customer Occurs whenever a customer is deleted.
customer.updated customer Occurs whenever a customer is edited.
loyalty_program_transaction.created loyalty_program_transaction Occurs whenever a loyalty program transaction is created.
item.blocked item Occurs whenever an item is blocked.
item.unblocked item Occurs whenever an item is unblocked.
item_variant.blocked item_variant Occurs whenever an item variant is blocked.
item_variant.unblocked item_variant Occurs whenever an item variant is unblocked.
modifier_option.blocked modifier_option Occurs whenever a modifier option is blocked.
modifier_option.unblocked modifier_option Occurs whenever a modifier option is unblocked.

Database Topics


Topic Object Event
discount.created discount Occurs whenever a discount is created.
discount.deleted discount Occurs whenever a discount is deleted.
discount.updated discount Occurs whenever a discount is edited.
promotion.created promotion Occurs whenever a promotion is created.
promotion.deleted promotion Occurs whenever a promotion is deleted.
promotion.updated promotion Occurs whenever a promotion is edited.