API Reference
Hyvä POS is in closed beta
Hyvä POS is currently in a closed beta (pilot phase) with a small group of merchants. It is not yet generally available: the App Store release follows the pilot, and features and configuration may still change, possibly in backwards-incompatible ways, before the general release. Want to take part? Sign up at hyva.io/pos.
The Hyvä POS module exposes its entire surface as regular Magento web API routes under /rest/V1/pos/. The register app is another API client: activation, config sync, staff login, receipt sync, and returns all go through the routes below, and your own integrations can call the same routes.
Authentication and Authorization
Authenticate as you would against any Magento REST endpoint:
- Bearer token: an integration access token or admin token in the
Authorization: Bearer <token> header. This is what the register app uses: the access token entered during store setup.
- OAuth 1.0a: for server-to-server integrations registered under System > Extensions > Integrations.
Every route declares an ACL resource in the module's webapi.xml. Scope a token to what it needs:
| ACL resource |
Grants access to |
Hyva_Pos::locations |
All read and day-to-day device calls: config, locations, terminals, heartbeat, held carts, credits, RMA, pickups, shipping |
Hyva_Pos::locations_manage |
Location and terminal create/update/delete, terminal activation |
Hyva_Pos::staff_manage |
Staff reads, staff authentication, session validation |
Hyva_Pos::staff_manage_edit |
Staff create/update/delete, location assignments, lockout clearing |
Hyva_Pos::staff_roles / Hyva_Pos::staff_roles_manage |
Role reads / role create/update/delete |
Hyva_Pos::receipts |
Receipt sync, lookups, receipt email |
Hyva_Pos::pos |
Admin-level reads: audit-log listing, telemetry report export |
Magento_Customer::manage |
The pay-by-invoice credit-limit read, the newsletter routes and the customer-insights read. They reuse the core customer ACL, since they expose nothing that core customer endpoints don't already |
The integration role used by a register device needs the full Hyva_Pos tree plus the standard Magento sales, catalog, and customer resources the register reads.
Conventions
- JSON in, JSON out, standard Magento web API envelope. Errors return
{"message": "...", "parameters": [...]} with HTTP 400 (validation and save errors), 401 (authentication and device-identity mismatches), 404 (entity not found), or 409 (a return or refund that cannot proceed yet, with an outcome in parameters; see RMA).
- Request bodies use the camelCase parameter names from the service interfaces (
activationCode, deviceIdentifier, terminalId). Entity payloads use snake_case field names and are wrapped in a key named after the parameter: {"location": {...}}, {"staff": {...}}, {"terminal": {...}}, {"role": {...}}.
- Three config endpoints (
pos/config, pos/terminals/:terminalId/config, pos/postcode-patterns) return a JSON string: the service serializes the object, then the web API framework encodes that string again. Parse the response body, then parse the resulting string.
- List endpoints (
locations, terminals, staff, roles, receipts) take standard Magento searchCriteria query parameters, for example GET /rest/V1/pos/staff?searchCriteria[pageSize]=200.
- Receipt sync and order placement are keyed by the client-generated sale id, so retries are safe.
- Terminal-scoped calls (activation, deactivation, heartbeat, license refresh) carry a
deviceIdentifier; the server verifies it against the registered terminal and rejects mismatches.
How Config Sync and Enforcement Work
Settings flow to a device in one payload. GET /V1/pos/terminals/:terminalId/config returns the global config (everything under Stores > Configuration > Hyvä POS), the terminal's location row, the staff and roles who may sign in there, and a resolved_config that layers terminal overrides over location values over global defaults. The heartbeat response carries a config_hash; when it changes, the device re-pulls the full config payload.
Configuration flows one way: a terminal does not write location settings back to Magento. A setting a cashier changes on the device stays on that device. Each lockable setting has a lock flag under Stores > Configuration > Hyvä POS > Lock Settings (hyva_pos_lock/enforcement/*); the flags travel to the device in the enforcement block of pos/config, where a locked setting takes Magento's value and its settings screen is read-only. See Configuration for the full flag list.
Routes by Area
| Method |
Route |
Purpose |
GET |
/V1/pos/config |
Global POS configuration, defaults, enforcement flags |
GET |
/V1/pos/terminals/:terminalId/config |
Unified per-terminal bootstrap payload |
GET |
/V1/pos/postcode-patterns |
Per-country postcode validation patterns |
GET |
/V1/pos/order-statuses |
Registered order statuses for picker UIs |
| Method |
Route |
Purpose |
GET |
/V1/pos/locations /:locationId /code/:code |
List and fetch locations |
POST/PUT/DELETE |
/V1/pos/locations /:locationId |
Create, update, delete locations |
GET |
/V1/pos/terminals /:terminalId |
List and fetch terminals |
POST/PUT/DELETE |
/V1/pos/terminals /:terminalId |
Create, update, delete terminals |
POST |
/V1/pos/terminals/activate |
Bind a device with a one-time activation code |
POST |
/V1/pos/terminals/deactivate |
Release the device binding |
POST |
/V1/pos/terminals/:terminalId/heartbeat |
Periodic check-in: device identity, config hash, license status |
POST |
/V1/pos/terminals/:terminalId/license/refresh |
Force a license refresh from hyva.io |
| Method |
Route |
Purpose |
GET |
/V1/pos/staff /:staffId |
List and fetch staff |
POST/PUT/DELETE |
/V1/pos/staff /:staffId |
Create, update, delete staff |
GET/POST/DELETE |
/V1/pos/staff/:staffId/locations /:locationId |
Read, assign, unassign location access |
POST |
/V1/pos/staff/authenticate |
Email + passcode login; returns a staff session |
POST |
/V1/pos/staff/session/validate |
Validate a staff session token |
POST |
/V1/pos/staff/:staffId/unlock |
Clear a login lockout early |
GET/POST/PUT/DELETE |
/V1/pos/roles /:roleId |
Role CRUD with granular permission keys |
| Method |
Route |
Purpose |
POST |
/V1/pos/receipts |
Sync a completed sale's receipt (idempotent by sale id) |
GET |
/V1/pos/receipts /:receiptId /by-increment-id/:incrementId |
List and fetch receipts |
POST |
/V1/pos/receipts/email |
Email a rendered receipt to the customer |
| Method |
Route |
Purpose |
GET |
/V1/pos/held-carts/location/:locationId |
The location's shared parked carts |
POST |
/V1/pos/held-carts · /:heldCartId/recall |
Park a cart; claim a parked cart |
DELETE |
/V1/pos/held-carts/:heldCartId · /uuid/:cartUuid |
Discard by id or by cart UUID |
| Method |
Route |
Purpose |
GET |
/V1/pos/credits/balance/:customerId · /giftcard/:code |
Balances; gift-card validation |
POST |
/V1/pos/credits/applicable · /refund |
What a cart may spend of a credit kind; refund to a balance |
POST |
/V1/pos/orders/:orderId/due-payments |
Collect the credit due an order still owes |
GET |
/V1/pos/orders/:orderId/points-earned |
The reward points the vendor credited for an order |
| Method |
Route |
Purpose |
POST |
/V1/pos/customer-validate · /V1/pos/customers |
Pre-validate; create with boundary re-validation |
POST |
/V1/pos/customer-prices |
Customer-specific prices from the resolver pool |
GET |
/V1/pos/customers/:customerId/credit-limit |
Available credit for pay-by-invoice |
GET |
/V1/pos/wishlist/:customerId |
The customer's wishlist at the register |
GET |
/V1/pos/customers/:customerId/rule-usage/:ruleId |
How often the customer used a cart price rule and its coupon |
GET |
/V1/pos/catalog-rule-prices · /V1/pos/fixed-product-taxes |
Catalog rule prices and fixed product taxes for the offline cache |
GET |
/V1/pos/newsletter/status |
A customer email's newsletter state |
POST |
/V1/pos/newsletter/subscribe · /unsubscribe |
Subscribe or unsubscribe an email |
GET |
/V1/pos/customer-insights/:customerId |
The Customer Insights sheet's statistics and sections |
| Method |
Route |
Purpose |
GET |
/V1/pos/rma/order/:orderId · /:rmaId · /open |
Returnables, single return, open-returns list |
GET |
/V1/pos/rma/options · /eligibility/:orderId |
The provider's reasons, conditions and resolutions; what an order can still return |
POST |
/V1/pos/rma · /process |
Create a return; one-call create + credit memo + resolution |
POST |
/V1/pos/rma/:rmaId/process · /receive · /resolve · /settle · /comment |
The staged in-store workflow |
PUT |
/V1/pos/rma/:rmaId/status |
Transition a return's status |
POST |
/V1/pos/rma/:rmaId/cancel-refund · /close |
Cancel a parked in-store refund; close an open return |
POST |
/V1/pos/refunds/preview |
The credit memo a refund would book, never saved |
GET |
/V1/pos/rma/refund-attempts/:attemptId |
One refund attempt through the original payment's gateway |
POST |
/V1/pos/rma/refund-attempts/:attemptId/reconcile · /resolve |
Settle an uncertain attempt: ask the gateway again, or record what its records show |
| Method |
Route |
Purpose |
GET |
/V1/pos/locations/:locationId/pickups |
The location's pickup queue |
POST |
/V1/pos/orders/:orderId/pickup-completion · /pickup-cancellation |
Complete or cancel a pickup |
GET |
/V1/pos/products/:childSku/bundle-parents |
Bundles containing this product |
POST/GET |
/V1/pos/shipping-rates · /shipping-config · /carriers |
Rates and carrier configuration |
POST/GET |
/V1/pos/orders/:orderId/ship-with-label · /V1/pos/shipments/:shipmentId/shipping-label |
Create and retrieve carrier labels |
| Method |
Route |
Purpose |
POST |
/V1/pos/layaways/:orderId/payments · /cancel |
Deposits and top-ups; cancellation with fee |
POST |
/V1/pos/self-checkout/otp/request · /verify |
Email one-time-code sign-in for kiosk customers |
| Method |
Route |
Purpose |
POST/GET |
/V1/pos/audit-log |
Submit device audit entries; list them (admin resource) |
POST/GET |
/V1/pos/telemetry · /report |
Submit diagnostics; export the report (admin resource) |