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 type | Purpose |
|---|---|
| Customers | Who is paying you |
| Plans | What they're paying for (pricing, billing interval) |
| Invoices | Records 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:
- Looks up the customer and plan
- Determines the billing interval (monthly, annual, etc.)
- Normalizes the amount to monthly (annual invoices ÷ 12)
- Compares to the customer's previous MRR
- 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:
| Movement | What triggers it |
|---|---|
| New | First invoice for a customer (or first after being churned) |
| Expansion | Invoice with higher MRR than previous period |
| Contraction | Invoice with lower MRR than previous period |
| Churn | No invoice in the expected billing period, or cancellation invoice |
| Reactivation | Invoice 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 customername- Customer or company name
Optional but recommended:
email- For customer lookupcountry- For geographic segmentationcreated- When they became a customermetadata- 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 planname- Display nameinterval- Billing period:day,week,month,yearinterval_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 invoicecustomer_id- Must match an existing customertype- One of:subscription,one-time,refund,cancellationinvoice_date- When the invoice was createdamount- Amount in cents (9900 = $99.00)currency- Three-letter currency code
Required for subscription invoices:
plan_id- Must match an existing plan
Recommended:
period_startandperiod_end- The billing period this invoice coverssubscription_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
- Create the customer
- Create the plan (if not already exists)
- Create a
subscriptioninvoice
# 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
- Customers first - Invoices reference customers
- Plans second - Invoices reference plans
- 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 system | Action in GrowPanel |
|---|---|
| New subscription | POST customer + invoice |
| Renewal | POST invoice |
| Upgrade/downgrade | POST invoice with new amount |
| Cancellation | POST cancellation invoice |
| Refund | POST refund invoice |
Webhook-driven sync
If your billing system supports webhooks, trigger API calls on:
invoice.paid→ POST invoicesubscription.created→ POST customer (if new) + invoicesubscription.updated→ POST invoice with new amountsubscription.cancelled→ POST cancellation invoicecharge.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:
- Import Data API - Push customers, plans, and invoices
- Customers endpoint - CRUD operations for customers
- Plans endpoint - CRUD operations for plans
- Invoices endpoint - CRUD operations for invoices
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.