Skip to content

Device Profiles

Overview

Device Profiles are reusable configuration templates assigned to kiosk devices. Instead of configuring each kiosk individually, you create a profile once and assign it to one or more devices at a location. The profile controls the kiosk's menus, dining options, idle behaviour, screensaver, schedule, receipt options, customer flow, customer identification, and order-number display.

Key Purpose: Create reusable configuration templates for kiosk devices.

Purpose

This page lets you create and manage configuration profiles that drive the kiosk experience: dining options, default and extra menus, idle settings, schedule, receipt handling, customer-flow layout, customer identification, and order-number display.

Key Concepts

  • Device Profile: A named, location-scoped configuration template assigned to one or more devices. Each profile is created for a specific location_id.
  • Profile family selector: The New Device Profile dialog renders a family selector. The Kiosk family is always offered and still creates a profile whose type the backend hardcodes to DeviceTypes::Kiosk (app/Services/BackOffice/DeviceProfileService.php line 71). A second family, Kitchen Display, appears in that selector only when the merchant is running the first-party Upvendo POS (isFirstPartyPosActive()); it creates a separate KdsProfile model (type fixed to DeviceTypes::KitchenDisplay) through its own /back-office/kds-profiles routes and opens the shared editor with ?type=kds to show the KDS-only sections (Prep & Orders, Timers, Sound). The selector control itself renders for everyone — a non-first-party merchant simply sees a single Kiosk option. POS profiles do not exist in this surface at all: the family map enumerates only kiosk, printer and KDS. Printer profiles are no longer options-only, but they are not managed here either — they have their own page, Device Management → Printer Profiles (/device-management/printer-profiles), gated firstPartyPosOnly on top of the same device-profile permissions. See Printers. (Verified: upvendo-backoffice/src/views/device-profiles/forms/components/NewDeviceProfileDialog.vue lines 36-49, the KDS entry added only when isFirstPartyPosActive() at line 43; src/utils/deviceProfileFamily.ts lines 12-31; src/views/device-profiles/forms/kds/ contains PrepAndOrders.vue, Timers.vue, Sound.vue, KdsDurationField.vue; app/RawModels/KdsProfile.php line 169; routes/api/backoffice/kds-profiles.php lines 31-49.)
  • Where the KDS gate leaks: hiding the create option is not the whole gate. The profile list's type filter always offers "Kitchen Display", to every merchant — it is appended to the server's options list unconditionally. Selecting it together with a location switches the table to /back-office/kds-profiles, which is behind the first-party-pos middleware, so a non-first-party merchant gets a 403 and the back office shows the backend's message, "This feature is only available to merchants using the first-party Upvendo POS." So: for a non-first-party merchant the KDS profile family cannot be created (no option in the dialog) but can be navigated to from the filter, where it errors rather than showing an empty table. (Verified: upvendo-backoffice/src/views/device-profiles/DeviceProfiles.vue lines 131-135 build typeOptions with no first-party check, lines 125-126 and 154-161 switch the source; app/Http/Middleware/EnsureFirstPartyPos.php lines 42-53.)
  • Dining Options: Each profile has two slots, dining_option_1 and dining_option_2, each chosen from For Here, Takeout, or None. The two slots must differ.
  • Idle Timeout: Ends an in-progress session and clears entered data after inactivity. Standard uses the backend-returned values (warning after 45s, shown for 15s); Custom lets you set both values (minimum 1 second each).
  • Idle Screensaver: A separate, optional full-screen image shown on an untouched kiosk after a configured number of minutes — distinct from the idle timeout.
  • Device Schedule: Controls when the kiosk is active — Default follows the location's hours, Custom uses per-day time ranges, Deactivated turns scheduling off.
  • ReloadMenu Event: Saving (create or update) a profile fires a ReloadMenu event so assigned devices re-sync their configuration and menu data.

Actions

Create Device Profile

