Appearance
HQ
The HQ API provides multi-store reporting and analytics for RORC POS operators. All endpoints require the rorcex:reports.view permission and honour the X-Organization-Scope: CASCADE header to expand the result set across child organizations.
These endpoints read RORCex's synced aggregate store, continuously copied from each store's RORC back office by background pollers (typically within ~5 minutes) — they do not query the lane live, so they stay available even when a lane is offline. Two exceptions: …/timeseries reads the CommerceStream materialization, and …/drift is populated by the RORC two-way-interface pipeline (currently empty). See Data Sources & Freshness.
Get Dashboard
Return a per-store KPI summary for all stores accessible to the caller: today's sales-so-far, yesterday's close, the 4-week weekday median, and today's variance against that median. This is a high-level snapshot — per-dimension rollups (department, cashier, terminal, hour) are returned by Get Store Summary.
GET /v1/hq/dashboardAuthentication: OAuth Token (service_account or user) Permission: rorcex:reports.view
Request Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
date | string | No | Business day to treat as "today", Y-m-d format. Defaults to today. |
Response
json
{
"as_of": "2026-06-12T03:23:25+00:00",
"stores": [
{
"store_id": "org_00000k1L2m3N4o5",
"today": {
"business_day_date": "2026-05-05",
"status": "A",
"source": "backoffice",
"last_snapshot_at": "2026-06-09 01:05:38",
"total_sales_so_far": 8420.50,
"freshness_label": "polled 6 min ago"
},
"yesterday": {
"business_day_date": "2026-05-04",
"status": "C",
"source": "backoffice",
"reconciled_at": null,
"total_sales": 8100.75
},
"median_4_week": { "weekday_avg_sales": 7800.00, "sample_size": 4 },
"variance_today_vs_median_pct": 7.95
}
]
}Status: 200 OK
Response Fields
| Field | Type | Description |
|---|---|---|
as_of | string (ISO 8601) | When the dashboard was generated. |
stores | array | One entry per store in scope. |
store_id | string | Store organization hashkey (note: this endpoint keys it store_id). |
today | object | null | Today's in-progress business day; null if none. Includes status (A active / C closed / F finalized), source, last_snapshot_at, total_sales_so_far, and a human freshness_label. |
yesterday | object | null | Yesterday's business day; null if none. Includes status, source, reconciled_at, and total_sales. |
median_4_week | object | weekday_avg_sales and sample_size for the same weekday over the prior 4 weeks. |
variance_today_vs_median_pct | number | Percent variance of total_sales_so_far against median_4_week.weekday_avg_sales. |
Errors
See /reference/errors.
Run Comparison
Run a cross-store metric comparison across a date range for a single dimension.
POST /v1/hq/comparisonAuthentication: OAuth Token (service_account or user) Permission: rorcex:reports.view
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
stores | array | Yes | List of store organization hashkeys to include |
dimension | string | Yes | Grouping dimension: department, cashier, terminal, or hourly |
metric | string | Yes | Metric to compare: sales_amount, transaction_count, or item_count |
from | string | Yes | Start of date range, Y-m-d |
to | string | Yes | End of date range, Y-m-d |
json
{
"stores": ["org_00000k1L2m3N4o5", "org_00000a1B2c3D4e5"],
"dimension": "department",
"metric": "sales_amount",
"from": "2026-06-01",
"to": "2026-06-11"
}Response
json
{
"rows": [
{
"store_org_id": "org_00000k1L2m3N4o5",
"dimension_value": "001",
"metric_value": 41820.75
},
{
"store_org_id": "org_00000a1B2c3D4e5",
"dimension_value": "001",
"metric_value": 38204.00
}
]
}Status: 200 OK
Response Fields
| Field | Type | Description |
|---|---|---|
rows | array | One entry per (store, dimension value) combination |
store_org_id | string | Store organization hashkey |
dimension_value | string | The dimension value (department code, cashier code, terminal code, or hour) |
metric_value | number | Aggregated metric value for the store × dimension combination over the date range |
Errors
See /reference/errors.
Get Store Summary
Return the per-store rollup for a single store on a given business day.
GET /v1/hq/stores/{storeOrgId}Authentication: OAuth Token (service_account or user) Permission: rorcex:reports.view
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
storeOrgId | string | Yes | Store organization hashkey matching org_[A-Za-z0-9]{11} |
Request Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
date | string | No | Business day to query, Y-m-d format. Defaults to today. |
Response
json
{
"business_day": {
"store_org_id": "org_00000k1L2m3N4o5",
"business_day_date": "2026-05-05",
"status": "A",
"date_time_from": "2026-06-07 22:15:55",
"date_time_to": null,
"closed_at": null,
"finalized_at": null,
"beginning_balance": "0.00",
"total_sales_amount": null,
"total_reported": "8420.50",
"total_verified": "0.00",
"total_over_short": "0.00",
"total_loan_count": 3,
"total_loan_value": "1693.66",
"total_pickup_count": 0,
"total_pickup_value": "0.00",
"total_paid_in_count": 0,
"total_paid_in_value": "0.00",
"total_paid_out_count": 0,
"total_paid_out_value": "0.00",
"archived": 0,
"source": "backoffice",
"last_snapshot_at": "2026-06-09 01:05:38",
"reconciled_at": null
},
"departments": [
{
"store_org_id": "org_00000k1L2m3N4o5",
"business_day_date": "2026-05-05",
"dept_code": "001",
"sales_count": 312,
"sales_amount": "4210.50",
"refund_count": 2,
"refund_amount": "-6.00",
"net_sales_amount": "4204.50",
"source": "backoffice"
}
],
"cashiers": [
{
"store_org_id": "org_00000k1L2m3N4o5",
"business_day_date": "2026-05-05",
"cashier_code": "777",
"transaction_count": 95,
"sales_amount": "2100.00",
"item_count": 480,
"void_count": 1,
"void_amount": "-3.00",
"refund_count": 0,
"refund_amount": "0.00",
"source": "backoffice"
}
],
"terminals": [
{
"store_org_id": "org_00000k1L2m3N4o5",
"business_day_date": "2026-05-05",
"terminal_code": "01",
"transaction_count": 220,
"sales_amount": "5100.00",
"item_count": 1080,
"source": "backoffice"
}
],
"hourly": [
{
"store_org_id": "org_00000k1L2m3N4o5",
"business_day_date": "2026-05-05",
"hour": 9,
"transaction_count": 38,
"sales_amount": "1369.94",
"item_count": 320,
"average_transaction_value": "36.0511",
"source": "backoffice"
}
]
}Status: 200 OK
The response is a single object with the day's business_day summary plus four rollup arrays — departments, cashiers, terminals, hourly — all in snake_case (RORCex's own aggregate tables, not raw lane rows). Decimal money fields are serialized as strings (e.g. "4210.50"). Each rollup row also carries last_snapshot_at, reconciled_at, created_at, and updated_at metadata (omitted above for brevity). When no data exists for the requested date, business_day is null and the rollup arrays are empty; the response is still 200 OK.
Errors
See /reference/errors. The store-not-found envelope (store_not_found) is returned if the store has no active RORCex install or falls outside the caller's scope.
Get Store Timeseries
Return day-by-day metric data for a single store and dimension over a date range.
GET /v1/hq/stores/{storeOrgId}/timeseriesAuthentication: OAuth Token (service_account or user) Permission: rorcex:reports.view
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
storeOrgId | string | Yes | Store organization hashkey matching org_[A-Za-z0-9]{11} |
Request Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
dimension | string | Yes | One of: department, cashier, terminal, hourly |
from | string | Yes | Start of date range, Y-m-d |
to | string | Yes | End of date range, Y-m-d. Maximum span: 90 days. |
Response
json
{
"rows": [
{
"date": "2026-06-01",
"...": "per-dimension daily sales-summary fields"
}
]
}Status: 200 OK
Response Fields
| Field | Type | Description |
|---|---|---|
rows | array | One row per day in the range that has data, for the chosen dimension. |
date | string | Business day date (Y-m-d), added by RORCex to each row. |
Each row is a daily sales-summary line for the requested dimension, sourced from the CommerceStream materialization, with the date field added. The exact per-row metric field set is materialization-dependent and was not captured on the lane used to validate these shapes.
Errors
See /reference/errors. 422 is returned if from/to exceed the 90-day span limit or are missing.
Get Store Drift
Return data-quality drift events detected for a single store over a date range.
GET /v1/hq/stores/{storeOrgId}/driftAuthentication: OAuth Token (service_account or user) Permission: rorcex:reports.view
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
storeOrgId | string | Yes | Store organization hashkey matching org_[A-Za-z0-9]{11} |
Request Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
from | string | Yes | Start of date range, Y-m-d |
to | string | Yes | End of date range, Y-m-d |
Response
json
{
"rows": []
}Status: 200 OK
Response Fields
| Field | Type | Description |
|---|---|---|
rows | array | One entry per detected drift event for the store over the date range. |
Drift detection is populated by the RORC two-way interface (RTI) reconciliation pipeline. On lanes where RTI drift detection is not yet active the array is empty — this is the current state on validated installs. When populated, each row is a data-quality drift record keyed by store_org_id and business_day_date with detection metadata.
Errors
See /reference/errors. 422 is returned if from or to are missing or invalid.