Ledger API 2026-09-01
Refund headroom reservation, pending refund total, and refund events.
This is a release-history archive topic. For current integration guidance, see the Ledger API package page.
Changes in 2026-09-01
Overview
Ledger API 2026-09-01 makes refunds that are still processing count against a
payment's refund headroom, adds the fields and events needed to track those
refunds, and corrects the status returned for a missing If-Match header.
This release changes refund behavior. Review the compatibility information
before you pin to it.
New Features
- Pending refund total:
Payment.amount_refund_pendingcarries the total of refunds that are stillprocessing. The remaining refund headroom on a payment isamount - amount_refunded - amount_refund_pending. - Refund retrieval and events:
GET /v1/refunds/{refund_id}returns a single refund, and therefund.succeededandrefund.failedwebhooks report when a refund reaches a terminal state. An integration that waits for one refund to finish before it issues the next can now observe that directly. - Refund settlement time:
Refund.settled_atrecords when a refund reached a terminal state, separately fromcreated_at, so reconciliation can align each refund to the period in which it completed.
Enhancements
- Refund headroom reservation: A refund that is still
processingreserves its amount against the payment. A new refund is accepted only if it fits in the remaining headroom, and the check and the reservation are a single atomic step. A request that does not fit returns422 refund_amount_exceeded. Previously, onlysucceededrefunds counted, so two concurrent ₹600 refunds against a ₹1,000 payment were both accepted and the payer received ₹1,200. - Refunded amount:
Payment.amount_refundedcounts onlysucceededrefunds, which is the money actually returned to the payer. It previously also counted refunds that were stillprocessing, so the field showed a pending refund as spent while the refund check ignored it.
Fixes
- Missing
If-Matchheader: When aPATCH /v1/invoices/{invoice_id}request has noIf-Matchheader, the API returns428 precondition_required. It previously returned412 precondition_failed, the status for a stale value, so a client could not tell the two conditions apart. This fix applies to every release.
Compatibility
The refund headroom and amount_refunded changes apply only to requests
pinned to 2026-09-01 or later. Accounts created before this date keep their
existing pin until they send Ledger-Version: 2026-09-01.
amount_refund_pending is returned only from this release, because on earlier
releases amount_refunded still includes pending refunds and returning both
would count them twice. GET /v1/refunds/{refund_id}, the two refund
webhooks, and settled_at are available on every release.
Review every read of amount_refunded, and every code path that can issue
more than one refund against a payment, before you pin to this release. Refer
to Migrating to 2026-09-01
for the full procedure, including a sandbox test.
Known Issues
- Several earlier SDK versions apply the
Ledger-Versionvalue set when the client is created and ignore a per-call override. Confirm the header on the outgoing request when you test this release.