Navigate to Device Management → Device Profiles, then add a new profile. Enter a unique name, pick the location, configure the two dining options, set up default and optional extra menus, choose idle settings, optionally enable the screensaver, set the schedule, and configure the remaining customer-flow / receipt / identification options. Requires the create-device-profile permission.

Edit Device Profile

Open an existing profile to modify its settings. Saving fires a ReloadMenu event so assigned devices re-sync. The profile's Assigned Devices section (visible only when editing) lists the devices currently using it. Requires the edit-device-profile permission.

Delete Device Profile

Remove a profile. Deletion is blocked while any device is still assigned to it — all devices must be reassigned first. Requires the delete-device-profile permission.

Configure Menus

Add a default menu and optionally extra menus served alongside it. When the profile's "override default menu" toggle is off, the location's in-house default menu is used; when on, the profile's own default_menu_id (and any extra_menu_ids) apply.

Enable Idle Screensaver

Turn the idle screensaver on, set the number of minutes of inactivity before it appears, and upload a screensaver image. The screensaver shows on an untouched kiosk; it is separate from the idle timeout that resets the session.

Business Rules

  • Profile names are validated for uniqueness within the tenant connection (UniqueInConnectionWithModel).
  • dining_option_1 and dining_option_2 must be different. The request computes is_dining_option_valid = (dining_option_1 !== dining_option_2); if they are equal, validation fails with "The dining options is invalid."
  • Dining-option values are restricted to DiningOptions::deviceProfile() = For Here, Takeout, None.
  • When Use custom pictures is on, an image is required for each dining-option slot that is not None (max 10 MB each).
  • Idle timeout: idle_timeout_type is standard or custom. For custom, both idle_timeout_seconds and show_warning_for_seconds are required and must be at least 1.
  • Idle screensaver: when idle_screensaver.enabled is true, idle_screensaver.minutes and an uploaded screensaver image are required.
  • Schedule: schedule_type is Default, Custom, or Deactivated. For Custom, each day requires an is_available flag and, when available, times entries with from/to in H:i format.
  • menu_item_columns must be 2 or 3 (defaults to 2).
  • order_number_display must be queue_number, order_number, or both.
  • Profile deletion is blocked when getDeviceCount() > 0, aborting with HTTP 400 and the message "Profile is still used by devices."

Location

  • Backoffice Route: /device-management/profiles (route name device-management-profiles; create at /new-profile, edit at /edit/:id)
  • Navigation: Device Management → Device Profiles (device-profiles.nav-title, subject device-profile)
  • Backend Controller: app/Http/Controllers/Api/BackOffice/DeviceProfileController.php
  • Backend Routes: routes/api/backoffice/device-profiles.php (prefix /back-office/device-profiles)
  • Backend Model: app/RawModels/DeviceProfile.php
  • Backoffice Page: src/pages/device-management/profiles/index.vue
  • Backoffice Form: src/views/device-profiles/DeviceProfileForm.vue (sub-forms in src/views/device-profiles/forms/)
  • Backoffice Store: src/store/modules/deviceProfile.ts

Fields

Profile Name

PropertyValue
Field IDname
LabelProfile Name
TypeText
RequiredYes
ValidationUnique within the tenant connection

Description: Name for this configuration profile.


Location

PropertyValue
Field IDlocation_id
LabelLocation
TypeSelect
RequiredYes (on create)

Description: The location this profile belongs to. Required when creating a profile (exists:locations,_id); not changed on edit.


Default Menu

PropertyValue
Field IDdefault_menu / default_menu_id (with custom_default_menu)
LabelDefault Menu
TypeMenu selector

Description: The menu served to kiosks using this profile. When custom_default_menu is off the profile falls back to the location's in-house default menu; when on, default_menu_id is required and used.


Extra Menus

PropertyValue
Field IDextra_menus / extra_menu_ids
LabelExtra Menus
TypeMenu list

Description: Additional menus served alongside the default menu. Only applicable when custom_default_menu is on (extra_menu_ids.* are required strings).


Dining Option 1

