Private preview
Post-fund your integration with Dynamic Reserves Private preview
Learn how to use dynamic reserves to post-fund card spend.
Dynamic reserves enable platforms to adjust their own credit limits in real-time to manage cash between Stripe and the funds available for authorisation. This feature allows you to:
- Control capital usage and minimise funding costs
- Control limits that determine authorisation availability
- Use Stripe to manage unexpected volatility
Private preview
To get access to the Dynamic Reserves APIs, include Stripe-Version: <your stripe version>;issuing_credit_beta=v2; in all API requests.
Your connected accounts can accrue a negative Issuing balance on card spend and ‘ ‘post-fund’ ’ Stripe later. You can fund your Issuing balance after card the network captures authorisations (typically 1 day after the authorisation is created) instead of pre-funding your Issuing balance before any card spend occurs. Each day, Stripe notifies you of how much you owe, and you can send a same-day wire to fund Stripe before the deadline. You must fund Stripe by the deadline (typically 20:00 UTC) to avoid late fees and additional penalties.
Connect
If you’re post-funding a Connect platform, your connected account behaviour is the same as described in:
- Set up connected accounts
- Manage credit terms
- Manage account obligations
The relationship between your platform and your connected accounts doesn’t change. The primary difference is that instead of the need to pre-fund the aggregate spend of your connected accounts, you can post-fund spend.
Before you begin
- Establish a reserve , accessed only in the event of operational failure.
- Send wires from your bank.
Card programme configuration
Stripe configures a CreditPolicy for your platform or direct card programme, which contains information about your payment obligations and terms. Your card programme CreditPolicy differs from the CreditPolicy that you set on your connected accounts. Stripe sets and controls your card programme CreditPolicy, which defines the following fields:
- current _ exposure _ limit _ amount : The maximum aggregate amount that can be spent across all of your connected accounts (or account, in the case of a Direct user). We calculate the current _ exposure _ limit _ amount based on the combination of funded _ reserve _ amount and reserve _ multiplier values using the following equation: current_exposure_limit_amount = MIN [(funded_reserve_amount * reserve_multiplier), maximum_exposure_limit]
- reserve _ multiplier _ decimal : The amount that the funded _ reserve _ amount is multiplied by to determine the current _ exposure _ limit _ amount . The reserve _ multiplier _ decimal is determined at the start of the post-funding programme.
- max _ exposure _ limit _ amount : The maximum aggregate amount that can be spent across all of your connected accounts (or account, in the case of a Direct user). Your maximum exposure limit is equal to a fixed value, set by Stripe, and your funded _ reserve _ amount .
- funded _ reserve _ amount : Corresponds to the total reserves you have posted with Stripe.
- exposure _ limit _ currency : The three-letter currency code for the current _ exposure _ limit _ amount and max _ exposure _ limit _ amount .
Stripe charges a fee if you spend above your funded_reserve, exceed your current_exposure_limit, or are late in paying a funding_obligation. Although Stripe permits you to spend above your current_exposure_limit up to your max_exposure_limit, this is emergency capital rather than funding that you use.
For example, if your funded_reserve_amount is 1,000 USD, your reserve_multiplier_decimal is 2.0x, your current_exposure_limit_amount is 2,000 USD, and your max_exposure_limit_amount is 3,000 USD:
- Stripe charges you a “credit usage” fee for spend between 1,000 USD and 2,000 USD.
- Stripe charges a higher “emergency capital” fee for spend between 2,000 USD and 3,000 USD.
- Stripe declines transactions above 3,000 USD.
To retrieve the details of your card programme CreditPolicy, call the GET CreditPolicy API endpoint:
Command Line
See the following example response:
{
"livemode": true,
"current_exposure_limit_amount": 11359999920 ,
"reserve_multiplier_decimal": "2.4",
"max_exposure_limit_amount": 13133333300,
"funded_reserve_amount": 4733333300,
// other fields
}
Stripe applies any changes it makes to the CreditPolicy after T+2 business days at 20:00 UTC. The credit_policy.upcoming_attributes.effective_at attribute represents this timestamp.
Command Line
See the following example response:
{
"livemode": true,
"upcoming_attributes": {
"current_exposure_limit_amount": 11359999920,
"reserve_multiplier_decimal": "2.4",
"max_exposure_limit_amount": 13233333300,
"funded_reserve_amount": 4733333300,
"effective_at": 1729195200 // 2024-10-17 20:00:00 +0000 UTC
}
}
Only the fixed portion of the max_exposure_limit_amount is subject to a T+2 business day delay. The max_exposure_limit_amount isn’t a Stripe-initiated change and updates dynamically based on your funded reserve.
For example, if you request Stripe to increase the fixed portion of your max_exposure_limit_amount by 1,000 USD, this change takes effect after T+2 business days. However, if you increase your funded_reserve by 1,000 USD, your max_exposure_limit_amount changes dynamically in real-time.
Card programme obligation
While your CreditPolicy defines the overall parameters of your postfunding programme, your FundingObligation represents your current obligation to Stripe for card spend across all of your connected accounts, or your account if you’re a Direct user.
Every morning, Stripe sends an issuing_funding_obligation.updated webhook event containing the FundingObligation that you owe Stripe. For any given FundingObligation, the amount_outstanding value represents the amount you owe that day.
{
"id": "icfo_123",
"amount_total": 95000000, // minor units
"amount_outstanding": 95000000, // minor units
"amount_paid": 0,
"currency": "usd",
"status": "unpaid",
"due_at": "timestamp_on_t1",
"paid_at": "nil",
"owed_to": "stripe",
"finalized_at": "timestamp_on_t2",
"grace_period_ends_at": "timestamp_on_t3",
…,
}
Late payments
Each FundingObligation contains a due_at field that indicates when the FundingObligation is due.
{
"id": "icfo_123",
"amount_total": 95000000, // minor units
"amount_outstanding": 95000000, // minor units
"amount_paid": 0,
"currency": "usd",
"status": "unpaid",
"due_at": "timestamp_on_t1",
"paid_at": "nil",
"owed_to": "stripe",
"finalized_at": "timestamp_on_t2",
"grace_period_ends_at": "timestamp_on_t3",
…,
}
If you fail to pay your FundingObligation when it’s due, the following occurs:
- Stripe withdraws from your reserve to cover the past-due amount.
- If you have a sufficient balance in your reserve, you receive a FundingObligation. updated webhook showing the Funding Obligation’s status changed to paid . If you have an insufficient reserve balance to fully cover the FundingObligation , you receive a FundingObligation. updated webhook showing the Funding Obligation’s status changed to past _ due and a grace _ period _ ends _ at timestamp of 20:00 UTC on the next business day.
- When a reserve pull occurs, the credit _ policy. current _ exposure _ limit _ amount and credit _ policy. max _ exposure _ limit _ amount reflect the updated exposure limit based on the new issuing credit reserve balance. You receive a webhook notifying you of the new exposure limits (current and max).
- You also receive an email notifying you of the reserve pull and past _ due FundingObligation .
- If your FundingObligation becomes past due, Stripe charges a late payment fee as stated in your contract with Stripe.
- It’s your responsibility to make sure your current _ exposure _ limit is larger than your negative Issuing balance. Be prepared to initiate a reserve top-up if necessary after a withdrawal initiated by Stripe. Failure to do so results in authorisation declines if your spend exceeds your max _ exposure _ limit .
Multiple late payments over time can lead to additional penalties on your platform, such as a decrease in your card programme exposure limit. You must remediate an unpaid FundingObligation within one additional business day, or Stripe might begin declining transactions.
Identify how much you owe Stripe
Stripe generates a FundingObligation for your card programme every day, including weekends and holidays. To keep your account current and avoid late fees and penalties, calculate your total amount owed each day based on the amount_outstanding value for all unpaid and past_due FundingObligations using a formula:
total_amount_outstanding = sum(unpaid FundingObligations) 1 + sum(past_due FundingObligations) 2 |
|---|
1 sum(unpaid FundingObligations) is the total of all FundingObligations with status=unpaid.
2 sum(past_due FundingObligations) is the total of all FundingObligations with status=past_due.
Manage funding obligations and due dates
When Stripe generates a FundingObligation on a weekday, it’s due that same day. If Stripe generates a FundingObligation on a weekend or public holiday, it’s due on the next business day. For a typical weekend, this means you’ll have three FundingObligations due on Monday. Make sure that you accurately aggregate your total amount owed to Stripe to make timely payments.
Fund Stripe to meet obligations
To fund Stripe daily based on the due_at timestamp for the total amount you owe, use any of the following methods:
- Same-day wires : Initiate a same-day wire from your bank to your Stripe Issuing balance to pay off a FundingObligation . Use the FundingInstructions API to retrieve the account and routing number for your Issuing balance, and use that as the destination for the wire.
- Balance transfers : In the US, you can move money instantly from your Stripe payments balance to your Issuing balance and use it to pay off your FundingObligation through the Stripe Dashboard or the API (contact Stripe to gain access to the API).
- Existing pre-funded Issuing balance : In the US, Stripe applies any pre-funded or over-funded amounts from the previous day to your next FundingObligation . In the related setting, prefunding your Issuing balance isn’t allowed for charge card users; instead, any positive Issuing balance is transferred to your Issuing Reserve.
After Stripe receives the full amount owed on the FundingObligation, we update its status and amounts, and trigger an issuing_funding_obligation.updated webhook event.
{
"id": "icfo_123",
"amount_total": 95000000, // minor units
"amount_outstanding": 0,
"amount_paid": 95000000, // minor units
"currency": "usd",
"status": "paid",
"due_at": "timestamp_on_t1",
"paid_at": "timestamp_of_payment",
"owed_to": "stripe",
"grace_period_ends_at": "timestamp_on_t2"
…,
}
If you pay only a portion of the total amount due, Stripe updates the amounts but keeps the status as unpaid. The issuing_funding_obligation.updated webhook event reflects this information.
{
"id": "icfo_123",
"amount_total": 95000000, // minor units
"amount_outstanding": 3000000, // minor units
"amount_paid": 92000000, // minor units
"currency": "usd",
"status": "unpaid",
"due_at": "timestamp_on_t1",
"paid_at": "timestamp_of_payment",
"owed_to": "stripe",
"grace_period_ends_at": "timestamp_on_t2"
…,
}
If the balance remains unpaid past the due_at deadline, the status changes to past_due, which triggers another issuing_funding_obligation.updated webhook event and initiates a reserve withdrawal.
Get transactions for a funding obligation
Retrieve the list of transactions that contribute to a FundingObligation by including one of the following parameters in the List all transactions API request:
- funding_obligation_for_account for Direct users.
- funding_obligation_for_platform for Platform users.
To retrieve transactions for direct charges:
Command Line
Select a language
cURL
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
See the following example response:
Query funding obligations for connected accounts
Connect platforms must include the Stripe-Account header with a connected account ID. Use funding_obligation_for_platform to query by the platform’s FundingObligation, or use funding_obligation_for_account if you know a connected account’s FundingObligation.
Command Line
Select a language
cURL
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
See the following example response:
Manage your reserve
You must post a reserve (referred to as “Collateral” in your programme agreement) with Stripe to use capital-efficient post-funded card spend. Stripe holds the reserve in an account that it owns and controls as security against funds owed, drawing from it to pay off any late or unpaid FundingObligations. Stripe also uses the reserve amount as the basis for current_exposure_limit and max_exposure_limit calculations. You can dynamically adjust your reserve balance by adding more funds when you expect higher spend, such as before a long weekend, and reducing your reserve when your projected spend is lower.
You might incur a late fee if your funding obligation becomes past_due and your reserve isn’t sufficient to cover the amount. Additionally, a pattern of past_due funding obligations can result in Stripe reducing your platform’s reserve_multiplier_decimal or the fixed portion of your max_exposure_limit_amount. To avoid this, fund your Stripe Issuing balance through wires or balance transfers before the due_at timestamp on the FundingObligation for your credit integration.
Identify your reserve components
You can identify the reserve_multiplier_decimal, max_exposure_limit_amount, funded_reserve_amount, and current_exposure_limit_amount in your CreditPolicy. Use these factors, along with your expected future spend, to determine the appropriate funded_reserve_amount.
Command Line
See the following example response:
{
"current_exposure_limit_amount": 11359999920 ,
"reserve_multiplier_decimal": "2.4",
"max_exposure_limit_amount": 13133333300,
"funded_reserve_amount": 4733333300,
// other fields
}
Add funds to your reserve balance
Stripe supports pushing funds into the reserve balance. You might do this to increase your current_exposure_limit_amount ahead of increased spend or after Stripe withdraws from your reserve to pay a past_due FundingObligation. You can find the account details for your reserve in the FundingInstruction, which contains bank account and routing information for you to originate a funds transfer.
Caution
This is a different set of instructions from those Stripe uses to fund your Issuing balance. The destination_balance for your reserve funding instructions are set as issuing_credit_reserved.
Command Line
cURL
See the following example response:
{
"id": "fi_XYZ",
"object": "funding_instruction",
"livemode": "true",
"currency": "usd",
"bank_transfer": {
"type": "us_bank_account",
"country": "US",
"financial_addresses": [{
"supported_networks": ["ach", "domestic_wire_us"],
"type": "aba",
"aba": {
"account_number": "546475644",
"bank_name": "Wells Fargo",
"routing_number": "123456"
}
}]
},
"destination_balance": "issuing_credit_reserved",
"funding_type": "bank_transfer"
}
Funds transferred through a wire or ACH credit to the bank account retrieved from the FundingInstructions are deposited into your reserve balance. When the funds arrive in your account, Stripe sends a topup.succeeded webhook notification along with an issuing_credit_policy.updated webhook event that represents your updated exposure limit and funded reserve amount. Stripe doesn’t add additional delays to the wire, and generally follows standard wire timelines.
{
"id": "tu_XYZ",
"object": "topup",
"amount": 9000,
"balance_transaction": "txn_123",
"destination_balance": "issuing_credit_reserved",
"created": 123456789,
...
}
Check your reserve balance
You can use the Balance API to check your reserve balance at any time:
Command Line
Select a language
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
See the following example response:
{
"object": "balance",
"available": [ ... ],
"connect_reserved": [ ... ],
"issuing": { ... },
"issuing_credit_reserved": [
{
"amount": 9000,
"currency": "usd"
}
],
"livemode": true,
"pending": [ ... ]
}
Manage past due funding obligations
If you have a FundingObligation that’s past_due, Stripe first withdraws from your reserve to pay off the FundingObligation. Stripe uses the issuing_funding_obligation.updated webhook to notify you, and updates the FundingObligation object to show the amount paid off by your reserve. If your reserve can’t fully cover the amount_outstanding on the FundingObligation, the FundingObligation remains past_due. See Past Due Funding Obligations for more details and implications.
The following shows a FundingObligation that’s fully paid by the reserve:
{
"id": "icfo_123",
"amount_total": 95000000, // minor units
"amount_outstanding": 0,
"amount_paid": 95000000, // minor units
"amount_paid_from_reserve": 95000000, // minor units
"currency": "usd",
"status": "paid",
"due_at": "timestamp_on_t1",
"paid_at": "timestamp_of_payment_with_reserve",
"owed_to": "stripe",
"grace_period_ends_at": "timestamp_on_t2"
…,
}
Stripe provides a BalanceTransfer object and associated BalanceTransactions to represent the automated transfer of funds from your reserve balance to your Issuing balance.
Command Line
cURL
See the following example response:
{
"id": "btr_1MinsBCq7itcH1tbDkk4sY8w",
"object": "balance_transfer",
"amount": 10000,
"currency": "usd",
"destination_balance": {
"issuing": {
"balance_transaction": "txn_123_inbound"
},
"type": "issuing"
},
...
"source_balance": {
"issuing_credit_reserved": {
"balance_transaction": "txn_123_outbound"
},
"type": "issuing_credit_reserved"
}
}
Command Line
Select a language
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
See the following example response:
[
{
"id": "txn_123_outbound",
"object": "balance_transaction",
"amount": 100,
"currency": "usd",
...
"type": "balance_transfer_outbound",
"balance_type": "issuing_credit_reserved",
"reporting_category": "issuing_credit_reserved_funds"
},
{
"id": "txn_123_inbound",
"object": "balance_transaction",
"amount": 100,
"currency": "usd",
...
"type": "balance_transfer_inbound",
"balance_type": "issuing",
"reporting_category": "issuing_credit_reserved_funds"
}
]
Pay out funds from your reserve balance
Stripe supports paying out funds from your reserve balance. You might do this to lower your current_exposure_limit_amount ahead of decreased spend to be more capital efficient. You can use the v1/payout endpoint with source_type set to issuing_credit_reserved.
Caution
This is a different set of instructions from those Stripe uses to fund your Issuing balance. The destination_balance for your reserve funding instructions are set as issuing_credit_reserved.
Command Line
After you create a payout, Stripe immediately sends a webhook indicating that the issuing credit reserve balance reflects the payout created.
Retrieve the updated balance:
Command Line
See the following example response:
{
// other fields,
"issuing_credit_reserved": [
{
"amount": 1233333300,
"currency": "usd"
}
],
}
The credit policy object reflects the latest exposure limit, and you receive an issuing_credit_policy.updated webhook informing you of the new exposure limits.
Retrieve the updated credit policy:
Command Line
See the following example response:
{
"object": "issuing.credit_policy",
"current_exposure_limit_amount": 11359999920 ,
"reserve_multiplier_decimal": "2.4",
"max_exposure_limit_amount": 13133333300,
"funded_reserve_amount": 4733333300,
// other fields
}
See the following example response:
{
"object": {
"object": "issuing.credit_policy",
"credit_period_ends_on_days": null,
"credit_period_interval": "day",
"credit_period_interval_count": 1,
"current_exposure_limit_amount": 240,
"days_until_due": 0,
"exposure_limit_currency": "usd",
"funded_reserve_amount": 200,
"last_effective_attributes": {
"credit_period_ends_on_days": null,
"credit_period_interval": "day",
"credit_period_interval_count": 1,
"current_exposure_limit_amount": 103,
"days_until_due": 0,
"effective_until": 1728763199,
"max_exposure_limit_amount": 103,
"reserve_multiplier_decimal": "1.300",
"status": "active"
}
}
}
In the example above, if you submit your payout request from Tuesday through Friday before 10:00 UTC, the wire is disbursed by the end of the same business day. If you submit your payout request after that cut-off, it’s most likely disbursed by the end of the next business day. On Mondays or following a holiday weekend, an additional one-day delay occurs. Even if you initiate the payout before 10:00 UTC, the wire is disbursed by the end of the day after the next business day.
Card programme available spend
To add a field or balance that shows the amount your card programme has available to spend, use the following formula:
available credit = max_exposure_limit + issuing balance (issuing balance might be negative because of additional spend allowed by the exposure limit) |
|---|
Authorisation declines when post-funding
When post-funding, authorisations might be declined due to the following:
- FundingObligations is past _ due
- You exceed your max _ exposure _ limit _ amount
Declines for past due funding obligations
Stripe declines authorisations when a FundingObligation is past_due beyond the grace period defined in the grace_period_ends_at timestamp of the FundingObligation. Refer to the following example to find the grace_period_ends_at:
{
"id": "icfo_123",
"amount_total": 95000000, // minor units
"amount_outstanding": 95000000, // minor units
"amount_paid": 0,
"currency": "usd",
"status": "past_due",
"due_at": "timestamp_on_t1",
"paid_at": null,
"owed_to": "stripe",
"grace_period_ends_at": "timestamp_on_t2",
...,
}
If the grace period has passed, Stripe Issuing declines authorisations and sends issuing_authorization.created events with the following:
{
"id": "iauth_123",
"object": "issuing_authorization",
"approved": false,
...,
"status": "closed",
"request_history": [
{
"amount": 100, // minor units
"approved": false,
"reason": "past_due_funding_obligation_to_stripe",
...,
}
]
}
Declines because of the maximum exposure limit
Stripe immediately begins declining authorisations when you meet or exceed your max_exposure_limit. You can add reserves to increase the limit and avoid declines.
If you exceed your max_exposure_limit, Stripe Issuing declines authorisations and sends issuing_authorization.created events with the following:
{
"id": "iauth_123",
"object": "issuing_authorization",
"approved": false,
...,
"status": "closed",
"request_history": [
{
"amount": 100, // minor units
"approved": false,
"reason": "platform_exposure_limit_exceeded",
...,
}
]
}
Manage post-funding email notifications for your platform
Stripe sends several mandatory email notifications for post-funding. You can manage and set thresholds for the following email notifications in your Balance notification settings:
- Notification of a Stripe-initiated reserve withdrawal because of an unpaid FundingObligation .
- Notification of a FundingObligation becoming past _ due if your reserve is insufficient to cover it.
- Notification that your negative Issuing balance exceeded 90% of your max _ exposure _ limit _ amount .
Optionally, you can configure the threshold in the Dashboard to receive notifications when your platform’s negative Issuing balance exceeds a percentage threshold of your current_exposure_limit.