Webhooks support pushing real-time updates from the server to the client as those updates happen. These are useful whenever you need to know exactly when a specific event happens, allowing you to take action on those events immediately via the API.

Supported events

  • An order is completed. Event code: order.finalized
  • A customer record is created. Event code: customer.created
  • A customer record is updated. Event code: customer.updated
  • A rewards card is created. Event code: rewardcard.created
  • A product/ingredient/modifier is out of stock. Event code: inout.stock
  • Menu is updated. Event code: menu.updated
  • TimeSheet entry created, updated or deleted. Event codes: timesheet.created, timesheet.updated and timesheet.deleted
  • Integration is changed. Event code: app.integration.changed
  • Endpoint test request. Event code: ping

Webhook Setup

To get Webhook updates you need to provide Revel with one or more URLs that will receive a POST request whenever appropriate action occurs. For example, the below URLs could be provided to Revel to receive these notifications for each of the above actions:

You can choose one or more action to send notifications for. You do not have to send notification for every action that Revel supports.

Webhook endpoint URL requirements:

To streamline the integration process and enhance security, Revel Systems requires partners to use a single webhook endpoint per event for all clients. This approach simplifies the management of webhooks, reduces potential points of failure and streamlines the onboarding process for our clients!

Instead of creating unique endpoint URLs for each client, you may utilise headers to distinguish between clients. All of our Webhook event's that require distinction between clients include headers that can be used to identify which Client and Establishment the event is being sent from. The following paragraph will describe the headers we include in our events.

Revel Headers

Each event from Revel, except for the readiness test event, will include the following headers:

X-Revel-Signature: request signature to authenticate the request

X-Revel-Instance: Customer Instance name

X-Revel-Event-Type: Type of the event originated the request

X-Revel-Event-Id: unique event identifier

X-Revel-Message-Id: unique message identifier

Optional headers:

X-Revel-Establishment-Id: Establishment ID (if applicable for the event)

Ensuring Webhook events are accepted

The following requirements should be met in order to ensure your system is configured to accept the webhook events we sent:

  • Should use HTTPS protocol
  • Should accept POST requests
  • Should accept JSON body
  • Should be accessible publicly
  • Should respond with 2XX status code
  • Should respond within 10 seconds

Webhook readiness test:

During setup Revel Systems will send a test request to provided endpoint. Your endpoint should meet all of the requirements above for the readiness test to be successful.

Test request will have the following headers:

X-Revel-Event-Type: ping

X-Revel-Signature: “xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx“

Payload will contain a JSON object:

{"ping": "pong"}
connection	close
accept-encoding	gzip
x-revel-signature	101d196a9266dcbbb3a7326f3fe40a774c9edd1f
x-revel-event-type	ping
content-type	application/json
content-length	16

Retry mechanism:

If your Webhook endpoint doesn't meet all of the above requirements, it will trigger the following retry mechanism:
• Exponential retries - if a Webhook Request failed, it will be put back into a queue and retry with a delay. The delay is computed by retry number - 1st: 60sec; 2nd: 300sec; 3rd: 900sec; 4th: 900sec

So overall there will be up to 4 tries in 36min period to get successful response with every failed Webhook Request.

Message Signature And Other Headers

Our webhook service uses HMAC-SHA1 to ensure the integrity and authenticity of the data we send. Specifically, we create a hash-based message authentication code (HMAC) using the SHA-1 algorithm and your secret key. This HMAC is then encoded as a hexadecimal string and sent along with the payload through the X-Revel-Signature header. You can use this signature to verify that the data has not been tampered with.

After webhook setup, Revel will provide the webhook recipient with a shared secret key necessary for message payload verification.

Example of X-Revel-Signature Header:

X-Revel-Signature: XIUKGMCYQYNULKYDLQTL
X-Revel-Instance: revelcustomer

A couple of examples of signature calculation:

import hmac
from hashlib import sha1

signature = hmac.new(
    "{the-shared-secret}".encode('utf-8'),
    "{the-request-body-string}".encode('utf-8'),
sha1).hexdigest()
import (
   "crypto/hmac"
   "crypto/sha1"
   "encoding/hex"
)

func calculateWebhookSignature(secretKey string, payload []byte) string {
    h := hmac.New(sha1.New, []byte(secretKey))
    h.Write(payload)
    signature := hex.EncodeToString(h.Sum(nil))
    return signature
}

Webhook Data

Field types

