Docs

Analytics and reconciliation

App-scoped reporting over the traffic your app originated: payment volume trends, refund analysis, subscription metrics, renewal diagnosis, and revenue-share payout auditing.

Closed beta@atmosphere-money/app-nodeSDK beta: 0.0.0-beta.3ATM API beta: 2026-0672 lexicons

Compatible with the closed-beta ATM app APIs and versioned ATM event headers. Check atm-api-version on every webhook or XRPC receiver event.

What apps can measure

ATM exposes read-only reporting queries scoped to the traffic your app originated. Every call is authenticated with app service-auth, numbers are always per currency (never summed across currencies), and the reads are free core rails — reporting never becomes pay-to-play.

getPaymentVolumeTrendsBucketed payment counts, success counts, and gross settled volume.
getRefundAnalysisRefunds grouped by reason code and status, with settled gross for rate math.
getSubscriptionMetricsActive count, interval-normalized MRR, and windowed new/canceled counts.
diagnoseSubscriptionFailureCoarse failure reason and ATM-authored guidance for one failed renewal.
auditFeeDistributionsRow-level audit of ATM's revenue-share payouts to your app for reconciliation.

Refund analysis

GET

money.atmosphere.analytics.getRefundAnalysis

Refunds on your originated payments grouped by reason code and status. The summary carries settled gross per currency so you can compute a refund rate without summing across currencies.

Method
GET
Auth
App service-auth
Retry behavior
Read-only; cache briefly. Params: environment, windowDays, currency.
Idempotency
Read-only.
Common errors
AppNotRegistered, plus standard service-auth errors.
request example
/xrpc/money.atmosphere.analytics.getRefundAnalysis?windowDays=30
response example
{
  "byReason": [
    {
      "reasonCode": "requested-by-customer",
      "status": "succeeded",
      "currency": "usd",
      "count": 3,
      "amount": 5400
    }
  ],
  "summary": [
    { "currency": "usd", "refundCount": 3, "refundedAmount": 5400, "settledCount": 40, "settledGrossAmount": 96800 }
  ],
  "window": { "windowDays": 30, "from": "2026-06-01T00:00:00.000Z", "to": "2026-07-01T00:00:00.000Z" }
}

Subscription metrics

GET

money.atmosphere.analytics.getSubscriptionMetrics

Per-currency subscription health for subscriptions your app originated: active count, interval-normalized MRR snapshot, and new/canceled counts inside the window.

Method
GET
Auth
App service-auth
Retry behavior
Read-only; cache briefly. MRR is a current snapshot; newCount and canceledCount are windowed by createdAt/canceledAt.
Idempotency
Read-only.
Common errors
AppNotRegistered, plus standard service-auth errors.
request example
/xrpc/money.atmosphere.analytics.getSubscriptionMetrics?windowDays=30
response example
{
  "byCurrency": [
    {
      "currency": "usd",
      "activeCount": 64,
      "mrr": 38000,
      "newCount": 9,
      "canceledCount": 2
    }
  ],
  "window": { "windowDays": 30, "from": "2026-06-01T00:00:00.000Z", "to": "2026-07-01T00:00:00.000Z" },
  "notes": []
}

Diagnose a failed renewal

GET

money.atmosphere.payment.diagnoseSubscriptionFailure

Why did this renewal fail? Returns a coarse reason plus ATM-authored recommended actions — your app owns the customer communication.

Method
GET
Auth
App service-auth
Retry behavior
Read-only. Only the originating app can diagnose a subscription; anything else reads as NotFound (no existence oracle).
Idempotency
Read-only.
Common errors
NotFound, plus standard service-auth errors. Reasons: payer-declined, payment-method-expired, authentication-required, processor-unavailable, recipient-account-held, recipient-kyc-pending, unknown.
request example
/xrpc/money.atmosphere.payment.diagnoseSubscriptionFailure?subscriptionId=sub_123
response example
{
  "reason": "payment-method-expired",
  "recipientHold": false,
  "retryEligible": true,
  "recommendedActions": [
    "Ask the supporter to update their card, then let the scheduled retry run."
  ],
  "detail": "The saved card expired before this renewal attempt.",
  "failedAt": "2026-06-28T09:12:00.000Z"
}

Audit revenue-share distributions

GET

money.atmosphere.app.auditFeeDistributions

Row-level, cursor-paged audit of your app revenue-share payouts: what each cycle earned, when ATM paid it, and any holds, reversals, or clawbacks — enough to reconcile ATM against your own books.

Method
GET
Auth
App service-auth
Retry behavior
Read-only. Returns only rows your app both originated and is owed a revenue share for; carries no buyer PII, payer fields, or connected-account ids.
Idempotency
Read-only; keyset cursor pagination.
Common errors
AppNotRegistered, plus standard service-auth errors. Statuses: queued, scheduled, transferred, held, reversed, failed.
request example
/xrpc/money.atmosphere.app.auditFeeDistributions?environment=live&status=transferred
response example
{
  "distributions": [
    {
      "id": "dist_9f2",
      "paymentId": "pay_a41",
      "chargeId": "in_1TkY...",
      "role": "app",
      "amount": 120,
      "currency": "usd",
      "status": "transferred",
      "processorTransferId": "tr_1TkZ...",
      "period": "2026-06",
      "createdAt": "2026-06-27T18:04:11.000Z"
    }
  ],
  "cursor": "b3BhcXVl"
}

Boundaries

  • All reporting is scoped to traffic your app originated — you never see a creator’s other apps or ATM-wide numbers.
  • Numbers are per currency. Do not sum cents across currencies.
  • Reporting reads are operational views. The ATM ledger and your webhook stream remain the settlement truth.
  • Analytics carries no buyer PII: no emails, names, notes, or payment-method details.