Building Integrations


This guide explains how to connect any billing system to GrowPanel. Whether you have a custom-built billing platform, use a service we don't natively support, or want to build a public integration, this guide covers everything you need to know.


How GrowPanel calculates metrics

Before building an integration, it helps to understand how GrowPanel turns raw billing data into subscription metrics.

The data model

GrowPanel works with three core data types:

Data typePurpose
CustomersWho is paying you
PlansWhat they're paying for (pricing, billing interval)
InvoicesRecords of what they actually paid

From these three inputs, GrowPanel calculates all subscription metrics: MRR, ARR, churn, expansion, contraction, reactivation, cohort retention, and more.

How invoices become MRR

The key insight is that invoices drive everything. GrowPanel doesn't track "subscriptions" as a separate concept—it reconstructs subscription state from invoice history.

When you send an invoice, GrowPanel:

  1. Looks up the customer and plan
  2. Determines the billing interval (monthly, annual, etc.)
  3. Normalizes the amount to monthly (annual invoices ÷ 12)
  4. Compares to the customer's previous MRR
  5. Classifies the change as new, expansion, contraction, or reactivation

Example: A customer paying $1,200/year for an annual plan contributes $100/month MRR.

MRR movements

GrowPanel automatically detects these movement types:

MovementWhat triggers it
NewFirst invoice for a customer (or first after being churned)
ExpansionInvoice with higher MRR than previous period
ContractionInvoice with lower MRR than previous period
ChurnNo invoice in the expected billing period, or cancellation invoice
ReactivationInvoice for a customer who previously churned

You don't need to tell GrowPanel which movement type applies—it figures this out from the invoice sequence.


What you need to send

To build an integration, you need to push three things to GrowPanel:

1. Customers

Basic information about who is paying you.

{
"id": "cust_123",
"name": "Acme Inc",
"email": "[email protected]",
"country": "US",
"created": "2024-01-15T00:00:00Z"
}

Required fields:

  • id - Your unique identifier for this customer
  • name - Customer or company name

Optional but recommended:

  • email - For customer lookup
  • country - For geographic segmentation
  • created - When they became a customer
  • metadata - Custom fields for segmentation (industry, size, etc.)

2. Plans

Your pricing structure.

{
"id": "plan_pro_monthly",
"name": "Pro Monthly",
"interval": "month",
"interval_count": 1,
"currency": "USD"
}

Required fields:

  • id - Your unique identifier for this plan
  • name - Display name
  • interval - Billing period: day, week, month, year
  • interval_count - Number of intervals (1 for monthly, 12 for annual)
  • currency - Three-letter currency code

Why interval matters: GrowPanel uses the interval to normalize revenue to monthly. A $1,200 annual plan becomes $100 MRR.

3. Invoices

The actual payment records that drive all metrics.

{
"id": "inv_456",
"customer_id": "cust_123",
"plan_id": "plan_pro_monthly",
"type": "subscription",
"invoice_date": "2024-02-01T00:00:00Z",
"amount": 9900,
"currency": "USD",
"period_start": "2024-02-01T00:00:00Z",
"period_end": "2024-03-01T00:00:00Z"
}

Required fields:

  • id - Your unique identifier for this invoice
  • customer_id - Must match an existing customer
  • type - One of: subscription, one-time, refund, cancellation
  • invoice_date - When the invoice was created
  • amount - Amount in cents (9900 = $99.00)
  • currency - Three-letter currency code

Required for subscription invoices:

  • plan_id - Must match an existing plan

Recommended:

  • period_start and period_end - The billing period this invoice covers
  • subscription_id - Groups invoices into a subscription

Invoice types explained

The type field tells GrowPanel how to process the invoice:

subscription

Regular recurring invoices. These create MRR.

{
"type": "subscription",
"amount": 9900,
"plan_id": "plan_pro"
}

one-time

Setup fees, consulting, or other non-recurring charges. These don't affect MRR.

{
"type": "one-time",
"amount": 50000
}

refund

Partial or full refunds. Reduces MRR proportionally.

{
"type": "refund",
"amount": -4950
}

cancellation

Marks the end of a subscription. Use amount 0 to signal churn without a refund.

{
"type": "cancellation",
"amount": 0,
"customer_id": "cust_123"
}

Common scenarios

New customer signs up

  1. Create the customer
  2. Create the plan (if not already exists)
  3. Create a subscription invoice
