{"title":"POS actions reference","slug":"pos-actions-reference","url":"https://support.storeconnect.com/articles/pos-actions-reference","url_markdown":"https://support.storeconnect.com/articles/pos-actions-reference.md","subtitle":null,"summary":"Complete reference for all available POS actions: the identifiers, parameters, and behavior for actions that can be triggered from action buttons, JavaScript, or Liquid templates.","type":"Developer_Documentation","video_url":"","keywords":"pos, actions, scAction, cart, nav, print, sync, modal, reference","last_modified":"2026-08-21T07:12:35+0000","body_markdown":"## Overview\n\nPOS actions are named operations that control the behavior of the StoreConnect POS — adding items to the cart, navigating screens, printing receipts, and more. Every button in the POS UI corresponds to an action.\n\nActions can be triggered in three ways:\n\n- **Action items** — Salesforce records (POS Action Items) assigned to action groups. Configured through the StoreConnect console.\n- **`scAction()` JavaScript function** — a global function available in custom views and Liquid templates rendered by the POS.\n- **Liquid `{% action %}` tag** — triggers an action inline within a Liquid template.\n\n## Triggering actions\n\n### Via action items\n\nAction items are configured in Salesforce under POS Action Groups. Set the **Action** field to the action identifier and the **Params** field to a semicolon- or ampersand-separated key-value string.\n\n### Via scAction()\n\nThe `scAction()` function is available globally within the POS browser context:\n\n```javascript\n\nscAction(action, params)\n```\n\n| Argument | Type | Required | Description |\n|----------|------|----------|-------------|\n| `action` | String | Yes | Action identifier (e.g. `'cart:add_product'`) |\n| `params` | Object | No | Key-value pairs of action parameters |\n\n**Example:**\n\n```javascript\n\nscAction('cart:add_product', { product_code: 'SKU123', quantity: 2 })\n\nscAction('cart:discount', { discount_type: 'percentage', discount_amount: 10 })\n```\n\n### Via Liquid templates\n\nUse Liquid to pass context variables from the current record into action parameters:\n\n\n```html\n\n\u003cbutton onclick=\"scAction('print:receipt', { order_sc_id: '{{ record.id }}' })\"\u003e\n  Print receipt\n\u003c/button\u003e\n```\n\n\n## Parameter format\n\nParameters in the **Params** field of a POS Action Item can use semicolons or ampersands as separators:\n\n```\nproduct_code=SKU123\u0026quantity=2\u0026unit_discount=5\nproduct_code=SKU123;quantity=2;unit_discount=5\n```\n\nLiquid template variables are resolved before the action runs:\n\n\n```\norder_sc_id={{ record.id }};print_template_sfid=a2cMn00003s4X88IAE\n```\n\n\n## Action chaining\n\nAn action item can have a **Next Action Item** configured. When the first action completes, the next action runs automatically. Some actions pass context to the next action — for example, `cart:add_product` passes `{{ cart_item_sc_id }}` so a follow-up action can reference the newly added item.\n\n---\n\n## Cart actions\n\n### cart:add_product\n\nAdds a product to the current cart.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `product_id` | String | No* | Product Salesforce ID |\n| `product_code` | String | No* | Product code (alternative to `product_id`) |\n| `quantity` | Number | No | Quantity to add (default: 1) |\n| `unit_price` | Number | No | Override unit price. Locks the price — prevents repricing if the customer changes. |\n| `unit_discount` | Number | No | Apply a unit discount |\n| `name` | String | No | Override the product name on the cart item |\n| `serial_numbers` | String | No | Comma-separated serial numbers |\n| `pending` | Boolean | No | Mark the item as pending (default: false) |\n| `pay_now` | String | No | Deposit mode: `\"all\"`, `\"none\"`, a dollar amount, or `\"N%\"` |\n\n*Either `product_id` or `product_code` is required.\n\nIf the product has variants, variable pricing, is a rental, or uses voucher assets, the product selection modal opens before the item is added.\n\n**Next action context:**\n\n```\nproduct_id        — product Salesforce ID\ncart_item_sc_id   — SC ID of the new cart item\n```\n\n**Example:**\n\n```\nproduct_code=SKU123\u0026quantity=2\u0026pay_now=50%\n```\n\n---\n\n### cart:item:update\n\nUpdates an existing cart item. Can change quantity, price, discount, name, serial numbers, pending status, or swap the product entirely.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `cart_item_sc_id` | String | Yes | SC ID of the cart item to update |\n| `quantity` | Number | No | New quantity (must be ≥ 1) |\n| `unit_price` | Number | No | New unit price (non-negative) |\n| `unit_discount` | Number | No | New unit discount (non-negative) |\n| `name` | String | No | Override display name |\n| `serial_numbers` | String | No | Comma-separated serial numbers |\n| `pending` | Boolean | No | Set pending status (`\"true\"` or `\"false\"`) |\n| `product_id` | String | No† | Product Salesforce ID to swap to |\n| `product_code` | String | No† | Product code to swap to |\n| `pay_now` | String | No | Deposit mode: `\"all\"`, `\"none\"`, a dollar amount, or `\"N%\"` |\n\n†For product swapping, provide exactly one of `product_id` or `product_code`. Cannot swap to rental products, products with variants, or asset-backed vouchers. If the item is linked to a fulfillment, that fulfillment is flagged for reconfirmation.\n\n**Example (swap product from a layout record):**\n\n\n```\ncart_item_sc_id={{ record.id }};product_id=01tXXXXXXXXXXXXXXX\n```\n\n\n---\n\n### cart:item:remove\n\nRemoves a cart item. Cleans up any associated rental asset holds and fulfillments.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `cart_item_sc_id` | String | Yes | SC ID of the cart item to remove |\n\n---\n\n### cart:add_contact\n\nAssigns a customer to the current cart.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `contact_sc_id` | String | Yes | SC ID of the contact to assign |\n\n---\n\n### cart:remove_contact\n\nRemoves the customer from the current cart. Takes no parameters.\n\n---\n\n### cart:discount\n\nApplies a cart-wide discount, distributed across eligible items.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `discount_amount` | Number | Yes | Discount value |\n| `discount_type` | String | Yes | `\"amount\"` or `\"percentage\"` (legacy: `\"dollar\"` or `\"percent\"`) |\n\nDiscounts that exceed the user's permitted maximum or the product minimum sell price rules are rejected with an alert.\n\n**Example:**\n\n```\ndiscount_amount=15;discount_type=percentage\n```\n\n---\n\n### cart:deposit:set\n\nSets pay-now deposit amounts across all items in the current cart.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `pay_now` | String | Yes | `\"all\"`, `\"none\"`, a dollar amount (e.g. `\"50\"`), or a percentage (e.g. `\"25%\"`) |\n\n| Value | Effect |\n|-------|--------|\n| `\"all\"` | Pay full price on all items |\n| `\"none\"` | Pay nothing now on all items |\n| `\"25%\"` | Each item's deposit is 25% of its discounted unit price |\n| `\"50\"` | Distributes $50 proportionally across all items |\n\nIndividual product minimum deposit rules are respected.\n\n---\n\n### cart:resume\n\nResumes a previously saved (parked) cart. If the cart is already linked to an existing order, an alert is shown and the cart cannot be resumed.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `cart_sc_id` | String | Yes | SC ID of the cart to resume |\n\n---\n\n### cart:toggle\n\nToggles the cart panel open or closed. If the POS is not on the home screen, navigates home first, then opens the cart. Takes no parameters.\n\n---\n\n### cart:item:cancel\n\nCancels a cart item on a cart linked to an open order. Sets the item's quantity to 0, which mirrors to the linked order line and stamps it cancelled for the audit trail. Cancelled items remain visible (muted/struck-through) but contribute zero to totals; restoring the quantity reverses the cancellation.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `cart_item_sc_id` | String | Yes | SC ID of the cart item to cancel |\n\n---\n\n### cart:new\n\nParks the current cart and makes a fresh empty cart active. Does not create or touch any order record. To start a cart linked to a new open order, use `cart:new:open_order`. Takes no parameters.\n\n---\n\n### checkout:start\n\nStarts checkout from a cart, mimicking a click of the cart's \"Pay\" button. Runs the same validation the Pay button uses (empty cart, pending/expired items, customer-required rules, discount limits, etc.) and shows an explanatory alert without navigating if a check fails. When nothing is owed (a pure refund or fully-deposited cart), it creates the order immediately and navigates to the order record instead of the payment screen.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `order_sc_id` | String | No | Salesforce ID of an existing order to check out (additional payment or refund capture). Takes precedence over `cart_sc_id`. |\n| `cart_sc_id` | String | No | Salesforce ID of the cart to check out. Defaults to the active cart; if different, that cart is resumed first. |\n\n---\n\n## Order actions\n\n### order:return\n\nProcesses a return for an existing order. Loads returnable items into the cart as refund lines and navigates to the home screen.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `order_sc_id` | String | Yes | Salesforce ID of the order to return |\n| `order_item_sc_ids` | String | No | Comma-separated order item Salesforce IDs to return. Omit to return all returnable items. |\n| `quantities` | String | No | Comma-separated quantities per item (parallel to `order_item_sc_ids`). Defaults to full remaining quantity. |\n| `amounts` | String | No | Comma-separated amounts per item — `\"N%\"` or a dollar value. |\n| `new_cart` | String | No | `\"true\"` to park the current cart and start fresh |\n\nItems with pending fulfillments or zero remaining quantity are skipped automatically.\n\n**Example (return specific items at partial amounts):**\n\n```\norder_sc_id=abc-123;order_item_sc_ids=id1,id2;quantities=1,3;amounts=100%,50%\n```\n\n---\n\n## Open order actions\n\nOpen orders are editable Order records (`s_c__pos_order_type__c = \"OPEN\"`) linked to a cart, used outside the standard checkout flow (for example, hospitality tabs). **These actions require the store variable `pos.open_orders.enabled` to be set.** All of them work offline — changes are enqueued and sync to Salesforce on reconnect.\n\n### cart:new:open_order\n\nCreates a new open order. If the current cart is empty, the order is linked to it; otherwise the current cart is parked and the order is linked to a fresh cart. The order is created as a shell (no payments or fulfillments).\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `memo` | String | No | Short note saved on the order (max 80 characters); shown as a banner on the cart |\n\n---\n\n### cart:update:open_order\n\nConverts the current active cart into a new open order and links it, preserving the cart's items and customer. Errors if the cart is already linked to an order — use `open_order:update` to edit a linked order instead.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `memo` | String | No | Short note saved on the order (max 80 characters) |\n\n---\n\n### open_order:submit\n\nCommits the active cart to its linked open order (the hospitality \"submit to the kitchen\" action). Reprices and transmits the full order as an idempotent upsert keyed on each line's `sc_id`, splits multi-quantity lines into individual units, and creates fulfillments for newly-submitted lines. Commit only — it does not clear the cart (pair with `cart:new` for a \"Submit \u0026 clear\" button). Requires the active cart to be linked to an open order. Takes no parameters.\n\n---\n\n### open_order:update\n\nEdits the memo of the open order already linked to the active cart (saves immediately). Only the memo can be changed this way.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `memo` | String | No | New memo (max 80 characters). Omit the parameter entirely to no-op; pass a blank value to clear the memo. |\n\n---\n\n### order:cancel\n\nCancels an open order so it no longer appears in the Open Orders list. If the cancelled order is the one currently loaded in the cart, a fresh cart is started automatically.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `order_sc_id` | String | Yes | SC ID of the open order to cancel |\n\n---\n\n### order:resume\n\nResumes an open order for continued editing by making its linked cart the active cart (the previously active cart is parked, not discarded). Does not navigate — the caller is responsible for navigation.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `order_sc_id` | String | Yes | SC ID of the open order to resume |\n\n---\n\n## Navigation actions\n\nNavigation actions change the active screen. They do not take effect if the POS is in a state that prevents navigation (e.g. an active modal blocking the UI).\n\n### Screen navigation\n\n| Action | Description |\n|--------|-------------|\n| `nav:home` | Navigate to the home screen |\n| `nav:checkout` | Navigate to the checkout screen |\n| `nav:authentication` | Navigate to the authentication screen |\n| `nav:register` | Navigate to the register selector |\n| `nav:settings` | Navigate to settings |\n| `nav:labels` | Navigate to the barcode label printing interface |\n\n### List views\n\n| Action | Description |\n|--------|-------------|\n| `nav:customers` | Navigate to the customers list |\n| `nav:products` | Navigate to the products list |\n| `nav:orders` | Navigate to the orders list |\n| `nav:carts` | Navigate to the carts list |\n| `nav:fulfillments` | Navigate to the fulfillments list |\n| `nav:suppliers` | Navigate to the suppliers list |\n| `nav:stock_adjustments` | Navigate to stock adjustments |\n| `nav:stock_requests` | Navigate to stock requests |\n\n### Record views\n\n| Action | Parameters | Description |\n|--------|------------|-------------|\n| `nav:customers:record` | `customer_id` | View a customer record |\n| `nav:customers:create` | — | Open the customer creation form |\n| `nav:customers:update` | `customer_id` | Open the customer edit form |\n| `nav:orders:record` | `order_id` | View an order record |\n| `nav:carts:record` | `cart_id` | View a cart record |\n| `nav:products:record` | `product_id` | View a product record |\n\n### Fulfillment and station views\n\n| Action | Parameters | Description |\n|--------|------------|-------------|\n| `nav:fulfillments:record` | `fulfillment_id` | View a fulfillment record |\n| `nav:fulfillment_stations` | `register_id` (optional) | Navigate to the fulfillment stations overview |\n| `nav:fulfillment_stations:record` | `station_id` | View a fulfillment station record |\n| `nav:station_fulfillments` | `station_id`, optional `view`, `statuses`, `sort` | Open a station's ticket workspace |\n| `nav:outlet_stations` | — | Navigate to the outlet stations screen |\n\nEach action above has an `open:*` counterpart (e.g. `open:station_fulfillments`) that opens the same target as a pushed sub-page — see [Open actions](#open-actions). For `nav:station_fulfillments`: `view` is `grid` (default), `rail`, `double-rail`, `flex-grid`, `rows`, or `list`; `statuses` is a comma-separated subset of `requested`, `preparing`, `ready_for_pickup`, `complete` (default `requested,ready_for_pickup`); `sort` is `field:direction` where `field` is `updated` or `status` (default `status:asc`).\n\n### Custom layouts and views\n\n| Action | Parameters | Description |\n|--------|------------|-------------|\n| `nav:layout` | `layout` or `layout_sc_id`, optional `record_id` | Navigate to a custom POS layout |\n| `nav:view` | `view` or `view_sc_id`, optional `record_id`, `object_name` | Navigate to a custom POS view |\n\n### Session management\n\n| Action | Parameters | Description |\n|--------|------------|-------------|\n| `nav:session_end` | — | End the current shift |\n| `nav:session_add_user` | — | Add a user to the session |\n| `nav:session_start_user` | `user_id` | Start session for a specific user |\n| `nav:session_start_balance` | `user_id`, `amount` | Start session with an opening balance |\n| `nav:disconnect_register` | — | Navigate to the register disconnection screen |\n\n---\n\n## Open actions\n\nOpen actions display a standalone full-screen page, separate from the main POS navigation stack.\n\n| Action | Parameters | Description |\n|--------|------------|-------------|\n| `open:customers:create` | — | Open the customer creation form as a standalone page. Does not assign the customer to the cart. |\n| `open:customers:record` | `customer_id` (required) | Open a customer record as a standalone page |\n| `open:customers:update` | `customer_id` (required) | Open the customer edit form as a standalone page |\n| `open:orders:record` | `order_id` | Open an order record as a standalone page |\n| `open:fulfillments:record` | `fulfillment_id` | Open a fulfillment record as a standalone page |\n| `open:fulfillment_stations` | `register_id` (optional) | Open the fulfillment stations overview as a standalone page |\n| `open:fulfillment_stations:record` | `station_id` | Open a fulfillment station record as a standalone page |\n| `open:station_fulfillments` | `station_id`, optional `view`, `statuses`, `sort` | Open a station's ticket workspace as a standalone page |\n| `open:outlet_stations` | — | Open the outlet stations screen as a standalone page |\n| `open:layout` | `layout` or `layout_sc_id`, optional `record_id` | Open a custom POS layout as a standalone page |\n| `open:view` | `view` or `view_sc_id`, optional `record_id`, `object_name` | Open a custom POS view as a standalone page |\n\n---\n\n## Modal actions\n\n### modal:close\n\nCloses the topmost modal. Takes no parameters.\n\n---\n\n### modal:open\n\n**Deprecated.** A generic modal opener that dispatches to a specific modal action based on the parameters supplied (`url` → `modal:open:url`, `layout_identifier` → `modal:open:layout`, `alert` → `modal:open:alert`, otherwise `modal:open:view`). Use the specific `modal:open:*` action instead.\n\n---\n\n### modal:open:alert\n\nOpens an alert modal.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `alert` | String | Yes | Alert content or identifier |\n\n---\n\n### modal:open:email_receipt\n\nOpens a modal to send an email receipt for an order. Pre-fills the recipient address with the contact's email if available.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `order_sc_id` | String | Yes | SC ID of the order |\n\n---\n\n### modal:open:pay_by_link\n\nOpens a modal to email a payment link for an order with an outstanding balance. Includes a QR code option for a scannable payment link.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `order_sc_id` | String | Yes | SC ID of the order |\n\n---\n\n### modal:open:return\n\nOpens an interactive return modal for an order, allowing the user to select items and quantities before processing.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `order_sc_id` | String | Yes | SC ID of the order |\n\n---\n\n### modal:open:url\n\nOpens a modal displaying a custom URL. Liquid context variables are resolved before the URL is rendered.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `url` | String | Yes | URL to load in the modal |\n\n---\n\n### modal:open:view\n\nOpens a custom POS view inside a modal. Additional parameters are merged into the Liquid context for the view.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `view_identifier` | String | Yes | Identifier of the view to display |\n| *(additional)* | * | No | Any extra parameters become Liquid context variables |\n\n---\n\n### modal:open:layout\n\nOpens a custom POS layout inside a modal. Context from the action chain is available to the layout's Liquid templates.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `layout_identifier` | String | Yes | Identifier of the layout to display |\n\n---\n\n### modal:open:action_group\n\nOpens a POS Action Group as a modal drill-in grid, rendering the group's action items.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `group_id` | String | Yes | Salesforce ID of the Action Group to render |\n| `name` | String | No | Header label for the modal (defaults to the group's name) |\n\n---\n\n### modal:open:cancel_order_confirm\n\nOpens a confirmation modal for cancelling an open order. On confirm, dispatches `order:cancel`; the modal stays open on failure so the user can retry.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `order_sc_id` | String | Yes | SC ID of the open order to cancel |\n\n---\n\n### modal:open:new_open_order\n\nOpens a confirmation modal for creating a new open order, with an optional memo input. On confirm, dispatches `cart:new:open_order` with the entered memo.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `memo` | String | No | Pre-fills the modal's memo input (max 80 characters) |\n\n---\n\n### modal:open:station_ticket\n\nOpens a station ticket in a modal, looked up from the live sync stream.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `fulfillment_id` | String | Yes | SC ID of the fulfillment/ticket to display |\n| `select_mode` | Boolean | No | `\"true\"` to open in the line-selection view |\n| `select_order_item_id` | String | No | Order item to preselect (used with `select_mode`) |\n\n---\n\n## Station actions\n\nActions for managing fulfillment stations and their tickets. The `*:confirm` and `*:picker` variants open a modal to gather input before performing the operation. Most take an optional `station_name` used only for the confirmation message or snackbar.\n\n### station:activate\n\nSets a fulfillment station's status back to active (restored).\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `station_id` | String | Yes | SC ID of the station to activate |\n| `station_name` | String | No | Display name used in the confirmation message |\n\n---\n\n### station:activate:confirm\n\nOpens a confirmation modal for activating a station. On confirm, dispatches `station:activate`.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `station_id` | String | Yes | SC ID of the station |\n| `station_name` | String | No | Display name shown in the modal |\n\n---\n\n### station:degrade\n\nSets a fulfillment station's status to degraded.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `station_id` | String | Yes | SC ID of the station to degrade |\n| `station_name` | String | No | Display name used in the confirmation message |\n\n---\n\n### station:degrade:confirm\n\nOpens a confirmation modal for degrading a station. On confirm, dispatches `station:degrade`.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `station_id` | String | Yes | SC ID of the station |\n| `station_name` | String | No | Display name shown in the modal |\n| `fallback_station_name` | String | No | Name of the fallback station shown in the modal |\n\n---\n\n### station:cover\n\nStarts covering a station from the active register. Shows a confirmation snackbar.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `station_id` | String | Yes | SC ID of the station to cover |\n| `station_name` | String | No | Display name shown in the snackbar |\n\n---\n\n### station:cover:picker\n\nOpens the picker modal for choosing stations to cover. Takes no parameters.\n\n---\n\n### station:cover:confirm\n\nOpens a confirmation modal for covering a station. On confirm, starts covering it.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `station_id` | String | Yes | SC ID of the station |\n| `station_name` | String | No | Display name shown in the modal |\n\n---\n\n### station:stop-cover\n\nStops covering a station from the active register. Shows a confirmation snackbar.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `station_id` | String | Yes | SC ID of the station to stop covering |\n| `station_name` | String | No | Display name shown in the snackbar |\n\n---\n\n### station:move\n\nBulk-moves the given fulfillments (tickets) to another station.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `station_id` | String | No | SC ID of the source station |\n| `destination_station_id` | String | Yes | SC ID of the destination station |\n| `destination_name` | String | Yes | Destination display name (shown in the confirmation alert) |\n| `fulfillment_ids` | String | Yes | Comma-separated fulfillment SC IDs to move |\n\n---\n\n### station:move:picker\n\nOpens the bulk-move picker modal. Three entry modes: with `station_id` + `fulfillment_ids`, jumps straight to the destination picker; with `station_id` only, opens at ticket selection; with `station_ids` (comma-separated), opens at the source picker.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `station_id` | String | No | Source station to lock |\n| `fulfillment_ids` | String | No | Comma-separated fulfillment SC IDs to pre-select |\n| `station_ids` | String | No | Comma-separated station SC IDs to offer as sources |\n| `station_name` | String | No | Display name shown in the modal |\n\n---\n\n### station:assign-register\n\nAssigns a fulfillment station to a register, or unassigns it when `register_id` is blank. The change is queued as an unsaved change against the station record, so it works offline. The previous register stops auto-printing for the station as soon as the change syncs, and the new register picks up the station's pending tickets once it is online with a fulfillment printer. Shows a confirmation snackbar.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `station_id` | String | Yes | SC ID of the station to reassign |\n| `register_id` | String | No | SC ID of the register to assign. Leave blank to unassign the station. |\n| `station_name` | String | No | Display name shown in the snackbar (defaults to \"Station\") |\n| `register_name` | String | No | Register name shown in the snackbar (defaults to \"register\") |\n\n---\n\n### station:assign-register:picker\n\nOpens the register-assignment picker modal. Three entry modes: with `station_id`, opens straight at register selection for that station; without `station_id`, opens at a station-picker first step; with `intent` set to `unassign`, opens straight at the unassign confirmation. On confirm, dispatches `station:assign-register`.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `station_id` | String | No | SC ID of the station to assign |\n| `station_name` | String | No | Display name shown in the modal |\n| `current_register_id` | String | No | SC ID of the station's current register, used to preselect it |\n| `intent` | String | No | `unassign` to open at the unassign confirmation step |\n\n---\n\n### station:auto-print:on\n\nTurns on auto-printing of new tickets for a station the active register is covering. Tickets already held for the station count as historical and are not printed; only tickets created after the switch-on point print automatically. Shows a snackbar when `station_name` is supplied.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `station_id` | String | Yes | SC ID of the station |\n| `station_name` | String | No | Display name shown in the snackbar. Omit to suppress the snackbar. |\n\n---\n\n### station:auto-print:off\n\nTurns off auto-printing of new tickets for a covered station. Shows a snackbar when `station_name` is supplied.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `station_id` | String | Yes | SC ID of the station |\n| `station_name` | String | No | Display name shown in the snackbar. Omit to suppress the snackbar. |\n\n---\n\n### station:printer:picker\n\nOpens the printer picker modal for a station.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `station_id` | String | Yes | SC ID of the station |\n| `station_name` | String | No | Display name shown in the modal |\n\n---\n\n### station:reprint\n\nReprints a station ticket using the same print-and-mark pipeline as auto-print. Requires a connected register.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `fulfillment_id` | String | Yes | SC ID of the ticket (fulfillment) to reprint |\n\n---\n\n## Print actions\n\nAll print actions require a printer to be connected and configured in POS settings. Errors are displayed as alerts if the template or printer cannot be resolved.\n\n### print:receipt\n\nPrints an order receipt using the configured receipt template, or an override template.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `order_sc_id` | String | Yes | SC ID of the order |\n| `print_template_sfid` | String | No | Salesforce ID of a receipt-context print template to use instead of the settings template |\n\n---\n\n### print:cart\n\nPrints the current cart contents using the configured cart template, or an override template.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `cart_sc_id` | String | No | SC ID of the cart to print. Defaults to the active cart. |\n| `print_template_sfid` | String | No | Salesforce ID of a cart-context print template to use instead of the settings template |\n\n---\n\n### print:labels\n\nPrints product labels using the configured label template, or an override template.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `product_sfids` | String | Yes | Comma-separated list of product Salesforce IDs |\n| `quantity` | Number | No | Labels to print per product (default: 1) |\n| `print_template_sfid` | String | No | Salesforce ID of a label-context print template to use instead of the settings template |\n\n**Example (from a product layout record):**\n\n\n```\nproduct_sfids={{ record.sfid }};quantity=2\n```\n\n\n---\n\n### print:quest_receipt\n\nPrints the Quest Airpay TAP transaction receipt for an order. Uses a hardcoded template. For a customized receipt, use `print:receipt` with a custom template that accesses `payment.gateway_receipt`.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `order_sc_id` | String | Yes | SC ID of the order |\n\n---\n\n### print:template\n\nPrints using any print template directly, regardless of context type. Additional parameters are passed as Liquid context to the template. Supports all printer types — thermal receipt, PDF document, and label.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `print_template_sfid` | String | Yes | Salesforce ID of the print template to use |\n| *(additional)* | * | No | Any extra parameters become Liquid context variables in the template |\n\n**Example:**\n\n\n```\nprint_template_sfid=a1b2c3d4e5f6g7h8;order_id={{ record.id }}\n```\n\n\n---\n\n## Sync actions\n\n### sync\n\nPerforms an incremental sync, downloading only records that have changed since the last sync. Does nothing if a sync is already in progress. Takes no parameters.\n\n---\n\n### sync:full\n\nPerforms a full re-sync, re-downloading all data. Can optionally target a single object.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `object` | String | No | Object to re-sync. Accepts Salesforce API names (e.g. `product2`, `s_c__cart__c`) or legacy aliases: `orders`, `stores`, `fulfillments`. Omit to re-sync everything. |\n\n---\n\n### sync:pause\n\nPauses syncing for all objects currently syncing. In-progress page requests complete before stopping. The paused state persists across page reloads. Takes no parameters.\n\n---\n\n### sync:resume\n\nResumes syncing for paused objects and re-syncs them immediately.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `object` | String | No | Object to resume. Accepts the same values as `sync:full`. Omit to resume all paused objects. |\n\n---\n\n### sync:clear\n\nDeletes local records then re-downloads them from Salesforce. Unlike `sync:full` (which only resets the cursor), `sync:clear` removes the local rows first, so stale records no longer in scope are cleared out. Certain records the running app still needs are preserved (current outlet, register, shift, user, the active price book, and any orders not yet pushed). A confirmation modal is shown before executing.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `object` | String | No | Object to clear. Accepts a sync object API name (e.g. `product2`, `s_c__cart__c`) or a legacy alias (`orders`, `stores`, `fulfillments`). Omit to clear every table. |\n\n---\n\n## Record actions\n\nThese actions create, update, or delete records in the POS local database (IndexedDB). The target table must use `s_c__sc_id__c` as its primary key.\n\n### record:save\n\nCreates or updates a record. An SC ID is auto-generated if not provided.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `object_name` | String | Yes | API name of the object/table |\n| *(additional)* | * | No | Any extra parameters become field values on the record |\n\n---\n\n### record:delete\n\nDeletes a record from a local database table.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `object_name` | String | Yes | API name of the object/table |\n| `record_sc_id` | String | Yes | SC ID of the record to delete |\n\n---\n\n## System actions\n\n### lock\n\nLocks the POS to the session screen, requiring users to re-authenticate before continuing. Takes no parameters.\n\n---\n\n### close\n\nCloses the current view or modal by popping it from the page stack. If the closed entry is a non-modal page with a modal behind it, both are closed. Takes no parameters.\n\n---\n\n### cash_drawer:open\n\nSends an open command to the connected cash drawer via the receipt printer integration. Takes no parameters.\n\n---\n\n### printer:remove\n\nRemoves a paired printer from POS settings.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `printer_id` | String | Yes | ID of the printer to remove |\n\n---\n\n## Unsaved changes actions\n\nActions for managing the local persistence queue of unsaved changes (**Settings → Advanced → Manage data → Unsaved changes**). Retrying is disabled while offline.\n\n### unsaved_changes:retry\n\nResets a single unsaved change to `pending` and re-sends it immediately rather than waiting for the next automatic retry.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `change_id` | String | Yes | The `changeId` of the unsaved change to retry |\n\n---\n\n### unsaved_changes:retry_all\n\nResets every non-succeeding unsaved change (stalled, exhausted, invalid) to `pending` and re-sends them all immediately. Blocked changes are left alone — they clear on their own once the change they depend on succeeds. Takes no parameters.\n\n---\n\n### unsaved_changes:discard\n\nDiscards a single unsaved change, removing it from the queue so it is never sent. The optimistic local value is not reverted — it remains until the next server sync overwrites that record.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `change_id` | String | Yes | The `changeId` of the unsaved change to discard |"}