Skip to main content
GET
/
apps
/
developer
/
:appId
/
analytics
App Analytics
curl --request GET \
  --url https://api.launchmystore.io/apps/developer/:appId/analytics \
  --header 'Authorization: Bearer <token>'
{
  "data.activeInstallations": 123,
  "data.totalInstalls": 123,
  "data.netNewInRange": 123,
  "data.series": [
    {}
  ],
  "data.dau": 123,
  "data.wau": 123,
  "data.mau": 123,
  "data.stickiness": 123,
  "data.totals": {
    "invocations": 123,
    "success": 123,
    "error": 123,
    "timeout": 123,
    "successRate": 123,
    "p50Ms": 123,
    "p95Ms": 123,
    "p99Ms": 123
  },
  "data.byFunction": [
    {}
  ],
  "data.totals.deliveries": 123,
  "data.totals.success": 123,
  "data.totals.failed": 123,
  "data.totals.successRate": 123,
  "data.totals.avgAttemptCount": 123,
  "data.byTopic": [
    {}
  ],
  "data.gross": 123,
  "data.commission": 123,
  "data.net": 123,
  "data.mrr": 123,
  "data.arr": 123,
  "data.churnRate": 123,
  "data.currency": "<string>"
}

Documentation Index

Fetch the complete documentation index at: https://docs.launchmystore.io/llms.txt

Use this file to discover all available pages before exploring further.