PropertyValue
Field IDdining_option_1
LabelDining Option 1
TypeSelect
OptionsFor Here, Takeout, None
RequiredYes

Description: First dining-option slot. Must differ from dining_option_2.


Dining Option 2

PropertyValue
Field IDdining_option_2
LabelDining Option 2
TypeSelect
OptionsFor Here, Takeout, None
RequiredYes

Description: Second dining-option slot. Must differ from dining_option_1.


Use Custom Pictures for Dining Options

PropertyValue
Field IDuse_custom_pictures_for_dining_options
LabelUse Custom Pictures
TypeToggle
Defaultfalse

Description: When on, you can upload an image for each non-None dining option (dining_option_1_image, dining_option_2_image; max 10 MB each). Stored as dining_option_1_content_id / dining_option_2_content_id.


Idle Timeout

PropertyValue
Field IDidle_timeout_type, idle_timeout_seconds, show_warning_for_seconds
LabelIdle Settings
TypeRadio (Standard / Custom) + Number (seconds)
Optionsstandard, custom
Defaultstandard (seconds 45 / warning 15)

Description: Ends an in-progress session and clears entered data after inactivity.

Business Logic:

  • Standard: warning after 45 seconds, shown for 15 seconds (backend-returned values).
  • Custom: set idle_timeout_seconds ("give warning after") and show_warning_for_seconds ("show warning for"); both required, minimum 1.

Idle Screensaver

PropertyValue
Field IDidle_screensaver.enabled, idle_screensaver.minutes, screensaver_image (stored as screensaver_content_id)
LabelIdle Screensaver
TypeToggle + Number (minutes) + Image upload
DefaultOff (minutes: null)

Description: An optional full-screen image shown on an untouched kiosk after the configured idle minutes. Separate from the idle timeout. When enabled, both minutes and an uploaded image are required.


PropertyValue
Field IDmenu_item_columns
LabelMenu Layout
TypeSelect
Options2, 3
Default2

Description: Number of columns used to lay out menu items in the customer flow.


Order Number Display

PropertyValue
Field IDorder_number_display
LabelOrder Number Display
TypeRadio
Optionsqueue_number, order_number, both
Defaultboth

Description: Which identifier is shown to the customer after an order is placed — queue number, order number, or both.


Customer Identification

PropertyValue
Field IDallow_customer_identification, customer_identification_methods
LabelCustomer Identification
TypeToggle + method checkboxes
Methodsmember_code (default on), email, phone
DefaultOff

Description: When enabled, customers can identify themselves using the enabled methods. With loyalty active, identified customers see their points and rewards. (Kiosk-app behaviour: not-verified-here.)


Sell Without Stock

PropertyValue
Field IDsell_without_stock
LabelSell Without Stock
TypeToggle
Defaultfalse

Description: Whether out-of-stock items can still be ordered. The toggle is shown only when the location has tracked inventory.


Reset Language On Order Complete

PropertyValue
Field IDreset_language_on_order_complete
LabelReset Language On Order Complete
TypeToggle
Defaultfalse

Description: Whether the kiosk resets to the default language after an order completes.


Use Pager

PropertyValue
Field IDuse_pager, pager_instructions
LabelUse Pager
TypeToggle + instructions (title max 200, subtitle max 300)
Defaultfalse

Description: Whether the kiosk hands out a pager, plus the title/subtitle instructions shown to the customer (only when on).


Receipt Options

PropertyValue
Field IDreceipt_options.print, receipt_options.email, receipt_options.phone, auto_print_receipt
LabelReceipt Settings
TypeCheckboxes + Auto-print toggle
Defaultprint: true, email: true, phone: false; auto_print_receipt: false

Description: Which receipt-delivery options are offered and whether receipts auto-print. The manual print option is hidden when auto_print_receipt is on.


Section Selection

PropertyValue
Field IDsection_selection_enabled, section_ids
LabelSection Selection
TypeToggle + section list (max 6)
DefaultOff

Description: When enabled, the kiosk lets the customer pick a section/table. section_ids is required when enabled.