Webhook Request payloads might contain the following field types:

  • String - String data. Example: "Hello World"
  • Boolean - Boolean data. Example: true
  • Integer - Integer data. Example: 2673
  • Float - Floating point numeric data. Example: 26.73
  • DateTime - A date & time as a string (ISO 8601). Example: "2023-12-10T03:07:43"
  • Decimal - Fixed precision numeric data. Example: "12.345678"

Integration changed payload samples

Whenever there is an access change to your integration the app.integration.changed event will trigger. There are 3 types of actions that can trigger the event: Create (a Revel instance was added to your application), Update(Additional establishment(s) access were added or removed to an instance you already have access to) or Delete(An instance access was removed).

Created payload (a Revel instance was added to your application):

{
    "action": "CREATE",
    "client_id": "your-instance-name",
    "full_access": true,
    "id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
}

Update payload (Application Integration has been changed):

{
    "action": "UPDATE",
    "client_id": "your-instance-name",
    "establishments": [1],
    "id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
}

Delete payload (Application Integration has been deleted):

{
    "action": "DELETE",
    "client_id": "your-instance-name",
    "id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
}

Order completed Payload sample

Upon completion of an order, a representation of the completed order will be sent using Revel's OrderAllInOne format, which includes information for the Order, Order Items, Payments, and Order History. The information about the loyalty transaction can be found under orderInfo.gift_reward_data, which is a JSON object sent in string format. The gift_reward_data values in the following sample contain line breaks for readability's sake.

