---
title: "Estimate a cancellation’s money effects"
description: "Dry-run."
canonical_url: "https://twominutebilling.com/help/developers/api-reference/subscriptions/estimate-a-cancellation-s-money-effects"
---
# Estimate a cancellation’s money effects

> Dry-run.

<api-operation method="POST" path="/v1/businesses/{biz}/subscriptions/{sub}/cancel_estimate">
<template v-slot:docs="">

No writes. Prices all four money effects of `POST …/cancel` under a given option set: the unbilled charges it would invoice or delete, the credit for the unused part of the term, what happens to still-open invoices, and which refundable credit notes would be refunded. Omitted options are resolved from the business defaults exactly as the cancel resolves them, so an empty body previews the cancellation you get by confirming with nothing selected. `warnings` names anything that will NOT happen the way the option set implies — most importantly, an `end_of_term` cancellation runs no credit, open-invoice or refund step. At the term end it only raises a final invoice for the term's metered usage and pending unbilled charges, and it ignores every other option.

## Path parameters

<table>
<thead>
  <tr>
    <th>
      Parameter
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Required
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        biz
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <strong>
        yes
      </strong>
    </td>
    
    <td>
      Business id (biz_…)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        sub
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <strong>
        yes
      </strong>
    </td>
    
    <td>
      Subscription id (sub_…)
    </td>
  </tr>
</tbody>
</table>

## Body

The request body is optional.

<table>
<thead>
  <tr>
    <th>
      Field
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Required
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        cancel_option
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      <code>
        end_of_billing_term
      </code>
      
       ends at the close of the billed term, which is the current term — it is <code>
        end_of_term
      </code>
      
      . One of <code>
        immediately
      </code>
      
      , <code>
        end_of_term
      </code>
      
      , <code>
        specific_date
      </code>
      
      , <code>
        end_of_billing_term
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        cancel_at
      </code>
    </td>
    
    <td>
      <code>
        string · ISO-8601
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      Required when <code>
        cancel_option=specific_date
      </code>
      
      , and must be in the future. The estimate is priced AS OF this instant, because the scheduled-changes pass applies it as an immediate cancel with these same options.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        include_cancellation_day_in_billing
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      Same as on <code>
        POST …/cancel
      </code>
      
      , with the same refusals.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        credit_option_for_current_term_charges
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      How the current term's charges are credited: <code>
        none
      </code>
      
      , <code>
        prorate
      </code>
      
       or <code>
        full
      </code>
      
      . One of <code>
        none
      </code>
      
      , <code>
        prorate
      </code>
      
      , <code>
        full
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        unbilled_charges_option
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      What to do with unbilled charges: <code>
        invoice
      </code>
      
       or <code>
        delete
      </code>
      
      . One of <code>
        invoice
      </code>
      
      , <code>
        delete
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        account_receivables_handling
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      What to do with unpaid invoices. One of <code>
        no_action
      </code>
      
      , <code>
        schedule_payment_collection
      </code>
      
      , <code>
        write_off
      </code>
      
      , <code>
        void
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        refundable_credits_handling
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      What to do with refundable credits. One of <code>
        no_action
      </code>
      
      , <code>
        schedule_refund
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        at_period_end
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      Shorthand for <code>
        cancel_option=end_of_term
      </code>
      
      , honoured identically to the cancel route.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        final_period
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      As on <code>
        POST …/cancel
      </code>
      
      , with the same refusals. Prices that credit. Omitted with <code>
        cancel_option=specific_date
      </code>
      
      : the business rule, as the cancel resolves it. One of <code>
        full_period
      </code>
      
      , <code>
        prorated
      </code>
      
      , <code>
        nothing
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        plan_credits
      </code>
    </td>
    
    <td>
      <code>
        object
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      The business's plan credit rules, set for this call only.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        plan_credits.on_cancel_at_period_end
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      As on <code>
        POST …/cancel
      </code>
      
      , with the same refusals. Moves no money, so the estimate does not change. One of <code>
        grant_started_window
      </code>
      
      , <code>
        stop_at_request
      </code>
      
      .
    </td>
  </tr>
</tbody>
</table>

## Response

