Enforce spend thresholds
To reduce fraud in Product-Led Growth (PLG) workflows, Metronome supports spend threshold billing. This feature allows you to cap the amount a customer can spend before being charged, thereby limiting your exposure to uncollected revenue.
After applying a spend threshold to a contract, watch for webhook notifications to be alerted when payments succeed or fail.
Spend threshold billing is currently in beta. It’s available for production use, but you may encounter product limitations. Breaking changes may occur.
Create a contract with spend thresholds
When you create a contract in Metronome, you can optionally configure a spend_threshold_configuration
. This config dictates:
- The
threshold_amount
for the customer’s contract: how much they can spend before a payment attempt is triggered - The
payment_gate_config
:- Configure whether to payment gate the release of the commit and what gateway to use. Select
EXTERNAL
if you are using a gateway Metronome does not currently support. - If using Stripe, configure
PAYMENT_TYPE
to dictate whether payment is sent as an invoice through Stripe Billing or directly as a paymentIntent to Stripe's payment gateway. - If using Stripe, select your existing tax provider.
- Configure whether to payment gate the release of the commit and what gateway to use. Select
- What
product_id
should be used to represent the commit: theproduct_id
dictates what the customer sees on their incremental invoice
If using Stripe as your payment gateway, ensure there is a valid Stripe billing configuration set on the contract. Additionally, set spend_threshold_configuration.is_enabled
to true
if you want Metronome to immediately evaluate the contract after its creation.
Create contracts with spend threshold in the Metronome app or using the Metronome API.
{
"customer_id": "8cecbf69-960f-4f66-9575-edebb7d95e88",
"rate_card_id": "a7bc3775-b651-46b6-b7e4-d225a7e55c4c",
"starting_at": "2025-04-01T00:00:00.000Z",
"billing_provider_configuration": {
"billing_provider_configuration_id": "211ef270-098f-422c-9ca8-7999bb9156cb"
},
...
"spend_threshold_configuration": {
"commit": {
"product_id": "d6be3bf4-1669-40c9-a8b1-388bb167ab16",
"name": "black_mesa_commit",
"description": "hello_its_me_im_in_california_dreaming"
},
"is_enabled": true,
"payment_gate_config": {
"payment_gate_type": "NONE"
},
"threshold_amount": 200
}
}
Update a contract’s spend threshold
You can update or add a spend_threshold_configuration
at any point by editing the user's contract. Add spend threshold limits to existing, non-limited contracts or change existing limits on a contract (for example, after some period of successful payments).
Note that these changes take effect immediately.
Edit contracts in the Metronome app or with the Metronome API. This API call adds a spend threshold to a contract:
{
"customer_id": "52f5a554-b887-4899-b919-4eb7789c6bf3",
"contract_id": "8a5529d3-f353-4231-bedf-7e83f5e9331d",
"add_spend_threshold_configuration": {
"commit": {
"product_id": "d6be3bf4-1669-40c9-a8b1-388bb167ab16",
"name": "threshold_charge",
"description": "one time for the one time"
},
"is_enabled": true,
"payment_gate_config": {
"payment_gate_type": "STRIPE",
"stripe_config": {
"payment_type": "INVOICE"
}
},
"threshold_amount": 100
}
}
This API call updates an existing spend threshold:
{
"customer_id": "8cecbf69-960f-4f66-9575-edebb7d95e88",
"contract_id": "6058587f-763c-400f-a822-3edb3eb2b86b",
"update_spend_threshold_configuration": {
"is_enabled": true,
"threshold_amount": 100,
"payment_gate_config": {
"payment_gate_type": "STRIPE",
"stripe_config": {
"payment_type": "INVOICE"
}
}
}
}
Spend threshold billing lifecycle
To best utilize spend threshold billing, consider its lifecycle: the actions Metronome takes and what actions you may need to take.
1. Charge for spend threshold amount (Metronome)
Once configured, Metronome evaluates the total spend of usage invoices on the contract to determine when the threshold_amount
has been reached. If the payment_gate_config
is set to Stripe, Metronome attempts to charge the customer the threshold_amount
.
If payment is successful, Metronome creates a commit for the same amount, which the outstanding balance draws down from. If a customer still exceeds their threshold, Metronome continues to charge the customer their threshold_amount
until their balance is brought below this amount.
2. Manage notifications (you)
Metronome fires three types of webhook notifications for spend threshold billing:
payment_gate.threshold_reached
when the customer hits their threshold.payment_gate.payment_status
after payment has been attempted. The status of that payment,paid
orfailed
, is denoted in thepayment_status
field.payment_gate.payment_pending_action_required
if intervention is required to process payment.
Your webhook endpoint must be configured to handle these notifications accordingly.
3. Handle failed payments (you)
When a payment fails, you receive a payment_gate.payment_status
notification, with a value of failed
. Additionally, the contract's spend_threshold_configuration.is_enabled
field is set to false
. You should expect to see a voided invoice in Metronome and Stripe for this transaction. See example webhook below:
{
"id": "417fcaa4-f3cf-434e-ab20-f70204cfd5ef",
"properties": {
"workflow_type": "spend",
"customer_id": "d290dec8-4ebb-4e73-89ef-45ed3443ca67",
"contract_id": "80b07d70-c84e-4ff0-b42c-875defff0931",
"invoice_id": "dd864572-9787-573f-9c74-e5159b4ea97c",
"error_message": "three_d_secure_redirect",
"billing_provider": {
"type": "stripe",
"stripe": {
"payment_intent_id": "pi_3ROpJCIkTQSg6Mm31fNUnPKx",
"error": {
"type": "card_error",
"code": "expired_card",
"decline_code": "expired_card",
"message": "Your card has expired."
},
},
},
},
"type": "payment_gate.payment_status"
}
At this point, you should follow up with your customer either directly or by creating an automated workflow triggered by this webhook notification.
Once you are ready to reattempt payment, set the contract's spend_threshold_configuration.is_enabled
field to true
. This forces the contract to evaluate against the threshold_amount
, resulting in a new payment attempt.
Metronome does not automatically retry failed payments (as any automatic retries would likely fail, too).
Manually create payment-gated commits
Spend threshold billing supports the addition of payment-gated commits on contracts: Metronome must successfully charge the customer before the commit resource is created in Metronome. When you attempt to add a payment-gated commit to a contract:
- Metronome immediately triggers a payment attempt based on the invoice amount.
- If the payment succeeds, Metronome grants the release of the commit.
- If the payment fails, Metronome voids the resource and sends a webhook notification.
Create a contract with a payment-gated commit
If the customer does not exist or does not have a previous contract, you can create a contract with a payment-gated commit. When creating a commit, the fields are the exact same as the existing commit flow, except you need to complete the payment_gate_config
. Set the type to STRIPE
and make sure you add a valid Stripe billing configuration to the contract.
This API call creates a contract with a payment-gated commit:
{
"customer_id": "8cecbf69-960f-4f66-9575-edebb7d95e88",
"rate_card_id": "a7bc3775-b651-46b6-b7e4-d225a7e55c4c",
"starting_at": "2025-04-01T00:00:00.000Z",
"billing_provider_configuration": {
"billing_provider_configuration_id": "211ef270-098f-422c-9ca8-7999bb9156cb"
},
...
"commits": [
{
"product_id": "d6be3bf4-1669-40c9-a8b1-388bb167ab16",
"type": "prepaid",
"invoice_schedule": {
"schedule_items": [
{
"timestamp": "2025-04-01T00:00:00.000Z",
"amount": 2000
}
]
},
"access_schedule": {
"schedule_items": [
{
"amount": 2000,
"starting_at": "2025-04-01T00:00:00.000Z",
"ending_before": "2026-04-01T00:00:00.000Z"
}
]
},
"payment_gate_config": {
"payment_gate_type": "STRIPE",
"tax_type": "STRIPE"
},
"priority": 100
}
]
}
When creating a commit, you need to specify the timestamp of the associated invoice in Metronome. Use the invoice_schedule.schedule_items.timestamp
to do so. This does not impact when the charge is processed in Stripe (which is immediate), but rather sets the issued_at
date in Metronome.
Add a payment-gated commit to an existing contract
You can add a payment-gated commit at any point by editing the user's contract. Ensure the contract has a valid billing configuration set up before creating the commit.
This is how we recommend clients handle manual recharging workflows for their customers where customers directly purchase credits in your platform.
This API call adds a payment-gated commit to an existing contract:
{
"customer_id": "8cecbf69-960f-4f66-9575-edebb7d95e88",
"contract_id": "d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc",
"add_commits": [
{
"product_id": "d6be3bf4-1669-40c9-a8b1-388bb167ab16",
"type": "prepaid",
"invoice_schedule": {
"schedule_items": [
{
"timestamp": "2025-04-01T00:00:00.000Z",
"amount": 2000
}
]
},
"access_schedule": {
"schedule_items": [
{
"amount": 2000,
"starting_at": "2025-04-01T00:00:00.000Z",
"ending_before": "2026-04-01T00:00:00.000Z"
}
]
},
"payment_gate_config": {
"payment_gate_type": "STRIPE",
"tax_type": "STRIPE"
},
"priority": 100
}
]
}
Manage Notifications
Two types of webhook notifications are emitted when creating a payment-gated commit:
payment_gate.payment_status
after payment has been attempted. The status of that payment,paid
orfailed
, is denoted in thepayment_status
field.payment_gate.payment_pending_action_required
if intervention is required to process payment.
Handle failed payments
If payment fails, the associated invoice in Metronome and Stripe is voided and no commit is created. To retry the payment, send a new API request with the relevant commit information.
Metronome does not automatically retry failed payments (as any automatic retries would likely fail, too).
Using external payment gate
If using the EXTERNAL
option for payment_gate_type
, you are responsible for facilitating payment and letting Metronome know the response. Follow this workflow:
- Set the spend threshold config with
payment_gate_type
set toEXTERNAL
- Listen for
payment_gate.external_initiate
that indicates Metronome is ready to recieve the outcome of the payment - Save the
workflow_id
- you will need this to release the commit - Charge the customer in your payment gateway of choice
- Call commits/threshold-billing/release to either release the commit on successful payment, or cancel the commit in case of failure.