POS endpoints
The POS Service (/pos) is DRE's real-time, action-based integration
surface. Despite the name it is not POS-specific — a webshop checkout, a kiosk,
or a call-center order screen calls exactly the same endpoints. It is plain
JSON over REST; there is no readable entity collection on /pos (to read
promotion master data, use the Promotions API).
All endpoints require authentication. All are POST with a
JSON body except the two GET diagnostics (side-effects poll, heartbeat).
POSService is mounted with @protocol: ['odata-v4', 'rest']. Every action is
reachable both as a plain REST call (the /v2/... form documented throughout
this guide) and as an OData V4 unbound action. The REST paths are the canonical
integration surface.
Endpoint map
| Group | Method & path | Purpose | Writes? |
|---|---|---|---|
| Evaluation | POST /pos/v2/evaluate | Price a basket against all active promotions | reads only¹ |
| Evaluation | POST /pos/v2/simulate | What-if pricing — identical logic, never writes | no |
| Confirmation | POST /pos/v2/confirm | Commit a transaction; trigger side effects | yes |
| Confirmation | GET /pos/v2/transactions/{id}/{counter}/side-effects | Poll async side-effect results | no |
| Coupons | POST /pos/coupons/validate | Check a coupon code | no |
| Coupons | POST /pos/coupons/reserve | Soft-hold a coupon for a transaction | yes |
| Coupons | POST /pos/coupons/redeem | Redeem a reserved coupon | yes |
| Coupons | POST /pos/coupons/cancel | Release a reservation | yes |
| Coupons | POST /pos/coupons/activate | Activate a digital coupon (CREATED → ACTIVE) | yes |
| Coupons | POST /pos/coupons/issue | Issue personalized coupons (CRM/marketing) | yes |
| Articles | POST /pos/articles/import | Synchronous article upsert | yes |
| Articles | POST /pos/articles/import-batch | Asynchronous batch article import | yes |
| Health | GET /pos/heartbeat | Connectivity & health diagnostics | no |
¹ evaluate does not change promotion state, but it does establish the
transaction-iteration identity (it assigns transactionCounter). See the
lifecycle.
Evaluation
POST /pos/v2/evaluate
Evaluates a shopping basket against all active promotions and returns the
line-item-centric EvaluateResponseV2: every promotion's effect lives inline
on the line it touched (lineItems[].discounts[]), plus basket totals, a
savings summary, granted free items, coupon results, and recommendations. The
entire request is wrapped in a top-level request object.
Call it on every basket change (each scan, quantity edit, or coupon entry). Full request/response field tables and the canonical example are on the POS Service wire contract.
POST /pos/v2/simulate
Identical evaluation logic and identical EvaluateResponseV2 shape, but
strictly read-only: it does not redeem coupons, consume budgets, or write
audit logs, and the response carries meta.isSimulation: true. Use it for
webshop cart previews, "what would I save" widgets, and the two simulator-only
flags includeInactive and includeMissedPromotions.
Confirmation
POST /pos/v2/confirm
Commits a transaction and triggers its side effects: budget consumption,
coupon redemption, loyalty, calculation audit log, and post-purchase coupon
generation. Requires the full iteration identity
(header.transactionId + header.transactionCounter). See the
Evaluate → Confirm lifecycle for the full flow
and the sync-vs-async split.
GET /pos/v2/transactions/{transactionId}/{transactionCounter}/side-effects
Polls the asynchronous side-effects job for a confirmed transaction. On BTP,
the secondary side effects (coupon redemption, loyalty, receipt, post-purchase
coupons, webhooks) run in the background after confirm returns. The response
reports status, timing, and the concrete results — including generated
postPurchaseCoupons[]. Cached server-side for ~1 second to dampen tight
polling loops.
Coupons
Six coupon actions cover the full lifecycle. The state machine, when each transition fires, generation, and post-purchase issuance are documented on the Coupon lifecycle page; the exact request/response shapes are on the wire contract.
| Endpoint | One-liner |
|---|---|
validate | Is this code usable right now? (read-only) |
reserve | Soft-hold ACTIVE → RESERVED, returns a reservationId |
redeem | RESERVED → REDEEMED by reservationId (not idempotent) |
cancel | Release a hold RESERVED → ACTIVE (idempotent) |
activate | Digital coupon CREATED → ACTIVE (customer activates in app) |
issue | Create personalized coupons for one or many customers (CRM) |
The coupons field on evaluate/confirm is an array of objects
([{ "code": "…" }]), not bare strings — see
POS API — Coupons wire-format.
Article import
POST /pos/articles/import
Synchronous upsert (create if new, update by articleNumber). Each article is
processed independently — one failure does not abort the batch. The body wraps
the array in articles.
POST /pos/articles/import-batch
Asynchronous batch import with job tracking. Returns immediately with a
jobId; monitor progress via GET /admin/ArticleImportJobs({jobId}). Use this
for large catalogs. Field tables are on the
POS Service wire contract.
Health
GET /pos/heartbeat
Returns connectivity and health diagnostics: status, version, mode,
btpConnectivity, lastSync, pendingTransactions, promotionsLoaded,
uptime. On a local-store instance it reflects circuit-breaker state and the
pending transaction queue; on BTP it returns a simplified status. Useful as a
readiness probe in your integration's health checks.
See also
- POS Service wire contract — full request/response field tables and the canonical example.
- Evaluate → Confirm lifecycle — how the endpoints fit together across a transaction.
- Promotion scenarios & actions — what each promotion type produces in the response.