<table>
<thead>
  <tr>
    <th>
      Field
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        object
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      The object type; always <code>
        cancel_estimate
      </code>
      
      . One of <code>
        cancel_estimate
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        currency
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      The currency of the amounts (ISO-4217 code).
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        options
      </code>
    </td>
    
    <td>
      <code>
        object
      </code>
    </td>
    
    <td>
      The option set actually previewed, with business defaults filled in.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        effective_at
      </code>
    </td>
    
    <td>
      <code>
        string · ISO-8601
      </code>
    </td>
    
    <td>
      When the cancellation takes effect. Every figure is computed as of this instant from TODAY’s state — for a deferred cancellation that state can still change first.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        immediate
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      False when nothing moves today because the cancellation is deferred.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        unbilled_charges
      </code>
    </td>
    
    <td>
      <code>
        object
      </code>
    </td>
    
    <td>
      <code>
        action
      </code>
      
       is <code>
        none
      </code>
      
       when no option was set, in which case the pending charges are left stranded on the cancelled subscription (also raised in <code>
        warnings
      </code>
      
      ). Under <code>
        invoice
      </code>
      
       the charges are taxed, customer credit is applied, and the invoice is raised OPEN — which is why it also appears in <code>
        open_invoices
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        cancellation_credit
      </code>
    </td>
    
    <td>
      <code>
        object
      </code>
    </td>
    
    <td>
      <code>
        delivery
      </code>
      
       is <code>
        adjustment
      </code>
      
       when the term invoice is still open (it reduces what is owed), <code>
        split
      </code>
      
       when the term was paid (bucket-funded slices return to their buckets; only the cash-funded slice becomes a refundable credit note), or <code>
        none
      </code>
      
      . <code>
        already_credited
      </code>
      
       true means a prior cancellation credited this term and this one grants nothing further.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        open_invoices
      </code>
    </td>
    
    <td>
      <code>
        object
      </code>
    </td>
    
    <td>
      Invoices the AR step would act on, each with its due AFTER any adjustment credit. Includes the invoice <code>
        unbilled_charges_option=invoice
      </code>
      
       would create, marked <code>
        projected
      </code>
      
      . With <code>
        void
      </code>
      
      , an invoice that cannot be voided (a payment on it, one in progress, or tax withheld) carries <code>
        void_blocked
      </code>
      
       with the reason, is left open, and is not counted in <code>
        void_minor
      </code>
      
      . <code>
        mandate_shortfall
      </code>
      
       is set when the largest single collection attempt exceeds the instrument’s per-debit mandate ceiling.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        refundable_credits
      </code>
    </td>
    
    <td>
      <code>
        object
      </code>
    </td>
    
    <td>
      Refundable credit notes the CUSTOMER holds — not scoped to this subscription, because the cancel path is not either.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        net_collect_minor
      </code>
    </td>
    
    <td>
      <code>
        integer
      </code>
    </td>
    
    <td>
      The net amount to collect, in minor units.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        net_refund_minor
      </code>
    </td>
    
    <td>
      <code>
        integer
      </code>
    </td>
    
    <td>
      The net amount to refund, in minor units.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        net_credit_minor
      </code>
    </td>
    
    <td>
      <code>
        integer
      </code>
    </td>
    
    <td>
      The net credit to the customer, in minor units.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        warnings
      </code>
    </td>
    
    <td>
      <code>
        array of string
      </code>
    </td>
    
    <td>
      Things that will NOT happen the way the option set implies. Empty means no known discrepancy.
    </td>
  </tr>
</tbody>
</table>

## Status codes

<table>
<thead>
  <tr>
    <th>
      Status
    </th>
    
    <th>
      Meaning
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        200
      </code>
    </td>
    
    <td>
      Cancel estimate
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        400
      </code>
    </td>
    
    <td>
      Invalid cancellation option set
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        404
      </code>
    </td>
    
    <td>
      No such subscription
    </td>
  </tr>
</tbody>
</table>
</template>

<template v-slot:request="">

```bash [Request]
curl -X POST "$TMBILLING_URL/v1/businesses/biz_XXXXXXXXXXXX01/subscriptions/sub_XXXXXXXXXXXX01/cancel_estimate" \
  -H "Authorization: Bearer $TMBILLING_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "cancel_option": "immediately",
    "cancel_at": "2026-03-14T09:30:00Z"
  }'
```

</template>

<template v-slot:response="">
<code-group>

```json [200 OK]
{
  "object": "cancel_estimate",
  "currency": "USD",
  "options": {},
  "effective_at": "2026-03-14T09:30:00Z",
  "immediate": false,
  "unbilled_charges": {},
  "cancellation_credit": {},
  "open_invoices": {},
  "refundable_credits": {},
  "net_collect_minor": 2900,
  "net_refund_minor": 2900,
  "net_credit_minor": 2900,
  "warnings": [
    "Warning"
  ]
}
```

```json [400 Bad Request]
{
  "error": {
    "type": "invalid_request_error",
    "message": "Invalid cancellation option set"
  }
}
```

```json [404 Not Found]
{
  "error": {
    "type": "invalid_request_error",
    "message": "No such subscription"
  }
}
```

</code-group>
</template>
</api-operation>


## Sitemap

See the full [sitemap](https://twominutebilling.com/sitemap.md) for all pages.