{
    "documents": [],
    "history": [
        {
            "closed": "2024-04-24T03:14:43-07:00",
            "id": 1,
            "opened": "2024-04-24T03:14:20-07:00",
            "order": "/resources/Order/123/",
            "order_closed_at": "/resources/PosStation/1/",
            "order_closed_by": "/enterprise/User/1/",
            "order_opened_at": "/resources/PosStation/1/",
            "order_opened_by": "/enterprise/User/1/",
            "resource_uri": "/resources/OrderHistory/1/",
            "uuid": "12345678-90ab-cdef-1234-567890abcdef1"
        }
    ],
    "items": [
        {
            "applied_discounts": [],
            "applied_service_fee": [],
            "applied_taxes": [
                {
                    "actual_tax_rate": "10.0000",
                    "fiscal_rate": "2",
                    "flat_tax_units": 0,
                    "id": 1,
                    "local_tax_id": 1,
                    "max_quantity_threshold": 0,
                    "max_threshold": "0.0000",
                    "min_quantity_threshold": 0,
                    "min_threshold": "0.0000",
                    "name": "Prevailing Tax",
                    "on_full_price": true,
                    "order_item": "/resources/OrderItem/1/",
                    "resource_uri": "/resources/AppliedTaxOrderItem/1/",
                    "rounding_type": 0,
                    "tax_amount": "5.8000",
                    "tax_rate": "10.0000",
                    "tax_table": null,
                    "tax_type": 0,
                    "uuid": "3e4231eb-b9b0-424d-90af-c63c3cbf14ea"
                }
            ],
            "appointment": null,
            "appointment_ref_uuid": null,
            "bill_parent": null,
            "catering_complete": false,
            "catering_delivery_date": null,
            "combo_fraction_part": 0,
            "combo_product_set": null,
            "combo_saving_amount": "-8.000000",
            "combo_type": 0,
            "combo_used": "/resources/Product/1/",
            "combo_uuid": "a0dd2300-cf36-4b58-ad59-77ff0d51ac2b",
            "commission_amount": "0.0000",
            "commissions": [],
            "cost": "0.0000",
            "course_number": 0,
            "created_by": "/enterprise/User/1/",
            "created_date": "2024-04-24T03:14:39-07:00",
            "crv_value": 0,
            "cup_qty": 0,
            "cup_weight": 0,
            "date_paid": null,
            "deleted": false,
            "deleted_date": null,
            "dining_option": 8,
            "discount": null,
            "discount_amount": null,
            "discount_code": null,
            "discount_reason": "",
            "discount_rule_amount": null,
            "discount_rule_type": null,
            "discount_tax_amount_included": "0.000000",
            "discount_taxed": null,
            "discounted_by": null,
            "dynamic_combo": "/resources/DynamicCombo/1/",
            "dynamic_combo_slot": null,
            "ervc_type": 0,
            "event_date": null,
            "exchange_discount": null,
            "exchanged": null,
            "exclude_from_discounts": false,
            "expedited": null,
            "external_shipping_address": null,
            "gift_card_number": null,
            "id": 1,
            "ingredientitems": [],
            "initial_price": 48,
            "invoice_document_uuid": null,
            "is_cold": false,
            "is_discounted": false,
            "is_layaway": false,
            "is_store_credit": false,
            "item_type": 0,
            "kitchen_completed": null,
            "manual_unit_price_adjustment": 0,
            "modifier_amount": 10,
            "modifier_cost": "0.0000",
            "modifieritems": [{
                    "conditional_of": null,
                    "id": 111,
                    "is_discounted": false,
                    "is_substituted": false,
                    "mod_type": 0,
                    "modifier": "/resources/Modifier/1/",
                    "modifier_cost": "0.0000",
                    "modifier_price": 10,
                    "no_modifier_substitute": false,
                    "order_item": "/resources/OrderItem/1/",
                    "qty": 1,
                    "qty_type": 0,
                    "resource_uri": "/resources/ModifierItem/111/",
                    "split_combo_data": {},
                    "substitution_of": null,
                    "uuid": "8bbf0535-5740-4ecb-a589-4ae16e522628"
                }
            ],
            "not_returnable": false,
            "on_hold": false,
            "on_layaway": null,
            "order": "/resources/Order/123/",
            "order_local_id": "123",
            "package": null,
            "package_uuid": null,
            "parent_combo_uuid": "a0dd2300-cf36-4b58-ad59-77ff0d51ac2b",
            "parent_uuid": null,
            "price": 48,
            "price_to_display": "0.000000",
            "printed": true,
            "product": "/resources/Product/1/",
            "product_name_override": "Spicy Bacon Spaghetti",
            "pump_date": null,
            "pump_number": null,
            "pure_sales": 58,
            "quantity": 1,
            "reference_discount": "",
            "reference_discounts": "[]",
            "resource_uri": "/resources/OrderItem/1/",
            "returned_establishment": null,
            "sales_tax_exemption_reason": null,
            "scanned_barcode": null,
            "seat_number": 1,
            "sent": false,
            "serial_number": null,
            "service_fee_tax": "0.000000",
            "service_fee_taxed": "0.000000",
            "service_fee_untaxed": "0.000000",
            "service_provider": null,
            "shared": 0,
            "sold_by_weight": false,
            "special_request": null,
            "split_parts": 1,
            "split_type": 0,
            "split_with_seat": 0,
            "start_time": null,
            "station": "/resources/PosStation/1/",
            "tax_amount": 5.8,
            "tax_included": false,
            "tax_rate": 10,
            "tax_rebate": 0,
            "taxed_flag": true,
            "temp_sort": 1713953674,
            "uom": null,
            "updated_by": "/enterprise/User/1/",
            "updated_date": "2024-04-24T03:14:42-07:00",
            "uuid": "f8752191-49be-443a-8b3a-65907a43043c",
            "void_ref_uuid": null,
            "voided_by": null,
            "voided_date": null,
            "voided_reason": "",
            "weight": 0,
            "wholesale_saving_amount": "0.000000"
        }
    ],
    "orderInfo": {
        "applied_discounts": [],
        "applied_service_fee": [],
        "applied_taxes": [
            {
                "dining_options": null,
                "fiscal_rate": "2",
                "id": 123,
                "is_prevailing": true,
                "local_tax_id": 321,
                "max_quantity_threshold": 0,
                "max_threshold": "0.0000",
                "min_quantity_threshold": 0,
                "min_threshold": "0.0000",
                "name": "Prevailing Tax",
                "on_full_price": true,
                "order": "/resources/Order/123/",
                "resource_uri": "/resources/AppliedTaxOrder/123/",
                "rounding_type": 0,
                "tax_rate": "10.0000",
                "tax_table": null,
                "tax_type": 0,
                "uuid": "d37f08b3-652a-4920-ae9d-29bc0854c7e0"
            }
        ],
        "asap": true,
        "auto_grat_pct": 0,
        "bill_number": 0,
        "bill_parent": null,
        "billing_address": null,
        "billing_zip_code": null,
        "bills": [],
        "bills_info": null,
        "bills_type": 0,
        "call_name": null,
        "call_number": null,
        "check_sum": "be27c4364e52fd975a919d44732e3664",
        "closed": true,
        "created_at": "/resources/PosStation/1/",
        "created_by": "/enterprise/User/1/",
        "created_date": "2024-04-24T03:14:20-07:00",
        "crv_taxed": false,
        "crv_value": 0,
        "customer": "/resources/Customer/123/",
        "customer_address_distance": null,
        "customer_birthdate": null,
        "deleted": false,
        "deleted_discounts": "{\"service_fees\":[],\"discounts\":[]}",
        "delivery_address": null,
        "delivery_clock_in": null,
        "delivery_clock_out": null,
        "delivery_distance": null,
        "delivery_duration": null,
        "delivery_employee": null,
        "delivery_estimated_distance": null,
        "device_id": null,
        "dining_option": 8,
        "discount": null,
        "discount_amount": null,
        "discount_code": null,
        "discount_nontaxable_surcharge_included": null,
        "discount_reason": "",
        "discount_rule_amount": null,
        "discount_rule_type": null,
        "discount_tax_amount": null,
        "discount_tax_amount_included": null,
        "discount_taxed": null,
        "discount_total_amount": "0.000000",
        "discounted_by": null,
        "drive_through_data": null,
        "establishment": "/enterprise/Establishment/1/",
        "exchange_discount": null,
        "exchanged": null,
        "exchanged_by": [],
        "external_sync": null,
        "final_total": 77,
        "fleet_service_data": null,
        "gift_reward_data": "",
        "gratuity": 0,
        "gratuity_type": 0,
        "ha_applied": false,
        "has_delivery_info": false,
        "has_history": true,
        "has_items": true,
        "id": 123,
        "invoice_date": null,
        "is_discounted": false,
        "is_invoice": false,
        "is_readonly": false,
        "is_unpaid": false,
        "kitchen_status": 0,
        "last_updated_at": "/resources/PosStation/1/",
        "local_id": "123",
        "loyalty_account_id": null,
        "notes": "",
        "notification_email_sent": false,
        "notification_text_sent": false,
        "number_of_people": 0,
        "orderhistory": ["/resources/OrderHistory/1/"],
        "package": [],
        "packages": [],
        "pickup_data": {
            "call_name": "John",
            "customer_arrived": false,
            "email": "[email protected]",
            "phone_number": "333333333",
            "pickup_type": 1,
            "send_confirmation": true,
            "status": 0,
            "vehicle_color": null,
            "vehicle_make": null,
            "vehicle_type": null
        },
        "pickup_time": "2024-04-24T03:19:00-07:00",
        "points_added": 0,
        "points_redeemed": 0,
        "pos_mode": "T",
        "prevailing_surcharge": 0,
        "prevailing_tax": 10,
        "printed": true,
        "registry_data": null,
        "remaining_due": 0,
        "reporting_id": null,
        "resource_uri": "/resources/Order/123/",
        "rounding_delta": 0,
        "running_tax_number": 0,
        "sent": false,
        "service_charge": 0,
        "service_fee_tax": "0.000000",
        "service_fee_taxed": "0.000000",
        "service_fee_untaxed": "0.000000",
        "smart_order": false,
        "smartpay_gratuity": 0,
        "smartpay_tip": 0,
        "subtotal": 70,
        "surcharge": 0,
        "surcharge_excluded": 0,
        "table": null,
        "table_owner": null,
        "tax": 7,
        "tax_country": "usa",
        "tax_excluded_amount": 7,
        "tax_rebate": 0,
        "tax_rounding_model": 0,
        "taxable_surcharge": 0,
        "taxable_surcharge_excluded": 0,
        "updated_by": "/enterprise/User/1/",
        "updated_date": "2024-04-24T03:14:43-07:00",
        "uuid": "1030441d-a05c-43f1-8505-05609099ac06",
        "vehicle": null,
        "version": 1,
        "virtual_data": {},
        "web_order": false
    },
    "order_exchange": null,
    "payments": [
        {
            "amount": "77.000000",
            "amount_authorized": "0.000000",
            "bill": 0,
            "card_surcharge": "0.000000",
            "card_type": null,
            "cash_drawer": 1,
            "cc_first_name": null,
            "cc_last_name": null,
            "change": "0.000000",
            "created_by": "/enterprise/User/1/",
            "created_date": "2024-04-24T03:14:42-07:00",
            "currency_amount": "77.000000",
            "currency_tip": "0.000000",
            "currency_type": 0,
            "deleted": null,
            "establishment": "/enterprise/Establishment/1/",
            "exchanged": null,
            "executed": false,
            "first_4_cc_digits": null,
            "gratuity": 0,
            "house_account": null,
            "id": 87737,
            "invoice_transition_date": null,
            "last_4_cc_digits": "",
            "online": false,
            "order": "/resources/Order/123/",
            "other_payment_type": null,
            "payer_id": null,
            "payment_date": "2024-04-24T03:14:42-07:00",
            "payment_type": 1,
            "processor_accepted": false,
            "processor_response": null,
            "rate": "1.00",
            "receipt_email": null,
            "refund_transaction_id": null,
            "refunded": false,
            "resource_uri": "/resources/Payment/87737/",
            "rounding_delta": 0,
            "signature_img_url": null,
            "source_type": 1,
            "station": "/resources/PosStation/1/",
            "till_owner": null,
            "tip": "0.000000",
            "transaction_captured": false,
            "transaction_data": null,
            "transaction_id": "1713953682",
            "transaction_status": null,
            "updated_by": "/enterprise/User/1/",
            "updated_date": "2024-04-24T03:14:42-07:00",
            "uuid": "0bf9c357-6526-4688-b94a-b05d82cafd8c"
        }
    ],
    "shell_combo_items": [
        {
            "applied_discounts": [],
            "applied_service_fee": [],
            "applied_taxes": [
                {
                    "actual_tax_rate": "10.0000",
                    "fiscal_rate": "2",
                    "flat_tax_units": 0,
                    "id": 123,
                    "local_tax_id": 321,
                    "max_quantity_threshold": 0,
                    "max_threshold": "0.0000",
                    "min_quantity_threshold": 0,
                    "min_threshold": "0.0000",
                    "name": "Prevailing Tax",
                    "on_full_price": true,
                    "order_item": "/resources/OrderItem/123123/",
                    "resource_uri": "/resources/AppliedTaxOrderItem/123/",
                    "rounding_type": 0,
                    "tax_amount": "7.0000",
                    "tax_rate": "10.0000",
                    "tax_table": null,
                    "tax_type": 0,
                    "uuid": "58b22be2-04f6-4c34-a3a2-57e8be4394c2"
                }
            ],
            "appointment": null,
            "appointment_ref_uuid": null,
            "bill_parent": null,
            "catering_complete": false,
            "catering_delivery_date": null,
            "combo_fraction_part": 0,
            "combo_product_set": null,
            "combo_saving_amount": "0.000000",
            "combo_type": 1,
            "combo_used": null,
            "combo_uuid": "a0dd2300-cf36-4b58-ad59-77ff0d51ac2b",
            "commission_amount": "0.0000",
            "commissions": [],
            "cost": "0.0000",
            "course_number": 0,
            "created_by": "/enterprise/User/1/",
            "created_date": "2024-04-24T03:14:39-07:00",
            "crv_value": 0,
            "cup_qty": 0,
            "cup_weight": 0,
            "date_paid": null,
            "deleted": false,
            "deleted_date": null,
            "dining_option": 8,
            "discount": null,
            "discount_amount": null,
            "discount_code": null,
            "discount_reason": "",
            "discount_rule_amount": null,
            "discount_rule_type": null,
            "discount_tax_amount_included": "0.000000",
            "discount_taxed": null,
            "discounted_by": null,
            "dynamic_combo": null,
            "dynamic_combo_slot": null,
            "ervc_type": 0,
            "event_date": null,
            "exchange_discount": null,
            "exchanged": null,
            "exclude_from_discounts": false,
            "expedited": null,
            "external_shipping_address": null,
            "gift_card_number": null,
            "id": 123123,
            "ingredientitems": [],
            "initial_price": 56,
            "invoice_document_uuid": null,
            "is_cold": false,
            "is_discounted": false,
            "is_layaway": false,
            "is_store_credit": false,
            "item_type": 0,
            "kitchen_completed": null,
            "manual_unit_price_adjustment": 0,
            "modifier_amount": 14,
            "modifier_cost": "0.0000",
            "modifieritems": [],
            "not_returnable": false,
            "on_hold": false,
            "on_layaway": "0.0000",
            "order": "/resources/Order/123/",
            "order_local_id": "123",
            "package": null,
            "package_uuid": null,
            "parent_combo_uuid": null,
            "parent_uuid": null,
            "price": 56,
            "price_to_display": "55.000000",
            "printed": true,
            "product": "/resources/Product/1/",
            "product_name_override": "Combo Test",
            "pump_date": null,
            "pump_number": null,
            "pure_sales": 70,
            "quantity": 1,
            "reference_discount": "",
            "reference_discounts": "[]",
            "resource_uri": "/resources/ShellComboItem/123123/",
            "returned_establishment": null,
            "sales_tax_exemption_reason": null,
            "scanned_barcode": null,
            "seat_number": 1,
            "sent": false,
            "serial_number": null,
            "service_fee_tax": "0.000000",
            "service_fee_taxed": "0.000000",
            "service_fee_untaxed": "0.000000",
            "service_provider": null,
            "shared": 0,
            "sold_by_weight": false,
            "special_request": null,
            "split_parts": 1,
            "split_type": 0,
            "split_with_seat": 0,
            "start_time": null,
            "station": "/resources/PosStation/1/",
            "tax_amount": 7,
            "tax_included": false,
            "tax_rate": 10,
            "tax_rebate": 0,
            "taxed_flag": true,
            "temp_sort": 1713953677,
            "uom": null,
            "updated_by": "/enterprise/User/1/",
            "updated_date": "2024-04-24T03:14:42-07:00",
            "uuid": "a0dd2300-cf36-4b58-ad59-77ff0d51ac2b",
            "void_ref_uuid": null,
            "voided_by": null,
            "voided_date": null,
            "voided_reason": "",
            "weight": 0,
            "wholesale_saving_amount": "0.000000"
        }
    ]
}