App analytics surface the operational health of a published app — distinct from the store-level analytics at /api/v1/analytics/* (which report a merchant’s sales / orders / customers, not the app developer’s own metrics). These endpoints are read by the developer dashboard in TeamInfra and are scoped to the calling developer account. They cover four areas:
  1. Installations — installs/uninstalls over time, active store count.
  2. Function executions — invocation counts, success/error/timeout rates, p50 / p95 latency, per-function breakdown.
  3. Webhook deliveries — success rate, retry rate, per-topic counts.
  4. Revenue — gross / commission / net, ARR, churn.
Auth: developer JWT (@Auth(MERCHANT) — developers and merchants share the same auth surface; ownership of the app is checked against appId).
Per-app analytics are exposed under the developer-scoped namespace /apps/developer/:appId/analytics/*. The merchant-facing /api/v1/analytics/* endpoints documented in Analytics overview report a different metric set (sales, orders, conversion) and require the read_analytics OAuth scope.

Installations overview

GET /apps/developer/:appId/analytics/installs Returns install/uninstall counts bucketed by day, plus a running total of active installations.
appId
string
required
App UUID.
range
string
One of 7d, 30d, 90d, 12m. Default 30d.
start
string
ISO date — overrides range lower bound.
end
string
ISO date — overrides range upper bound.
curl -X GET "https://api.launchmystore.io/apps/developer/<APP_ID>/analytics/installs?range=30d" \
  -H "Authorization: Bearer <DEVELOPER_JWT>"
data.activeInstallations
integer
Current count of AppInstallation rows with status: active.
data.totalInstalls
integer
All-time install count (incl. churned).
data.netNewInRange
integer
installsInRange − uninstallsInRange.
data.series
array
{
  "status": 200,
  "data": {
    "activeInstallations": 1247,
    "totalInstalls": 1612,
    "netNewInRange": 89,
    "series": [
      { "date": "2026-04-16", "installs": 12, "uninstalls": 1, "cumulative": 1158 },
      { "date": "2026-04-17", "installs": 18, "uninstalls": 3, "cumulative": 1173 }
    ]
  }
}

Active stores

GET /apps/developer/:appId/analytics/active-stores An installation is “active” if it received at least one successful function invocation or webhook delivery in the trailing 30 days. Use this to distinguish parked installs from real users.
curl -X GET "https://api.launchmystore.io/apps/developer/<APP_ID>/analytics/active-stores?range=30d" \
  -H "Authorization: Bearer <DEVELOPER_JWT>"
data.dau
integer
Distinct stores that exercised the app today.
data.wau
integer
7-day distinct stores.
data.mau
integer
30-day distinct stores.
data.stickiness
number
dau / mau ratio.

Function invocations

GET /apps/developer/:appId/analytics/functions Aggregates rows from the AppFunctionRuns table (see function runs) over the range.
range
string
default:"7d"
functionHandle
string
Filter to one function.
functionType
string
Filter to one type (e.g. discount, shipping_rate).
curl -X GET "https://api.launchmystore.io/apps/developer/<APP_ID>/analytics/functions?range=7d" \
  -H "Authorization: Bearer <DEVELOPER_JWT>"
data.totals
object
data.byFunction
array
Per-function rollup. Each entry: { functionHandle, functionType, invocations, success, error, timeout, p50Ms, p95Ms }.
data.series
array
Daily bucket: { date, invocations, success, error, timeout }.
{
  "status": 200,
  "data": {
    "totals": {
      "invocations": 18472,
      "success": 18411,
      "error": 49,
      "timeout": 12,
      "successRate": 0.9967,
      "p50Ms": 4,
      "p95Ms": 18,
      "p99Ms": 47
    },
    "byFunction": [
      { "functionHandle": "tiered-discount", "functionType": "discount",
        "invocations": 14201, "success": 14198, "error": 3, "timeout": 0,
        "p50Ms": 3, "p95Ms": 9 },
      { "functionHandle": "weight-shipping", "functionType": "shipping_rate",
        "invocations": 4271,  "success": 4213,  "error": 46, "timeout": 12,
        "p50Ms": 22, "p95Ms": 184 }
    ]
  }
}

Webhook delivery success rate

GET /apps/developer/:appId/analytics/webhooks Aggregates rows from WebhookDeliveryLogs. Webhook delivery uses 3-retry exponential backoff (1m / 5m / 15m); a delivery is failed only after the final retry returns non-2xx.
curl -X GET "https://api.launchmystore.io/apps/developer/<APP_ID>/analytics/webhooks?range=30d" \
  -H "Authorization: Bearer <DEVELOPER_JWT>"
data.totals.deliveries
integer
data.totals.success
integer
data.totals.failed
integer
data.totals.successRate
number
success / deliveries.
data.totals.avgAttemptCount
number
Average attempts before success — 1.0 means most deliveries succeed first try.
data.byTopic
array
Per-topic rollup. Each entry: { topic, deliveries, success, failed, successRate, p50LatencyMs }.
{
  "status": 200,
  "data": {
    "totals": {
      "deliveries": 8421,
      "success": 8394,
      "failed": 27,
      "successRate": 0.9968,
      "avgAttemptCount": 1.02
    },
    "byTopic": [
      { "topic": "orders/create",  "deliveries": 5210, "success": 5208, "failed": 2, "successRate": 0.9996, "p50LatencyMs": 134 },
      { "topic": "orders/updated", "deliveries": 1841, "success": 1820, "failed": 21, "successRate": 0.9886, "p50LatencyMs": 178 }
    ]
  }
}

Revenue

GET /apps/developer/:appId/analytics/revenue Pulls from AppBillingTransactions and joins with the app’s pricing configuration.
data.gross
number
Total amount charged to merchants in range, before commission.
data.commission
number
Platform fee withheld (typically 20%).
data.net
number
Developer-net revenue = gross − commission.
data.mrr
number
Monthly Recurring Revenue at end of range — sum of active subscription developerAmount.
data.arr
number
Annual Recurring Revenue = mrr × 12.
data.churnRate
number
% of MRR lost to cancellations in range, 0-1.
data.currency
string
ISO-4217 currency code.
{
  "status": 200,
  "data": {
    "gross": "1247.61",
    "commission": "249.52",
    "net": "998.09",
    "mrr": "847.13",
    "arr": "10165.56",
    "churnRate": 0.018,
    "currency": "USD"
  }
}

Error codes

CodeDescription
401Missing or invalid developer JWT.
403The calling developer does not own this app.
404App not found.
400Invalid range (not one of 7d, 30d, 90d, 12m) or malformed start / end.