# 1. Create customer
curl -X POST https://api.growpanel.io/v1/data-sources/{id}/customers \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{"id": "cust_new", "name": "New Customer", "email": "[email protected]"}'

# 2. Create invoice
curl -X POST https://api.growpanel.io/v1/data-sources/{id}/invoices \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"id": "inv_001",
"customer_id": "cust_new",
"plan_id": "plan_pro",
"type": "subscription",
"invoice_date": "2024-02-01T00:00:00Z",
"amount": 9900,
"currency": "USD"
}'

Result: GrowPanel records this as New MRR of $99.

Customer upgrades

Send a new subscription invoice with the higher amount.

{
"id": "inv_002",
"customer_id": "cust_123",
"plan_id": "plan_enterprise",
"type": "subscription",
"amount": 29900,
"invoice_date": "2024-03-01T00:00:00Z"
}

Result: GrowPanel compares to the previous invoice ($99) and records Expansion MRR of $200.

Customer downgrades

Send a new subscription invoice with the lower amount.

{
"id": "inv_003",
"customer_id": "cust_123",
"plan_id": "plan_basic",
"type": "subscription",
"amount": 4900,
"invoice_date": "2024-04-01T00:00:00Z"
}

Result: GrowPanel records Contraction MRR of $250.

Customer cancels

Send a cancellation invoice with amount 0.

{
"id": "inv_004",
"customer_id": "cust_123",
"type": "cancellation",
"amount": 0,
"invoice_date": "2024-05-01T00:00:00Z"
}

Result: GrowPanel records Churned MRR equal to their last invoice amount.

Customer reactivates

After a customer has churned, send a new subscription invoice.

{
"id": "inv_005",
"customer_id": "cust_123",
"plan_id": "plan_pro",
"type": "subscription",
"amount": 9900,
"invoice_date": "2024-08-01T00:00:00Z"
}

Result: GrowPanel recognizes this customer previously churned and records Reactivation MRR of $99.


Historical data import

For accurate reporting, import your full invoice history—not just current subscriptions.

Why history matters

GrowPanel calculates:

  • Cohort retention - Needs to know when customers started
  • Churn trends - Needs to see when customers left
  • Growth decomposition - Needs the full sequence of changes

Without historical data, you'll only see current state, not trends.

Import order

  1. Customers first - Invoices reference customers
  2. Plans second - Invoices reference plans
  3. Invoices last - In chronological order

Batch imports

For large datasets, use batch requests:

{
"invoices": [
{"id": "inv_001", "customer_id": "cust_1", "amount": 9900, "...": "..."},
{"id": "inv_002", "customer_id": "cust_2", "amount": 4900, "...": "..."},
{"id": "inv_003", "customer_id": "cust_1", "amount": 9900, "...": "..."}
]
}

Real-time sync

After the initial import, keep GrowPanel updated as events happen:

Event in your systemAction in GrowPanel
New subscriptionPOST customer + invoice
RenewalPOST invoice
Upgrade/downgradePOST invoice with new amount
CancellationPOST cancellation invoice
RefundPOST refund invoice

Webhook-driven sync

If your billing system supports webhooks, trigger API calls on:

  • invoice.paid → POST invoice
  • subscription.created → POST customer (if new) + invoice
  • subscription.updated → POST invoice with new amount
  • subscription.cancelled → POST cancellation invoice
  • charge.refunded → POST refund invoice

Best practices

Use stable IDs

Your id fields should be:

  • Unique - No duplicates within a type
  • Stable - Same customer always has the same ID
  • Immutable - Don't change IDs over time

GrowPanel uses IDs for deduplication. If you send the same invoice ID twice, it updates rather than duplicates.

Include all invoices

Send every paid invoice, including:

  • Historical invoices (for accurate cohort analysis)
  • Prorated invoices (GrowPanel handles proration)
  • Zero-amount invoices (for trials converting to paid)

Use cents for amounts

All amounts should be in the smallest currency unit:

  • $99.00 → 9900
  • €49.50 → 4950
  • ¥1000 → 1000

Include period dates

period_start and period_end help GrowPanel:

  • Handle partial-month invoices correctly
  • Align billing cycles across customers
  • Calculate accurate daily MRR

API reference

For complete endpoint documentation:


Need help?

Building an integration and have questions?

  • Email: [email protected]
  • Include: Your use case, billing platform, and any specific questions

We're happy to help you connect your billing system to GrowPanel.