Customer Creation or Updates

Upon completion of a customer entry being created or a customer's data being updated, the following sample is a json representation of the Customer record that will be sent via webhook.

{
    "accept_checks": false,
    "account_balance": null,
    "account_limit": null,
    "active": true,
    "address": "1st Ave",
    "addresses": [{
            "active": true,
            "address_type": null,
            "city": "NY",
            "company_name": "comany addr",
            "country": "US",
            "created_date": "2024-04-25T07:32:12.333459",
            "customer": "/resources/Customer/1/",
            "delivery_instructions": "bell",
            "email": "[email protected]",
            "id": 1,
            "latitude": 0,
            "longitude": 0,
            "name": "home",
            "phone_number": "12345678",
            "primary_billing": true,
            "primary_shipping": true,
            "resource_uri": "/resources/CustomerAddress/1/",
            "state": "NY",
            "street_1": "1st Ave",
            "street_2": "",
            "updated_date": "2024-04-25T07:32:12.333539",
            "uuid": "11727761-8a37-4507-956c-3a4057362cda",
            "zipcode": "12345"
        }
    ],
    "birth_date": "1990-04-01T00:00:00",
    "cc_exp": null,
    "cc_first_name": null,
    "cc_last_4_digits": null,
    "cc_last_name": null,
    "charge_account": false,
    "city": "NY",
    "company_name": "noname",
    "contract_expiration": null,
    "created_by": "/enterprise/User/4/",
    "created_date": "2024-04-19T07:30:32.552066",
    "customer_groups": [],
    "customer_xt_uuid": null,
    "deleted": false,
    "discount": null,
    "email": "[email protected]",
    "email_opt_in": null,
    "exp_date": null,
    "expensify_account": null,
    "first_name": "Abu",
    "gender": 0,
    "gift_card_numbers": [],
    "id": 1,
    "image": null,
    "is_visitor": false,
    "last_name": "Dabi",
    "lic_number": null,
    "loyalty_number": null,
    "loyalty_ref_id": null,
    "notes": "note",
    "ok_to_email": true,
    "past_due": null,
    "phone_number": "1234",
    "phone_opt_in": null,
    "picture": null,
    "pin": null,
    "post_opt_in": null,
    "ref_number": "ref code",
    "resource_uri": "/resources/Customer/1/",
    "reward_card_numbers": [],
    "source": null,
    "state": "NY",
    "tax_exempt": false,
    "tax_location": null,
    "third_party_id": null,
    "title": "Test customer",
    "total_purchases": 0,
    "total_visits": 0,
    "track_as_company": false,
    "type": 0,
    "updated_by": "/enterprise/User/4/",
    "updated_date": "2024-04-25T07:33:56.263878",
    "uuid": "4f944638-0ac9-4c12-95b1-037c5d924a1d",
    "vehicles": [],
    "version_date": "2024-04-25T07:33:56.263956",
    "zipcode": "12345"
}