Order Instructions

PropertyValue
Field IDorder_instructions.enabled, order_instructions.use_same_for_all, order_instructions.all, order_instructions.for_here, order_instructions.takeout
LabelOrder Instructions
TypeToggle + textareas (max 300 each)
Defaultenabled: false, use_same_for_all: true

Description: Optional instruction text shown to the customer — either one message for all orders, or separate text per dining option.


Device Schedule

PropertyValue
Field IDschedule_type, schedule
LabelSchedule
TypeRadio (Default / Custom) + per-day time ranges; Deactivated via separate action
OptionsDefault, Custom, Deactivated
DefaultDefault

Description: When the kiosk is active. Default follows the location's hours; Custom uses per-day is_available + times (from/to, H:i); Deactivated turns scheduling off.


Note on tipping: Tip collection is not a device-profile field. Tipping is read from the location's in-house settings (collect_tips). A Tipping.vue component exists in the source tree but is not wired into the profile form.

Business Logic

Profile Lifecycle

Create / edit profile (location-scoped, type hardcoded to Kiosk)


Validate (StoreDeviceProfileRequest)


Store / update via DeviceProfileService


Fire ReloadMenu(location_id, "device_profile", profile_id)


Assigned devices re-sync configuration + menu data

Deletion Guard

Delete profile request


getDeviceCount() for this profile

   > 0  │  == 0
   ▼    │
abort(400)│  delete profile
"Profile  │  (+ activity log)
is still  │
used by   │
devices"  │

Relations

Depends On

  • Locations: A profile is created for a specific location; default menu and schedule fall back to location settings.
  • Menus: Default and extra menus are served via the profile.

Affects

  • Kiosk: Devices assigned to the profile take their menus and settings from it.

Examples

Standard Kiosk Profile (custom default menu, both numbers)

json
{
  "name": "Standard Kiosk",
  "location_id": "loc-123",
  "dining_option_1": "For Here",
  "dining_option_2": "Takeout",
  "use_custom_pictures_for_dining_options": false,
  "custom_default_menu": true,
  "default_menu_id": "menu-main",
  "extra_menu_ids": [],
  "idle_timeout_type": "standard",
  "idle_screensaver": { "enabled": false },
  "menu_item_columns": 2,
  "order_number_display": "both",
  "schedule_type": "Default",
  "receipt_options": { "print": true, "email": true, "phone": false },
  "auto_print_receipt": false
}

Fast Food Profile (custom idle, 3 columns)

json
{
  "name": "Fast Food",
  "location_id": "loc-123",
  "dining_option_1": "For Here",
  "dining_option_2": "Takeout",
  "idle_timeout_type": "custom",
  "idle_timeout_seconds": 60,
  "show_warning_for_seconds": 15,
  "idle_screensaver": { "enabled": false },
  "menu_item_columns": 3,
  "order_number_display": "both",
  "sell_without_stock": false,
  "schedule_type": "Default"
}

Takeout-Only Profile (one slot set to None)

json
{
  "name": "Takeout Only",
  "location_id": "loc-123",
  "dining_option_1": "Takeout",
  "dining_option_2": "None",
  "idle_timeout_type": "standard",
  "idle_screensaver": { "enabled": false },
  "menu_item_columns": 2,
  "order_number_display": "queue_number",
  "schedule_type": "Default"
}

Cafe Profile (screensaver + customer identification)

json
{
  "name": "Cafe Kiosk",
  "location_id": "loc-123",
  "dining_option_1": "For Here",
  "dining_option_2": "Takeout",
  "idle_timeout_type": "standard",
  "idle_screensaver": { "enabled": true, "minutes": 5 },
  "menu_item_columns": 2,
  "order_number_display": "order_number",
  "allow_customer_identification": true,
  "customer_identification_methods": { "member_code": true, "email": false, "phone": false },
  "schedule_type": "Custom"
}

