Linkit

Analytics

Dashboard plus Sensy and consumption forecasts — not the reports envelope

Analytics

GET /api/v1/analytics/dashboard is mounted (ReportPorts::analytics_repository). It is not a /reports/* body.

Requires tenant read × Analytics. A merchant who can read /reports/sales (report) can still get 403 The authorized record is not allowed to perform this action. here. That is RBAC, not a 501. Live Ocima owner JWT, 2026-09-10: reports 200, dashboard 403.

Window is ?range=, not ?days=. Closed set: 7/7d, 30/30d (and empty), 90/90d, 180/180d, 1y/365/365d. Anything else — including ?range=8 — is 30. No error.


Dashboard

GET /api/v1/analytics/dashboard?range=7d&section=summary&section=trends
{
  "organization_id": "0rmzqwt5hhaf07r",
  "range_days": 7,
  "fetched_at": "2026-09-10T14:34:07Z",
  "data": {}
}

errors is omitted when empty. A failed section is a string in errors.<name> and is absent from data.

Nine sections, Go order: summary, trends, apps, alerts, activity, sensy, consumption, products, posts.

?section=Behaviour
omittedall nine
unknown namesdropped silently
selection empty after drops (?section=nonsense)all nine, not an empty dashboard
selected but empty resultkey omitted (omitempty) — not "trends":[]
summary with zerosemitted (struct, not a slice)

summary all-zeros is a measured zero. A missing trends key is either no rows or a section you did not ask for.


Sensy and consumption

EndpointGrant
GET /api/v1/analytics/sensyread × Analytics
GET /api/v1/analytics/consumptionsame
GET /api/v1/analytics/sensy/exportexport × Analytics
GET /api/v1/analytics/sensy/templateread × Analytics — CSV header sku_id,product_name_en,sale_date,qty,unit_price,current_qty,reorder_threshold,buffer
POST /api/v1/analytics/sensy/uploadimport × Analytics

?horizon= default 14, max 90. Non-positive / unparseable → 14. Same ?range= set as the dashboard.