Using the Sales API
Purpose of this guide
This guide covers how to retrieve sales for an entire business account, a specific store, or a specific POS terminal using ReceiptRoller's Sales API. It is the entry point for building a "sales dashboard" from a mobile app or server integration.
Prerequisites
- You have obtained an access token via the OAuth 2.0 authorization code flow
- Your app's scopes include
sales.read - You have already obtained the business account and store IDs (Listing business accounts, stores, and POS terminals)
- Base URL:
https://receiptroller.io
Endpoint list
| Endpoint | Purpose | Main filters |
|---|---|---|
GET /api/v1/sales/kpis | This month's KPIs (revenue, transactions, average ticket) and month-over-month comparison | organizationId, storeId?, terminalId? |
GET /api/v1/sales/trend | Monthly trend (12 months by default, up to 60 months) | organizationId, storeId?, months, terminalId? |
GET /api/v1/sales/products | Sales by product + ABC analysis + gross margin rate | organizationId, storeId, since, until, category, search, sortBy, terminalId? |
GET /api/v1/sales/visitors | Visitor analysis (time of day, day of week, conversion, new / repeat) | organizationId, storeId, since, until, terminalId? |
GET /api/v1/sales/multi-trend | Overlay the monthly trends of multiple stores (up to 10 stores) | organizationId, storeIds (comma-separated), months |
GET /api/v1/sales/advice | AI advice (Intelligence panel cards) | organizationId, storeId?, severity?, category? |
GET /api/v1/sales/forecast | End-of-month projection | organizationId, storeId? |
GET /api/v1/sales/churn | Customer churn score (RFM-lite) | organizationId, storeId, lookbackDays |
GET /api/v1/sales/recommendations | Product recommendations for individual customers | organizationId, storeId, customerId, topN, lookbackDays |
Sales for the whole business account (KPIs)
When you want "this month's numbers" for the selected business account, call kpis without a storeId.
GET /api/v1/sales/kpis?organizationId={organizationId}
Authorization: Bearer {access_token}
Response structure
Every numeric field is returned as a common nested type called KpiValue. There is no need to recompute month-over-month or percentage change on the client side.
{
"organizationId": "0aa2...e7b1",
"currentMonth": "2026-06",
"previousMonth": "2026-05",
"totalStores": { "current": 12, "previous": 12, "changePercent": 0.0 },
"totalStaff": { "current": 87, "previous": 84, "changePercent": 3.6 },
"totalProducts": { "current": 1450, "previous": 1410, "changePercent": 2.8 },
"totalCustomers": { "current": 8920, "previous": 8650, "changePercent": 3.1 },
"totalRevenue": { "current": 3850000, "previous": 3520000, "changePercent": 9.4 },
"totalTransactions": { "current": 1240, "previous": 1180, "changePercent": 5.1 },
"averageTicket": { "current": 3104.84, "previous": 2983.05, "changePercent": 4.1 },
"avgGoogleRating": { "current": 4.3, "previous": 4.2, "changePercent": 2.4 },
"totalReservations": { "current": 210, "previous": 195, "changePercent": 7.7 }
}
Inside KpiValue
current— this month's valueprevious— last month's value (nullwhen there is no snapshot for last month)changePercent— month-over-month change rate (%).nullwhenpreviousis null or 0
About averageTicket
- The server returns
totalRevenue / totalTransactionsalready computed. There is no need to recompute it on the client - When the transaction count is 0, it returns
current: 0(it never becomes NaN) - The same
averageTicketfield is returned at the store level and the POS terminal level
Sales for a specific store
Adding storeId to the same endpoint returns KPIs for that store only. The response is in the StoreDashboardKpis shape (with store-oriented field names such as revenue, transactionCount, and averageTicket).
GET /api/v1/sales/kpis?organizationId={organizationId}&storeId={storeId}
Authorization: Bearer {access_token}
{
"storeId": "store-001",
"storeName": "渋谷本店",
"currentMonth": "2026-06",
"staffCount": { "current": 12, "previous": 11, "changePercent": 9.1 },
"revenue": { "current": 850000, "previous": 780000, "changePercent": 8.9 },
"transactionCount": { "current": 340, "previous": 310, "changePercent": 9.6 },
"averageTicket": { "current": 2500.0, "previous": 2516.13, "changePercent": -0.6 },
"reservationCount": { "current": 45, "previous": 38, "changePercent": 18.4 },
"googleRating": { "current": 4.4, "previous": 4.3, "changePercent": 2.3 },
"productCount": { "current": 320, "previous": 318, "changePercent": 0.6 },
"customerCount": { "current": 1820, "previous": 1750, "changePercent": 4.0 }
}
Time-series trend
Retrieves the monthly progression over the past N months. Use it for drawing graphs.
GET /api/v1/sales/trend?organizationId={organizationId}&storeId={storeId}&months=12
Authorization: Bearer {access_token}
Notes
monthsis at most 60. OmittingstoreIdgives the business account total- Currently monthly only. If you need a daily or weekly graph, it is planned for an upcoming release (adding
?granularity=day|monthis planned, tracked in t-e9a2f468)
Sales by product (with a date range)
Aggregates sales by product over any period, such as "the top 50 sellers last month."
GET /api/v1/sales/products
?organizationId={organizationId}
&storeId={storeId}
&since=2026-05-01
&until=2026-05-31
&sortBy=revenue
&category=ドリンク
&search=ラテ
&terminalId={terminalId} # (optional) aggregate for a specific POS terminal only
Authorization: Bearer {access_token}
Notes
since/untilare dates (start inclusive; the end runs up to 0:00 the day afteruntil)- The response includes the ABC group (A: up to 70% of cumulative sales / B: up to 90% / C: the rest), gross profit and gross margin rate, and a total gross-profit KPI
sortBy:revenue(default) /quantity/margin- Adding
terminalIdnarrows the aggregation to that one terminal (see "Filtering by POS terminal" below)
When you want to compare multiple stores
When you want to overlay multiple stores of a business account onto a single graph, use multi-trend.
GET /api/v1/sales/multi-trend
?organizationId={organizationId}
&storeIds=store-001,store-002,store-003
&months=12
Authorization: Bearer {access_token}
Up to 10 stores. Beyond 6 stores the lines become hard to read, so it is best to limit it to the stores the user selects.
Visitor analysis (day of week and time of day)
This endpoint is for understanding behavioral patterns such as "strong on weekday mornings 7-9" or "traffic rises on Saturday afternoons."
GET /api/v1/sales/visitors
?organizationId={organizationId}
&storeId={storeId}
&since=2026-05-01
&until=2026-05-31
&terminalId={terminalId} # (optional) aggregate for a specific POS terminal only
Authorization: Bearer {access_token}
The response includes the distribution by time of day, the distribution by day of week, a time-of-day × day-of-week heatmap, the conversion rate (CRM linkage rate), and the new / repeat breakdown over the past 12 months.
AI advice (Intelligence panel)
Retrieves cards such as sales anomaly detection, forecasts, and improvement suggestions.
GET /api/v1/sales/advice
?organizationId={organizationId}
&storeId={storeId}
&severity=Action
&category=Anomaly
Authorization: Bearer {access_token}
Notes
severity:Action/Warning/Opportunity/Infocategory:Trend/AverageTicket/MixShift/Anomaly/Forecast/Comparison- Cards are generated in a once-a-day batch (they are not real-time)
Filtering by POS terminal (terminalId)
Filtering at the POS terminal (terminalId) level — such as "sales for one register" or "sales for the terminal that had a specific cashier/staff" — is supported by four endpoints (kpis, trend, products, visitors).
# KPIs (this month's numbers for one terminal + MoM comparison, includes averageTicket)
GET /api/v1/sales/kpis?organizationId={orgId}&storeId={storeId}&terminalId={terminalId}
# Monthly trend (past N months for one terminal)
GET /api/v1/sales/trend?organizationId={orgId}&storeId={storeId}&terminalId={terminalId}&months=12
# Sales by product (period aggregation for one terminal)
GET /api/v1/sales/products?organizationId={orgId}&storeId={storeId}&terminalId={terminalId}&since=...&until=...
# Visitor analysis (time of day and day of week for one terminal)
GET /api/v1/sales/visitors?organizationId={orgId}&storeId={storeId}&terminalId={terminalId}&since=...&until=...
Notes
- When using
terminalId,storeIdis also required - If the
terminalIddoes not belong to the specifiedstoreId, 404 is returned (this prevents cross-store references) - You can get terminal IDs with
GET /api/v1/me/organizations/{orgId}/stores/{storeId}/pos-terminals
About terminal-level aggregation
- Because
/kpisand/trendaggregate live at terminal granularity on request, the response contains only Revenue, TransactionCount, and AverageTicket. Fields such as staff count, product count, and Google rating are not terminal-level concepts, so0is returned - Because
/productsand/visitorsare live aggregations to begin with, all fields are returned correctly at terminal granularity
A typical flow (mobile app)
- Get the business accounts with
GET /api/v1/me/organizations - Once the user picks one, get the store list with
GET /api/v1/me/organizations/{orgId}/stores - On the dashboard screen, request
GET /api/v1/sales/kpisandGET /api/v1/sales/trendin parallel - When the user switches stores, re-fetch the same endpoints with a
storeId - When a "by POS terminal" tab is opened, get the terminal list with
GET /api/v1/me/organizations/{orgId}/stores/{storeId}/pos-terminals, and re-fetch each sales endpoint with aterminalIdfor the selected terminal - When a "by product" tab is opened, call
GET /api/v1/sales/products - When an "advice" tab is opened, call
GET /api/v1/sales/advice
Permissions and tokens
- Required scope:
sales.read - Apps that support multiple business accounts should specify
?organizationId=on every call using a user-scoped access token - Apps fixed to a single business account can omit
organizationIdif they use a token bound to a business account at authorization time - Access token lifetime: 8 hours. It is set long to match a full day's work shift. The same token can be reused even when switching business accounts or stores
- Refresh token lifetime: 30 days. When it expires, obtain a new access token with
POST /api/v1/auth/refresh
Error responses
| Status | Meaning | What to do |
|---|---|---|
| 401 Unauthorized | Access token invalid / expired | Re-obtain with the refresh token |
| 403 Forbidden | Scope does not include sales.read / user is not a member of the business account | Check the app's registered scopes and the selected business account |
| 400 Bad Request | Missing required parameter (e.g. specifying storeId/terminalId on products without storeId) | Review the query parameters |
| 404 Not Found | terminalId does not belong to the specified storeId | Re-fetch the store/terminal selection UI |
Related articles
-
Using the Store Information APIA guide to the REST API for fetching and updating a store's basic information (store name, store type, contact details, and address). Lets you implement a store information editing screen from token-authenticated clients such as staff apps.
-
PosTransactionDto specification — field reference for transaction dataA complete field reference for PosTransactionDto, the canonical model for the transaction data ReceiptRoller handles. For each category — identifiers, dates, amounts, line items, payments, staff, status, and CRM linkage — it summarizes the field names, types, meanings, and how each POS vendor populates them. A reference for developers and external-system integrators. Also referenced from the Smaregi and Square mapping articles.
-
Purchase and receipt data integrationExplains the structure of the purchase and receipt data ReceiptRoller handles, how to retrieve it, related scopes, Webhooks, and common use cases.
-
Using the Business Hours APIA guide to ReceiptRoller's Business Hours API (/api/v1/stores/{storeId}/business-hours). Covers retrieving and updating per-day business hours, registering special business days (temporary closures and hour changes), configuring a store's workable hours (the upper bound for shift creation), and determining whether the store is currently open.
-
Using the Orders / OMS APIA guide to CRUD operations on the orders under a business account using ReceiptRoller's Orders / OMS API (/api/v1/orders). Covers creating, updating, transitioning status (confirm, process, cancel), and deleting orders, plus the flow for Android / iOS apps and server integrations.