FAQs

  • "Can I create a KDS or POS profile here?" For POS, a flat no — no POS profile family exists in this surface at all. For KDS, in practice still no, but for a different reason than it used to be: a Kitchen Display family does exist in the New Device Profile dialog, but it is shown only to merchants running the first-party Upvendo POS, and the /back-office/kds-profiles API group is behind the first-party-pos middleware (403 otherwise). So the answer is a gate, not a missing selector — the old wording ("the type is hardcoded to Kiosk and there is no type selector") is no longer accurate, since the selector is there and shows a single Kiosk option for everyone else.
  • "Why does filtering the profile list by 'Kitchen Display' show an error?" Because that filter value is offered to everyone but the endpoint behind it is not. If your account is not on the first-party Upvendo POS, picking Kitchen Display switches the table to the KDS profile API, which refuses the request with "This feature is only available to merchants using the first-party Upvendo POS." Clear the type filter to get the normal kiosk/printer list back. Nothing about your permissions or your data is wrong. (Verified: upvendo-backoffice/src/views/device-profiles/DeviceProfiles.vue lines 131-135 and 154-161; routes/api/backoffice/kds-profiles.php line 31.)
  • "What happens when I save a profile that has assigned devices?" A ReloadMenu event fires for the profile's location, so devices using it re-sync their configuration and menu data.
  • "Why can't I delete a profile?" Deletion is blocked while any device is still assigned to it. Reassign those devices to another profile first.
  • "Can different kiosks show different menus or settings?" Yes. Assign them to different profiles — each profile carries its own menus, dining options, idle behaviour, schedule, and more.
  • "What's the difference between Idle Timeout and the Idle Screensaver?" The timeout ends an in-progress session and clears entered data after inactivity; the screensaver shows a custom image on an untouched kiosk after a set number of minutes. They are configured separately in Idle Settings.
  • "What are the schedule types?" Default follows the location's hours, Custom uses per-day time ranges, and Deactivated turns scheduling off.

Troubleshooting

  • Cannot delete profile → A device is still assigned (getDeviceCount() > 0). Reassign those devices to a different profile, then delete.
  • "The dining options is invalid"dining_option_1 and dining_option_2 are set to the same value. They must differ.
  • Screensaver won't save → When the idle screensaver is enabled, both the minutes value and an uploaded image are required.
  • Custom idle timeout rejected → In Custom mode, both "give warning after" and "show warning for" must be at least 1 second.
  • Sell Without Stock toggle missing → It only appears when the location has tracked inventory.
  • Menu not appearing on the kiosk → If the profile uses a custom default menu, confirm default_menu_id is set; otherwise the location's in-house default menu is used. (Kiosk-app rendering: not-verified-here.)
  • "This feature is only available to merchants using the first-party Upvendo POS" on the profile list → The type filter is set to Kitchen Display, which reads from a first-party-only API. Clear the filter. The Kitchen Display option is offered to every merchant even though the data behind it is not. (Verified: upvendo-backoffice/src/views/device-profiles/DeviceProfiles.vue lines 131-135; routes/api/backoffice/kds-profiles.php line 31.)
  • No Kitchen Display option in the New Device Profile dialog → Expected unless the merchant runs the first-party Upvendo POS; the family is added to the selector only when that check passes, so a single Kiosk option is the normal view. It is not a permission problem and cannot be enabled from the back office. (Verified: NewDeviceProfileDialog.vue lines 43-48; config/pos-providers.php line 49 keeps the upvendo provider unselectable.)
  • "You need the 'View Device Profile' permission to assign a Kitchen Display profile" → Usually literal: grant VIEW_DEVICE_PROFILE to the role. But a non-first-party merchant with a grandfathered Kitchen Display sees the same message, because the back office reports every 403 from the KDS options endpoint as a permission problem while the real refusal is the first-party gate. In that case the permission is not the barrier. (Verified: src/store/modules/kdsProfile.ts lines 151-154; message at src/plugins/i18n/locales/modules/en/devices.ts line 49; gate at routes/api/backoffice/kds-profiles.php line 31.)