Rewards Card Creation

Upon creation of a Rewards Card, the following is a sample json body representation will be sent to the webhook URL configured to receive Rewards Card creations.

{
  "active": true,
  "address": null,
  "created_by": "/enterprise/User/3144/",
  "created_date": "2021-12-28T21:08:12.568476",
  "current_points": 0,
  "customer": null,
  "error_code": 0,
  "id": 3134,
  "number": "123321",
  "payment_type": 0,
  "resource_uri": "/resources/RewardsCard/3134/",
  "reward_points": {
    "points_by_items": 0,
    "points_by_purchases": 0,
    "points_by_visits": 0
  },
  "total_points": 0,
  "total_purchases": 0,
  "total_visits": 0,
  "updated_by": "/enterprise/User/3144/",
  "updated_date": "2021-12-28T21:08:12.568595"
}

Item Availability status is changed on POS

Separate message for every item upon any change of the availability status initiated from the POS for products or modifiers, or on any change of the availability status done on the POS for the related products/ modifiers/ ingredients, or for all unavailable products/modifiers when the feature is turned off in the settings of MC, the following sample record that will be sent via webhook.

{
  "barcode": "100001009367",
  "id": 622335,
  "instock": false,
  "type": "product"
}

Additional information is provided in the headers:

x-revel-instance (string) - holds instance name
x-revel-event-type (string) - “inout.stock” for our service
x-revel-establishment-id (int) - holds establishment ID

