Webhooks


The webhook integration sends a JSON payload to any HTTPS URL whenever an MRR movement occurs. Use webhooks to build custom integrations, connect to automation tools, or feed data into internal systems.


Connecting a webhook

  1. Go to Settings > Integrations
  2. Find the Webhooks card and click Enable
  3. Enter your webhook endpoint URL (must use HTTPS)
  4. Optionally click Test to send a test payload and verify your endpoint responds
  5. Click Enable to save

The card shows "Webhook enabled" with your URL displayed.


Testing your webhook

Before saving, you can send a test payload to verify your endpoint is working:

  1. Enter the URL in the configuration modal
  2. Click the Test button
  3. GrowPanel sends a test payload with sample data to your URL
  4. If the endpoint returns HTTP 2xx, the test passes
  5. If it fails, the error message tells you what went wrong (timeout, non-2xx status, etc.)

The test payload looks like a real notification but uses dummy data (cus_test_123, Pro Plan, etc.) so you can identify it.


Configuring notifications

After enabling, click the Settings button on the Webhooks card to configure filtering:

  • Threshold - Minimum MRR change to trigger a notification (e.g., "Over $100")
  • Event types - Which movement types to send (new, expansion, contraction, churn, reactivation, scheduled cancellation, failed payment)

By default, all event types are enabled with no minimum threshold, so every MRR movement is sent.

See Integrations overview for details on threshold and event type settings.


Payload format

GrowPanel sends a POST request with Content-Type: application/json. The payload includes the customer and all movements in a single request.

MRR movement payload

{
"event": "mrr_movement",
"account_id": "acc_abc123",
"customer": {
"id": "cus_456",
"name": "Acme Corp",
"email": "[email protected]",
"status": "active"
},
"movements": [
{
"type": "new",
"mrr_change": 4900,
"currency": "usd",
"date": "2025-03-15",
"plan_name": "Pro Plan",
"subscription_id": "sub_789",
"description": "subscribed to Pro Plan",
"is_future": false
}
]
}

Scheduled cancellation payload

{
"event": "scheduled_cancellation",
"account_id": "acc_abc123",
"customer": {
"id": "cus_456",
"name": "Acme Corp",
"email": "[email protected]",
"status": "active"
},
"movements": [
{
"type": "churn",
"mrr_change": -4900,
"currency": "usd",
"date": "2025-04-15",
"plan_name": "Pro Plan",
"subscription_id": "sub_789",
"description": "scheduled cancellation of Pro Plan",
"is_future": true
}
]
}

Failed payment payload

Sent when a customer's payment fails for the first time after previously successful payments:

{
"event": "failed_payment",
"timestamp": "2025-03-15T14:30:00Z",
"customer": {
"id": "cus_456",
"name": "Acme Corp",
"email": "[email protected]",
"status": "past_due",
"current_mrr": 4900,
"currency": "usd"
},
"payment": {
"invoice_id": "inv_789",
"amount": 4900,
"currency": "usd",
"failure_reason": "card_declined",
"attempt_count": 1,
"date": "2025-03-15"
}
}

This event only triggers on the first failed payment after successful payments, not on every retry or for customers who never paid successfully.

Field reference

FieldTypeDescription
eventstring"mrr_movement", "scheduled_cancellation", or "failed_payment"
account_idstringYour GrowPanel account ID
customer.idstringThe customer's external ID from your billing source
customer.namestringCustomer name
customer.emailstringCustomer email
customer.statusstringCurrent status: active, trialing, past_due, canceled
movements[].typestringnew, expansion, contraction, churn, or reactivation
movements[].mrr_changeintegerMRR change in cents (positive for growth, negative for churn)
movements[].currencystringThree-letter currency code (lowercase)
movements[].datestringDate of the movement
movements[].plan_namestringName of the plan involved
movements[].subscription_idstringSubscription ID from the billing source
movements[].descriptionstringHuman-readable description of the change
movements[].is_futurebooleantrue for scheduled future movements
payment.invoice_idstringInvoice ID from billing source (failed_payment only)
payment.amountintegerPayment amount in cents (failed_payment only)
payment.currencystringThree-letter currency code (failed_payment only)
payment.failure_reasonstringWhy the payment failed (failed_payment only)
payment.attempt_countintegerNumber of payment attempts (failed_payment only)
payment.datestringDate of the failed payment (failed_payment only)

Multiple movements

A single webhook call may contain multiple movements if they occurred together (e.g., a customer switching plans generates both a contraction on the old plan and an expansion on the new plan).


Requirements for your endpoint

Your webhook endpoint must:

  • Accept POST requests
  • Use HTTPS (HTTP is not supported)
  • Return a 2xx status code within 5 seconds
  • Accept Content-Type: application/json

GrowPanel does not retry failed deliveries. If your endpoint is down or returns an error, that notification is lost. For reliable delivery, consider using a webhook relay service that queues and retries.


Changing the URL

Click Configure on the Webhooks card to update the endpoint URL. You can also test the new URL before saving.


Disabling

Click Disable on the Webhooks card. This removes the webhook URL and notification settings. No further payloads will be sent.


Use cases

Use caseHow
Custom Slack botPoint the webhook at your own Slack bot that formats messages your way
CRM updatesUpdate deal stages or customer records when MRR changes
Internal dashboardFeed real-time MRR data into your own analytics system
Zapier / Make / n8nUse webhook triggers to connect to thousands of apps
AlertingRoute to PagerDuty or Opsgenie for high-value churn alerts
Dunning workflowsTrigger automated payment recovery when a payment fails