Product analytics API
Your products' installs report device metrics every 30 minutes through the official SDKs; you read them back as counts of installs. Reports never affect license checks, and the SDKs never wait for them.
POST /api/v2/analytics/report
What the SDKs send. You only need this if you write your own client.
POST /api/v2/analytics/report
Authorization: Bearer slk_... # licensed installs: the API key you validate with
Content-Type: application/json
{
"schema": 1,
"licenseKey": "K7QX-M2PD-9HWT-R4CN", "fingerprint": "machine-a",
"sdk": { "name": "java", "version": "1.4.0" },
"metrics": {
"productVersion": "2.3.1", "os": "Linux", "osVersion": "5.15.0", "arch": "aarch64", "cores": 4, "locale": "en_US",
"runtime": "java", "runtimeVersion": "21.0.4", "platform": "paper", "platformVersion": "1.21.1"
}
}A free (unlicensed) product sends no Authorization header, its public product analytics id (on the product's Analytics tab) and a random installId it creates once and keeps:
{ "productAnalyticsId": "pa_7Hk2mQ9xZr4LbN8vT1wYcD", "installId": "0b8e5c9a-3f1d-4e7a-9c55-2d8f1e6a7b40", "metrics": { "os": "Linux" } }Send raw values: SunLicense groups them (5.15.0-1051-oracle → Linux 5.15, 1.8.0_392 → java 8, amd64 → x86_64). Every metric is optional. Reports are at most 16 KB; strings longer than 64 characters are cut.
| Answer | When | What the client does |
|---|---|---|
204 | Accepted | Reports again in 30 minutes |
400 invalid_report | Not a report (wrong types, no identity) | Reports again in 30 minutes |
401 | Unknown API key | Same |
403 analytics_disabled | You switched analytics off for the product | Waits Retry-After (a day) |
404 unknown_license / unknown_product | No such license key in your organization / product analytics id | Waits Retry-After (30 minutes for a key, 6 hours for an id) |
413 report_too_large | Over 16 KB | Reports again in 30 minutes |
429 rate_limited | More than one report per install per 5 minutes, or too many from one address | Waits Retry-After |
503 busy | We're catching up | Waits Retry-After |
Each install's first report after it starts comes after a random 1 to 30 minutes, then every 30 minutes. End users switch reporting off with the product's analytics: false setting or SUNLICENSE_ANALYTICS=off.
Reading analytics
With a dashboard session or an access token with analytics.read. Ranges are UTC days; asking for more history than your plan keeps returns what there is, with "clipped": true.
| Route | Returns |
|---|---|
GET /api/v1/analytics/overview | Active installs (reported in the last hour) per product, and your plan's analytics limits |
GET /api/v1/analytics/products/{id}/summary | Active, licensed and unlicensed installs; installs today and in 30 days; first and last report |
GET /api/v1/analytics/products/{id}/series?metric=os&days=30 | Installs per day (or granularity=hour, up to 7 days) for the top values (top, default 6) and other |
GET /api/v1/analytics/products/{id}/breakdown?metric=os | Installs per value in the last full hour, or per day on average with days=N; parent=Linux with metric=osVersion drills down |
GET /api/v1/analytics/catalog | The metrics: installs, licensed, productVersion, os, osVersion, arch, cores, locale, runtime, runtimeVersion, platform, platformVersion, country, sdk |
GET /api/v1/analytics/licenses/{id}/installs | A license's installs with their device details (needs licenses.read) |
GET /api/v1/analytics/customers/{id}/installs | The same for all of a customer's licenses |
GET /api/v1/portal/licenses/{id}/installs | The customer portal's version, with a portal session: the signed-in customer's own license only, device fields and a shortened fingerprint |
GET /api/v1/analytics/products/{id}/settings | enabled and the product analytics id (PATCH with {"enabled": false}, POST …/rotate-id with products.write) |
GET /api/v1/analytics/usage | Reports this month, installs tracked in 30 days and your plan's installs limit |
// GET /api/v1/analytics/products/{id}/breakdown?metric=os&days=7
{ "metric": "os", "mode": "average", "totalInstalls": 1200, "clipped": false,
"values": [ { "value": "Linux", "installs": 812, "share": 0.677, "total": 812 } ], "otherInstalls": 0 }Plans: Free keeps 30 days of history and tracks 1,000 installs, Lite 90 days and 10,000 installs, Standard a year and unlimited installs. Past the installs limit, new installs aren't counted; nothing stops working. See Plans.