Field descriptions

  • barcode (string) - populated from POS message
  • id (int) - ID for product/modifier - required
  • instock (bool) - availability status of the product/modifier - required
  • type (string) - product or modifier - required

Menu Changed

Example event

{
  "event":"menu.updated"
}

Rules for Menu.Changed Event Firing

The menu.updated event is triggered whenever a change is made to products, modifiers and/or multi-channel and online custom menus and the “Push changes” button is pressed on the management console.

The event is triggered whenever one of the following changes occur and the “Push changes” button is pressed on the Management console:

  1. Any change is made to a custom menu with “Application type” set to “Mode” and “Mode/Station” set to “Online” or “Multi-Channel”.
    1. If the “Mode/Station” setting is changed from "Kiosk", "Bar", "Menu Board", "Online - Catering" or "SmartDining" to “Online” or “Multi-channel” the event will also trigger.
  2. Changes made to Products. Most of the settings and fields trigger the event.
  3. Changes made to Modifiers. Most of the settings and fields trigger the event.
  4. The event will also trigger on EMS level if any of the above changes occur.

For a full list of menu changed webhook triggers, refer to this page.

TimeSheet Entries

When Webhooks are Triggered

Webhooks are activated whenever changes occur to timesheet entries through:

  • Manual Adjustments: Modifications performed in the Management Console or directly on the POS system.
  • POS Actions: When events like clock-ins or clock-outs occur through the POS.

