Skip to content

Revenue from Stripe

Nordva Launch can read your own Stripe account and report the numbers a small product needs: MRR, who started paying, who cancelled, and what was collected. The same connection lets Contacts show who became a customer and Attribution show which signup sources produce customers.

Launch only reads. It never creates, changes or refunds anything in your Stripe account, and it never sees card data.

In Stripe, go to Developers → API keys → Create restricted key.

Stripe first asks how you will use the key. Choose the option for providing the key to another website, and enter:

FieldValue
NameNordva Launch
URLhttps://launch.nordva.dev

Then set these five resources to Read and leave everything else at None. Do not pick Write anywhere:

ResourceWhy
CustomersEmail, name, and your user id from metadata
SubscriptionsStatus, amount, plan
InvoicesPaid invoices, for revenue
ProductsPlan names
EventsThe change feed Launch uses to stay up to date

The key starts with rk_live_. A key starting with rk_test_ connects a test-mode account, which is a good way to try this first.

Open Revenue in the dashboard and paste the key. Launch checks each of the five permissions before saving and, if one is missing, shows Stripe’s own message naming it.

Connecting is only possible in the dashboard, behind your login. There is no API-key endpoint and no MCP tool for it, so a payment-account credential never travels through an API key or an AI conversation.

The first import starts immediately and runs in the background. After that, each connection syncs about once an hour.

If your Stripe customers carry your application’s user id in metadata (for example metadata.user_id), enter that key name when connecting. Feedback and notifications you send with the same user_id then appear on the right person in Contacts.

All amounts are in the smallest currency unit (cents), reported per currency, and never converted or added together.

Terminal window
curl "https://api.nordva.dev/v1/revenue/summary?period_days=30" \
-H "Authorization: Bearer nv_live_YOUR_SECRET_KEY"
{
"data": {
"period_days": 30,
"by_currency": [{
"currency": "usd",
"mrr_minor": 38000,
"active_subscriptions": 21,
"trialing_subscriptions": 2,
"paying_customers": 20,
"new_subscriptions": 4,
"new_mrr_minor": 7300,
"churned_subscriptions": 1,
"churned_mrr_minor": 1500,
"net_mrr_change_minor": 5800,
"revenue_minor": 41200,
"payments": 23
}],
"sync": { "status": "active", "last_synced_at": "2026-09-17T14:02:11.000Z", "livemode": true }
}
}
EndpointWhat it returns
GET /v1/integrations/stripeConnection status, last sync, synced counts, last error
GET /v1/revenue/summary?period_days=The summary above
GET /v1/revenue/series?range=30d|90d|12m|allCollected revenue per day (up to 90 days), ISO week (up to a year) or month, with empty buckets filled with zero
GET /v1/revenue/events?type=payment|cancellation&limit=Recent payments and cancellations with customer email and plan. For a cancellation, amount_minor is the monthly amount that stopped

History reaches 90 days on Indie and 24 months on Builder. A longer range is shortened and the response says so with clamped_to_plan: true.

MRR is an operational number, not an accounting one:

  • Yearly plans are divided by twelve, weekly plans multiplied by 52 ÷ 12, and quantities are included.
  • A coupon counts when it is forever, or repeating and still running. A once coupon does not change the run rate.
  • Metered and tiered prices have no fixed amount and count as zero. A subscription with paused collection counts as zero.
  • active and past_due subscriptions count. Trialing subscriptions are reported separately.
  • Revenue is paid invoices. Refunds are not subtracted.

Every response includes sync:

statusMeaning
backfillingThe first import is still running. Numbers are incomplete.
activeUp to date as of last_synced_at.
revokedStripe no longer accepts the key (deleted or rolled). Numbers are as of the last sync. Disconnect and connect a new key. Launch emails the account owner when this happens.
errorThe key lost a read permission. last_error on the status endpoint names it.

Disconnect in the dashboard deletes the stored key and every synced customer, subscription and invoice. Nothing changes in Stripe. Deleting the project does the same.

Ask your assistant things like “what’s my MRR and did it grow this month?” or “who cancelled this week?”. It uses get_revenue_summary, get_revenue_series, list_recent_payments and get_stripe_connection_status. The assistant cannot connect Stripe and will never ask you for a key.

CodeMeaning
STRIPE_NOT_CONNECTEDNo Stripe account is connected to this project.
STRIPE_KEY_NOT_RESTRICTEDThe pasted key is not an rk_ key. If it was a secret key, roll it.
STRIPE_KEY_INVALIDStripe did not recognise the key.
STRIPE_KEY_MISSING_PERMISSIONOne of the five read permissions is missing. The message names it.
STRIPE_ALREADY_CONNECTEDDisconnect the current key first.
STRIPE_CONNECTION_LIMIT_REACHEDIndie includes one connection per account. Builder includes one per project.