A valid request URL is required to generate request examples{
"window": {
"from": "2026-07-16",
"to": "2026-07-16"
},
"previousWindow": {
"from": "2026-07-15",
"to": "2026-07-15"
},
"comparison": {
"current": {
"ticketCount": 2,
"grossSalesCents": 7200,
"basketAverageCents": 3600,
"unitsSold": 4,
"vatTotalCents": 1200
},
"previous": {
"ticketCount": 0,
"grossSalesCents": 0,
"basketAverageCents": 0,
"unitsSold": 0,
"vatTotalCents": 0
},
"grossSalesCents": {
"absolute": 7200,
"percent": null
},
"ticketCount": {
"absolute": 2,
"percent": null
},
"unitsSold": {
"absolute": 4,
"percent": null
},
"basketAverageCents": {
"absolute": 3600,
"percent": null
}
},
"byStore": [
{
"key": "store-report",
"metrics": {
"ticketCount": 2,
"grossSalesCents": 7200,
"basketAverageCents": 3600,
"unitsSold": 4,
"vatTotalCents": 1200
}
}
],
"byDay": [
{
"key": "2026-07-16",
"metrics": {
"ticketCount": 2,
"grossSalesCents": 7200,
"basketAverageCents": 3600,
"unitsSold": 4,
"vatTotalCents": 1200
}
}
],
"byCategory": [
{
"category": "coffee",
"grossCents": 7200,
"unitsSold": 4,
"ticketCount": 2
}
]
}{
"error": {
"code": "VALIDATION_FAILED",
"message": "<string>",
"statusCode": 123,
"fieldErrors": [
{
"field": "<string>",
"message": "<string>"
}
]
}
}{
"error": {
"code": "VALIDATION_FAILED",
"message": "<string>",
"statusCode": 123
}
}{
"error": {
"code": "VALIDATION_FAILED",
"message": "<string>",
"statusCode": 123
}
}{
"error": {
"code": "VALIDATION_FAILED",
"message": "<string>",
"statusCode": 123
}
}Windowed sales analytics report
Rolls the per-ticket sales read model up into a windowed analytics report for the Rapports / Analytics screen: the headline KPIs for the [from, to] UTC-day window (YYYY-MM-DD), a period-over-period comparison against the immediately-preceding equal-length window (absolute Δ + %, percent null when the previous window is empty), and breakdowns by store, by day and by product category. Both from and to are REQUIRED — a missing or inverted window 400s. Pass an optional ?store= to narrow. Money is integer cents.
A valid request URL is required to generate request examples{
"window": {
"from": "2026-07-16",
"to": "2026-07-16"
},
"previousWindow": {
"from": "2026-07-15",
"to": "2026-07-15"
},
"comparison": {
"current": {
"ticketCount": 2,
"grossSalesCents": 7200,
"basketAverageCents": 3600,
"unitsSold": 4,
"vatTotalCents": 1200
},
"previous": {
"ticketCount": 0,
"grossSalesCents": 0,
"basketAverageCents": 0,
"unitsSold": 0,
"vatTotalCents": 0
},
"grossSalesCents": {
"absolute": 7200,
"percent": null
},
"ticketCount": {
"absolute": 2,
"percent": null
},
"unitsSold": {
"absolute": 4,
"percent": null
},
"basketAverageCents": {
"absolute": 3600,
"percent": null
}
},
"byStore": [
{
"key": "store-report",
"metrics": {
"ticketCount": 2,
"grossSalesCents": 7200,
"basketAverageCents": 3600,
"unitsSold": 4,
"vatTotalCents": 1200
}
}
],
"byDay": [
{
"key": "2026-07-16",
"metrics": {
"ticketCount": 2,
"grossSalesCents": 7200,
"basketAverageCents": 3600,
"unitsSold": 4,
"vatTotalCents": 1200
}
}
],
"byCategory": [
{
"category": "coffee",
"grossCents": 7200,
"unitsSold": 4,
"ticketCount": 2
}
]
}{
"error": {
"code": "VALIDATION_FAILED",
"message": "<string>",
"statusCode": 123,
"fieldErrors": [
{
"field": "<string>",
"message": "<string>"
}
]
}
}{
"error": {
"code": "VALIDATION_FAILED",
"message": "<string>",
"statusCode": 123
}
}{
"error": {
"code": "VALIDATION_FAILED",
"message": "<string>",
"statusCode": 123
}
}{
"error": {
"code": "VALIDATION_FAILED",
"message": "<string>",
"statusCode": 123
}
}Authorizations
Authorization: Bearer <token>. Accepts EITHER a Keycloak access token (scopes-in-token) OR an opaque POS session token; both resolve to the same pos.* scope vocabulary the route guards enforce.
Response
The windowed report: window, comparison and the store/day/category breakdowns.
The windowed report: window, comparison and the store/day/category breakdowns.