Supported Actions

The following actions generate a webhook payload:

  • Clock In: An employee starts their shift.
  • Clock Out: An employee ends their shift.
  • Break Start: An employee begins a break.
  • Break End: An employee resumes work after a break.
  • Entry Adjustments: An entry is created, adjusted or deleted through POS or Management console.

Timesheet entry webhook Payload sample

{
  "action_type": "Clock Out",
  "break_length": 1,
  "break_type": 2,
  "clock_in": "2024-10-09T11:29:34+03:00",
  "clock_out": "2024-10-09T11:34:45+03:00",
  "created_by": "/enterprise/User/4/",
  "created_date": "2024-10-09T11:29:34+03:00",
  "department_name": "emt-6376",
  "employee": "/resources/Employee/34/",
  "establishment": "/enterprise/Establishment/1/",
  "exempt_salaried": false,
  "id": 68,
  "is_auto_clock_out": false,
  "parent": "/resources/TimeSheetEntry/68/",
  "remarks": "",
  "resource_uri": "/resources/TimeSheetEntry/68/",
  "returned_date": null,
  "role_name": "Owner",
  "role_wage": 20,
  "stage": 0,
  "updated_by": "/enterprise/User/4/",
  "updated_date": "2024-10-09T11:34:45+03:00"
}

FieldExplanationData Type
action_typeDescribes the type of action performed. Possible values:

- Time Worked Created Manually POS
- Time Worked Updated Manually POS
- Time Worked Deleted Manually POS
- Clock In
- Clock Out
- Time Worked Created Manually
- Time Worked Updated Manually
- Time Worked Deleted Manually
String
break_lengthThe duration of the break in minutes.Integer
break_typeThe type of break, represented as an integer (e.g., 1 for lunch, 2 for short breaks).Integer
clock_inThe timestamp when the employee clocked in, in ISO 8601 format.String (DateTime)
clock_outThe timestamp when the employee clocked out, in ISO 8601 format.String (DateTime)
created_byURI pointing to the user or system that created the timesheet entry.String (URI)
created_dateThe timestamp when the entry was originally created, in ISO 8601 format.String (DateTime)
department_nameThe name of the department associated with the timesheet entry.String
employeeA URI pointing to the employee associated with this timesheet entry.String (URI)
establishmentA URI pointing to the establishment or location where the timesheet entry occurred.String (URI)
exempt_salariedIndicates whether the employee is salaried and exempt from overtime calculations (true/false).Boolean
idThe unique identifier for this timesheet entry.Integer
is_auto_clock_outIndicates whether the clock-out action was performed automatically by the system (true/false).Boolean
parentA URI pointing to the parent timesheet entry, if applicable (e.g., for adjustments).String (URI)
remarksAdditional notes or comments associated with the timesheet entry.String
resource_uriThe unique URI for this timesheet entry, useful for referencing or fetching additional data.String (URI)
returned_dateTimestamp indicating when the timesheet entry was returned, if applicable, in ISO 8601 format.String (DateTime)
role_nameThe role of the employee (e.g., Owner, Manager).String
role_wageThe hourly wage or salary associated with the employee's role.Float
stageAn integer representing the stage or status of the timesheet entry (e.g., 0 for active).Integer
updated_byA URI pointing to the user or system that last updated the entry.String (URI)
updated_dateThe timestamp of the most recent update to the timesheet entry, in ISO 8601 format.String (DateTime)

