Docs

Analytics and reconciliation

App-scoped reporting over the traffic your app originated: payment volume trends, refund analysis, subscription metrics, renewal diagnosis, and app-fee 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 your app-fee payouts 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 app-fee distributions

GET

money.atmosphere.app.auditFeeDistributions

Row-level, cursor-paged audit of your app-fee payouts: what each cycle earned, when it transferred, 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 receives the fee 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.
Analytics and reconciliation - Atmosphere Money Docs