The parts other systems plug into.
24 documented endpoints across 10 resources at a versioned path, 9 signed webhook events, 12 barcode symbologies, and a portal API your customers and suppliers authenticate against with your shop’s code.
24
Documented endpoints
27
Scopes a key can carry
9
Signed webhook events
140
Operations that take a key
A partner API, versioned and kept apart from the app’s own
The endpoints an integrator uses sit at their own versioned path, separate from the internal API the Polaris screens call. Swagger UI and ReDoc are both served against it, so the reference is the same document the code is.
Every response carries the API version that served it and a request id you can quote back to us when something looks wrong. Every write takes an idempotency key — it is required, not optional, so the retry story is settled before you write any code.
A key is kept as a hash. Lose it and you rotate it.
When you generate a key, what gets stored is a hash of it plus a short prefix to recognise it by in the list. Nobody can read the key back afterwards — not you, and not us. That is the whole point, and it means a lost key is a rotation rather than a lookup.
What a key carries
- 27 scopes, drawn from 9 preset templates
- An IP allowlist
- An origin allowlist
- An endpoint allowlist
- An explicit list of the stores it may touch
- An expiry date
Default rate windows
- A minute
- 60
- An hour
- 1,000
- A day
- 24,000
Requests allowed per window, per key.
Webhooks that give up honestly
9 events cover bills, refunds, customers, orders and reconciliations. Each delivery carries an HMAC signature computed per endpoint, so the receiving system can check the payload came from Polaris and reached it unaltered.
When your endpoint is down, Polaris retries at 30, 120, 300 seconds and then dead-letters the delivery. It stops and says so rather than retrying forever or quietly dropping the event.
One delivery, if it keeps failing
- Retry 1 · 30s
- Retry 2 · 120s
- Retry 3 · 300s
- Dead letter
Where a webhook is allowed to go
The address a target hostname resolves to is pinned before the call goes out, so a DNS answer cannot change between the check and the request. That closes DNS rebinding, where a hostname passes validation and then points somewhere inside your network a moment later.
Refused outright
- Targets that are not HTTPS
- Private and loopback addresses
- Link-local addresses
- Cloud-metadata addresses
A double-tap cannot write the bill twice
140 named operations across the product carry an idempotency key. Bill create, bill payment and bill void each persist the request against that key plus a fingerprint of the request, its method and its path — so a retry replays the original response instead of writing a second row.
A request that is still in flight holds a processing lease for 5 minutes, which is what stops two taps a second apart from racing each other into the ledger.
Barcodes, labels, and the scanner on the counter
12 symbologies are read, with check-digit validation across the EAN, UPC and ITF families. GS1 element strings parse 12 base application identifiers plus net weight, pound and price variants, symbology prefixes and GS1 Digital Link URLs. A product can carry as many barcodes as it needs, each with its own symbology, usage, pack quantity and unit.
The butcher’s scale prints its own barcode
Variable-measure EAN-13 is decoded natively rather than treated as an unknown code. The prefix says what the digits after it mean, so the label the scale printed a minute ago rings up at the counter for the weight it actually measured.
EAN-13 prefix
- 20–23
- An embedded weight
- 24–29
- An embedded price
4 label templates, seeded on first use
| A4 sheet | 36 labels at 50×30mm, four across and nine down |
|---|---|
| Thermal | 50×30mm |
| Thermal | 58×40mm |
| ZPL | Native, at 203 DPI straight to a Zebra |
Receipts print A4 today. Thermal receipts are on the roadmap; labels are already thermal-capable.
A USB scanner needs no driver
It is recognised as a keyboard wedge from its inter-key timing, at a 50 ms threshold. Scanner profiles are set per organisation and carry a 750 ms duplicate window, a symbology allow-list, and a camera mode for a phone.
Scanning survives the connection
The catalogue is snapshotted locally in the browser, and every scan records whether it resolved online or from that local copy. When the line comes back you can see which was which — nothing is silently guessed.
The portal API ships before the app does
A portal account authenticates with a phone number, a password and your shop’s code — so one phone can belong to several Polaris shops without the accounts colliding. A sign-in returns a 30-minute access token behind a 30-day rotating refresh, revocable from the server, and repeated attempts are throttled.
Customers · app in testing
The endpoints are live today: a customer’s own bills, khata, refunds, quotations and loyalty, plus 9 views of how they are actually paying you. The phone app that reads them is still in testing, so today those endpoints are what you build against.
Suppliers · API only
There is no supplier screen to log into. What ships is the API: a supplier’s ledger with you, their purchase orders, returns and ratelists, on the same shop-code sign-in, for their own system to read.
A second branch is a second decision
Access to a store is two-layered: an organisation-level permission, and then a membership on that branch carrying 5 capabilities — sell, refund, manage inventory, adjust ledger and view reports — across 4 store types. The same cashier can ring up sales at the main shop and only read reports at the second one.
The active store travels on a request header, and the middleware refuses a store the person holds no membership for. Switching branches is not a way around the second layer.
Your configuration exports to a file
Export the whole setup and re-import it later, or into another environment. The import shows a category-by-category diff of what would change before a single setting is applied, and it asks for your password first.