Using the API

Authorization

Endpoint uses JWT authorization. Specific application's client_id and secret must be used to obtain the access_token.

Sample request/response for obtaining JWT token:

curl --request POST --url "https://authentication.revelup.com/oauth/token" --header 'content-type:application/json' --data '{"grant_type":"client_credentials", "client_id":"<value>", "client_secret":"<value>", "audience":"https://api.revelsystems.com"}'
{
    "access_token":"XXXXX.YYYYY.ZZZZZ",
    "expires_in":86400,
    "token_type":"Bearer"
}

Fetch application integrations list

Provides a list of existing integrations under the particular application.

GET https://api.revelsystems.com/external/integrations
Header ParameterTypeDescription
AuthorizationstringRequired. A bearer token i.e. 'Bearer XXXXX.YYYYY.ZZZZZ'
content-typestringRequired. Value application/json
Query ParameterTypeDescription
pageintegerOptional. Page number. Default value is 1, min 1, max 1000000.
pageSizeintegerOptional. Number of records to return per page. Default value is 10, min 1, max 100.

Sample request/response:

curl --request GET --url "https://api.revelsystems.com/external/integrations?page=1&pageSize=10" --header 'Authorization:Bearer XXXXX.YYYYY.ZZZZZ' --header 'content-type:application/json'
{
    "pageSize":10,
    "page":1,
    "totalItems":2,
    "totalPages":1,
    "items":[
        {
            "client_id":"pizza-restaurant",
            "establishments":[2,3,10],
            "full_access":false
        },
        {
            "client_id":"sushi-in",
            "establishments":[1],
            "full_access":false
        }
    ]
}

Fetch application webhook message log

Provides a list of handled webhook messages for existing integrations under the particular application. By default only the failed messages are stored.

GET https://api.revelsystems.com/external/message-log
Header ParameterTypeDescription
AuthorizationstringRequired. A bearer token i.e. 'Bearer XXXXX.YYYYY.ZZZZZ'
content-typestringRequired. Value application/json
Query ParameterTypeDescription
pagestringOptional. A reference to a page.
pageSizeintegerOptional. Number of records to return per page. Default value is 10, min 1, max 100.
statestringOptional. Webhook message state, values : 'invoked', 'failed' or 'retrying'.
instanceNamestringOptional. Instance name.
createdOnStartintegerOptional. Time interval floor value, when message was created in unix epoch time i.e. 1674222412
createdOnEndintegerOptional. Time interval ceiling value, when message was created in unix epoch time i.e. 1674222419

Sample request/response:

curl --request GET \
  --url "https://api.revelsystems.com/external/message-log?page=48U93U2HR0VU93RNIV9P2UN3IRUEVH2IURBVIERBHNIPVQUBRVIB2IBIUBQIUBP2IQUB29UG30V97347Q3B4V7Q3BV8B34VU3B09UV3BV93&pageSize=10&state=failed&instanceName=sushi&createdOnStart=1674222412&createdOnEnd=1674222419" \
  --header 'Authorization:Bearer XXXXX.YYYYY.ZZZZZ' \
  --header 'content-type:application/json'
{
    "next_page": "48U93U2HR0VU93RNIV9P2UN3IRUEVH2IURBVIERBHNIPVQUBRVIB2IBIUBQIUBP2IQUB29UG30V97347Q3B4V7Q3BV8B34VU3B09UV3BV93",
    "items": [
        {
            "id": "4af806e2-4b8d-45dc-8de0-987efe3226f3",
            "instanceName": "sushi",
            "establishmentId": 1,
            "event": "order.finalized",
            "eventTimestamp": 1674222414,
            "applicationId": "045594e2-48e0-46b6-aa54-065b3ec35cd9",
            "webhookUrl": "https://your.webhook.url",
            "payload": "{\"json\":\"payload\"}",
            "state": "failed",
            "createdOn": 1674222419
        }
    ]
}