---
title: "Simulate debt payoff"
method: POST
path: "/v1/tools/betteroff_simulate_debt_payoff"
tags: ["tools"]
---

# Simulate debt payoff

`POST /v1/tools/betteroff_simulate_debt_payoff`

## Request

- Base URL: `https://api.betteroff.finance`
- URL: `https://api.betteroff.finance/v1/tools/betteroff_simulate_debt_payoff`
- Auth: one of:
  - OpenID Connect (`https://app.betteroff.finance/api/auth/.well-known/openid-configuration`, scopes: `debts:read`)
  - HTTP bearer

Use this when the user asks to compare debt payoff strategies. Simulate paying off debts by avalanche (highest APR first) or snowball (smallest balance first), with an optional extra monthly payment. Refuses with missingInputs when a balance, APR, minimum payment, or FX rate is missing; betteroff_propose_debt_details saves terms the user states. Read-only; never moves money.

## Request body

- object
  - `strategy` 'avalanche' | 'snowball', required: avalanche = highest APR first (minimizes interest); snowball = smallest balance first (faster early wins).
  - `extraMonthly` number, required: Extra amount paid toward debts each month beyond the minimums, in the user's base currency. Use 0 for none.

## Response `200`

Tool result

- union
  - object
    - `ok` false, required
    - `requestId` string
    - `error` string, required
    - `code` string, required
    - `retryable` boolean, required
    - `nextStep` string, required
    - `field` string
    - `missingInputs` object[]
      - `id` string, required
      - `name` string, required
      - `balanceMissing` boolean, required
      - `interestRateMissing` boolean, required
      - `minimumPaymentMissing` boolean, required
  - object
    - `ok` true, required
    - `requestId` string
    - `schemaVersion` '4', required
    - `data` object, required
      - `baseCurrency` string, required
      - `feasible` boolean, required
      - `totalMonths` number, nullable, required
      - `totalInterest` string, required: Decimal text, e.g. "-12.50". Read the currency beside it or on the result.
      - `order` object[], required
        - `id` string, required
        - `name` string, required
        - `payoffMonth` number, required
    - `currency` string, nullable, required
    - `timezone` string, required
    - `asOf` string, nullable, required
    - `revision` integer, required
    - `householdRevision` integer, required
    - `quality` object, required
      - `state` 'complete' | 'partial' | 'unavailable', required
      - `reasons` string[], required
    - `evidence` object[], required
      - `source` string, required
      - `id` string
      - `observedAt` string, nullable, required
    - `page` object, required
      - `returnedCount` integer, required
      - `totalCount` integer, nullable, required
      - `truncated` boolean, required
      - `nextCursor` Schema0, required (unresolved $ref)
    - `warnings` string[], required
    - `notes` string

## Other responses

- `400`: INVALID_INPUT (a missing, unknown, or invalid argument, named in `fields`), TOOL_CALL_REJECTED, or a body that is not JSON.
- `401`: AGENT_TOKEN_INVALID: the token is missing, expired, or revoked.
- `402`: AGENT_SUBSCRIPTION_INACTIVE or FEATURE_NOT_INCLUDED: needs BetterOff Core.
- `403`: INSUFFICIENT_SCOPE, ACCESS_DENIED, or AGENT_GRANT_REVOKED.
- `404`: TOOL_NOT_FOUND, or NOT_FOUND for a record the org does not have.
- `409`: CONFLICT: the record's state rules this call out. Read it again.
- `422`: INCOMPLETE_DATA or RESULT_TOO_LARGE. Narrow the request; don't retry as is.
- `429`: RATE_LIMITED. Retry after Retry-After seconds.
- `503`: DATA_UNAVAILABLE, DEPENDENCY_UNAVAILABLE (including the 25-second tool deadline), or AGENT_AUTHZ_UNAVAILABLE. Retryable.
- `default`: Problem details

---

[API](https://skmtc.dev/betteroff/apis/betteroff-api.md) · [All operations](https://skmtc.dev/betteroff/apis/betteroff-api/llms.txt) · [OpenAPI document](https://skmtc.dev/betteroff/apis/betteroff-api/revisions/bc858c8d428d?raw)
