Custom API
Overview
GrowPanel's Custom API integration allows you to connect any billing system or data source using our REST API. This is ideal for businesses with custom-built billing systems, proprietary platforms, or unique data requirements that aren't covered by our native integrations.
The Custom API integration supports two modes:
- Push mode: Your system sends data to GrowPanel's REST API endpoints
- Pull mode: GrowPanel fetches data from your API endpoint on demand
This guide covers:
- How to create a Custom API data source
- How to push data to GrowPanel (Push mode)
- How to configure GrowPanel to pull from your API (Pull mode)
- Data formats and endpoints
- Best practices and troubleshooting
Creating a Custom API data source
Step 1: Add a new data source
- In GrowPanel, navigate to Settings → Data sources.
- Click Add data source and select Custom API.
- Enter a name for the data source (e.g., "Custom Billing System").
Step 2: Configure the data source
Depending on your needs, configure one or both modes:
For Push mode:
- No additional configuration needed. Your API key will be used to authenticate requests.
For Pull mode:
- Enter your API endpoint URL where GrowPanel should fetch data.
- Optionally configure authentication headers if your endpoint requires them.
- Select the data types to fetch (customers, plans, invoices).
Step 3: Save and get credentials
- Click Save to create the data source.
- Note the Data Source ID - you'll need this when pushing data.
- Go to Account → API Keys to get or create an API key for authentication.
Push mode: Sending data to GrowPanel
In Push mode, your system sends data to GrowPanel's REST API. This is useful when you want real-time updates as events happen in your billing system.
Authentication
All API requests must include your API key in the header:
Authorization: Bearer YOUR_API_KEY
Endpoints
Push data to these endpoints under https://api.growpanel.io/v1/:
| Endpoint | Method | Description |
|---|---|---|
/data-sources/{id}/customers | POST | Create or update customers |
/data-sources/{id}/plans | POST | Create or update plans |
/data-sources/{id}/invoices | POST | Create or update invoices |
Replace {id} with your Data Source ID.
Customer object
{
"id": "cust_123",
"name": "Acme Inc",
"email": "[email protected]",
"created": "2024-01-15T00:00:00Z",
"country": "US",
"trial_started": "2024-01-10T00:00:00Z",
"metadata": {
"industry": "Technology",
"company_size": "50-100"
}
}| Field | Type | Required | Description |
|---|---|---|---|
| id | string | Yes | Unique customer identifier |
| name | string | Yes | Customer name or company name |
| string | No | Customer email address | |
| created | datetime | No | When the customer was created (ISO 8601) |
| country | string | No | Two-letter country code |
| trial_started | datetime | No | When the trial started (ISO 8601) |
| metadata | object | No | Custom key-value pairs for filtering |
Plan object
{
"id": "plan_pro_monthly",
"name": "Pro Monthly",
"interval": "month",
"interval_count": 1,
"currency": "USD",
"plan_group": "Pro"
}| Field | Type | Required | Description |
|---|---|---|---|
| id | string | Yes | Unique plan identifier |
| name | string | Yes | Display name of the plan |
| interval | string | Yes | Billing interval: day, week, month, year |
| interval_count | integer | Yes | Number of intervals per billing cycle |
| currency | string | Yes | Three-letter currency code |
| plan_group | string | No | Group name for organizing plans |
Invoice object
{
"id": "inv_456",
"customer_id": "cust_123",
"type": "subscription",
"invoice_date": "2024-02-01T00:00:00Z",
"amount": 9900,
"currency": "USD",
"plan_id": "plan_pro_monthly",
"subscription_id": "sub_789",
"period_start": "2024-02-01T00:00:00Z",
"period_end": "2024-03-01T00:00:00Z",
"proration": false,
"quantity": 1,
"discount": 0
}| Field | Type | Required | Description |
|---|---|---|---|
| id | string | Yes | Unique invoice identifier |
| customer_id | string | Yes | Must match an existing customer ID |
| type | string | Yes | One of: subscription, one-time, refund, cancellation |
| invoice_date | datetime | Yes | When the invoice was created (ISO 8601) |
| amount | integer | Yes | Amount in cents (e.g., 9900 for $99.00) |
| currency | string | Yes | Three-letter currency code |
| plan_id | string | Conditional | Required for subscription invoices |
| subscription_id | string | No | Groups invoices into a subscription |
| period_start | datetime | No | Subscription period start |
| period_end | datetime | No | Subscription period end |
| proration | boolean | No | Whether this is a prorated invoice |
| quantity | integer | No | Number of units/seats |
| discount | integer | No | Discount amount in cents |
Batch requests
You can send multiple objects in a single request:
{
"customers": [
{ "id": "cust_1", "name": "Customer One", "email": "[email protected]" },
{ "id": "cust_2", "name": "Customer Two", "email": "[email protected]" }
]
}Example: Push a new subscription
Here's a complete example of pushing data for a new customer subscription:
# 1. Create the customer
curl -X POST https://api.growpanel.io/v1/data-sources/ds_abc123/customers \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"id": "cust_123",
"name": "Acme Inc",
"email": "[email protected]",
"country": "US"
}'
# 2. Create the plan (if not already created)
curl -X POST https://api.growpanel.io/v1/data-sources/ds_abc123/plans \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"id": "plan_pro",
"name": "Pro Plan",
"interval": "month",
"interval_count": 1,
"currency": "USD"
}'
# 3. Create the invoice
curl -X POST https://api.growpanel.io/v1/data-sources/ds_abc123/invoices \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"id": "inv_001",
"customer_id": "cust_123",
"type": "subscription",
"invoice_date": "2024-02-01T00:00:00Z",
"amount": 9900,
"currency": "USD",
"plan_id": "plan_pro",
"subscription_id": "sub_001",
"period_start": "2024-02-01T00:00:00Z",
"period_end": "2024-03-01T00:00:00Z"
}'Pull mode: GrowPanel fetches from your API
In Pull mode, GrowPanel fetches data from an endpoint you provide. This is useful when you have an existing API that exposes your billing data and you want to trigger syncs on demand.
Configuring your endpoint
When creating the Custom API data source, enter your API endpoint URL. GrowPanel will make GET requests to:
{your-endpoint}/customers{your-endpoint}/plans{your-endpoint}/invoices
Your endpoint should return JSON arrays in the same format as the Push mode objects described above.
Authentication for your endpoint
If your endpoint requires authentication, configure it in the data source settings:
- API Key header: Add a custom header with your API key
- Bearer token: Use standard Bearer token authentication
- Basic auth: Provide username and password
Expected response format
Your endpoints should return JSON arrays:
{
"data": [
{ "id": "cust_1", "name": "Customer One", "email": "[email protected]" },
{ "id": "cust_2", "name": "Customer Two", "email": "[email protected]" }
],
"has_more": false
}For large datasets, GrowPanel supports pagination. Include has_more: true and GrowPanel will make subsequent requests with ?page=2, ?page=3, etc.
Triggering a sync
To fetch data from your endpoint:
- Go to Settings → Data sources.
- Find your Custom API data source.
- Click Sync now.
GrowPanel will fetch from your endpoints and update the data. You can monitor progress on the data source detail page.
How GrowPanel processes your data
After receiving data (via Push or Pull), GrowPanel:
- Validates the data - Checks required fields and relationships
- Creates or updates records - Uses your IDs for deduplication
- Calculates MRR movements - Processes invoices to determine new, expansion, contraction, churn, and reactivation events
- Updates metrics - Refreshes dashboards and reports
MRR is calculated from invoice data:
- Subscription invoices create recurring revenue based on the plan interval
- Refund invoices reduce MRR
- Cancellation invoices (with amount 0) mark the end of a subscription
Invoice types explained
| Type | Description | Effect on MRR |
|---|---|---|
| subscription | Regular recurring invoice | Adds MRR based on plan interval |
| one-time | One-time charge (setup fee, etc.) | No MRR impact |
| refund | Partial or full refund | Reduces MRR |
| cancellation | Marks subscription end | Churns remaining MRR |
Modeling MRR movements
To model different MRR movement types:
New subscription:
{
"type": "subscription",
"customer_id": "new_customer",
"amount": 9900
}Upgrade (expansion):
{
"type": "subscription",
"customer_id": "existing_customer",
"amount": 19900,
"plan_id": "higher_plan"
}Downgrade (contraction):
{
"type": "subscription",
"customer_id": "existing_customer",
"amount": 4900,
"plan_id": "lower_plan"
}Cancellation (churn):
{
"type": "cancellation",
"customer_id": "churning_customer",
"amount": 0
}Best practices
Data consistency
- Use stable IDs - Your customer, plan, and invoice IDs should be stable and unique
- Send data in order - Create customers and plans before referencing them in invoices
- Include all historical data - For accurate reporting, include all past invoices, not just current subscriptions
Real-time updates
- Push on events - Send data to GrowPanel when events happen (new subscription, upgrade, cancellation)
- Use webhooks - If your billing system supports webhooks, use them to trigger pushes to GrowPanel
- Batch for efficiency - Send multiple objects in one request when possible
Data quality
- Validate before sending - Check required fields before making API calls
- Use correct amounts - Always use cents (integer), not dollars (decimal)
- Use ISO 8601 dates - Format all dates as
YYYY-MM-DDTHH:MM:SSZ
Troubleshooting
| Problem | Possible cause | Solution |
|---|---|---|
| 401 Unauthorized | Invalid or missing API key | Check your API key in Account → API Keys |
| 400 Bad Request | Invalid data format | Check the error response for field-specific errors |
| Invoice not affecting MRR | Missing plan_id or wrong type | Ensure subscription invoices have a valid plan_id |
| Customer not found | Invoice references unknown customer | Push customer data before invoice data |
| Duplicate data | Same ID pushed multiple times | This is fine - GrowPanel updates existing records |
| Pull mode not fetching | Endpoint URL incorrect or not accessible | Verify URL is reachable and returns expected format |
| MRR calculations seem wrong | Missing period dates or incorrect amounts | Include period_start and period_end; use cents |
API reference
For complete API documentation, including error codes, rate limits, and all available endpoints, see the REST API reference.
Summary
The Custom API integration gives you complete flexibility to connect any billing system to GrowPanel. Use Push mode to send real-time updates as events happen, or Pull mode to sync on demand from your existing API. GrowPanel processes your raw billing data into MRR movements, giving you the same powerful analytics available with native integrations.
If you need help implementing the Custom API integration, contact our support team or refer to the REST API documentation.