---
title: "Create interest plan version"
method: PATCH
path: "/v1/interest/plan/{interestPlanId}"
tags: ["Interest engine"]
---

# Create interest plan version

`PATCH /v1/interest/plan/{interestPlanId}`

## Request

- Base URL: `https://sandbox.pismolabs.io/interest-engine`
- URL: `https://sandbox.pismolabs.io/interest-engine/v1/interest/plan/{interestPlanId}`
- Auth: HTTP bearer

Create a new version of an existing interest plan. This endpoint allows you to update specific fields while preserving others from the previous version.

Key features:
- Creates a new version with the specified `start_date`.
- Updates only the provided fields—any field not specified inherits the value from the previous version.
- Validates that the new `start_date` is after the `start_date` of the previous version.
- Maintains immutable fields like `interest_type` and `tier_calculation`.
- Preserves existing tiers when updating `interest_by_tiers`—only specified tiers are updated.

This endpoint generates an [Interest plan created](https://developers.pismo.io/events/docs/interest-engine-interest-plan-creation-success-1) event.

## Path parameters

- `interestPlanId` string, required

## Request body

- InterestPlanVersionRequest
  - `start_date` string, date, required: Date to start applying the new interest plan version. Format = YYYY-MM-DD. Must be greater than or equal to current date.
  - `description` string: Interest plan name
  - `fixed_interest_rate` number, float, nullable: Nominal annual interest rate, expressed as a decimal fraction. 0.10 = 10% per year. 1.00 = 100% per year. Do not send 10 for 10%. Maximum precision: 8 decimal places. The platform converts this annual rate to the accrual period using `accrual_basis` and `interest_type`. If you pass a value for `benchmark`, this field must be null. Otherwise, it's required.
  - `margin` number, double: Additive spread, in the same unit and period as the benchmark rate: nominal annual, decimal fraction. If `benchmark` is 0.025 and `margin` is 0.0225, the resulting annual rate is 0.0475. If you pass a value for `benchmark`, this field is optional. If `benchmark` is null, this field must be null also.
  - `margin_rate` number, double, nullable: Multiplier applied to the benchmark rate, expressed as a decimal fraction of 100%. 1.00 = 100% of the benchmark. 1.10 = 110% of the benchmark. 0.95 = 95% of the benchmark. This is not added to the benchmark—use `margin` for an additive spread. If you don't pass a value for `benchmark`, this field must be null. Otherwise, it's required.
  - `interest_by_tiers` InterestByTiers: Interest by tiers configuration
    - `type` 'TERM' | 'AMOUNT', required: Interest type - `TERM`: Interest rate varies according to the period of time since the deposit was made. - `AMOUNT`: Interest rate varies according to the current balance.
    - `tier_calculation` 'RETROACTIVE' | 'NON-RETROACTIVE', required: Tier calculation method - `RETROACTIVE`: Interest is recalculated from the beginning based on the new applicable rate. - `NON-RETROACTIVE`: Interest is calculated progressively based on each layer rate.
    - `tiers` InterestByTiersArrayObject[], required
      - `days` integer, nullable: Number of days in `interest_by_tier`
      - `amount` number, double, nullable: Amount in the `interest_by_tier`
      - `margin_rate` number, double, nullable: Multiplier applied to the benchmark rate, expressed as a decimal fraction of 100%. 1.00 = 100% of the benchmark. 1.10 = 110% of the benchmark. 0.95 = 95% of the benchmark. This is not added to the benchmark—use `margin` for an additive spread. If you don't pass a value for `benchmark`, this field must be null. Otherwise, it's required.
      - `fixed_interest_rate` number, float, nullable: Nominal annual interest rate, expressed as a decimal fraction. 0.10 = 10% per year. 1.00 = 100% per year. Do not send 10 for 10%. Maximum precision: 8 decimal places. The platform converts this annual rate to the accrual period using `accrual_basis` and `interest_type`. If you pass a value for `benchmark`, this field must be null. Otherwise, it's required.
  - `interest_thresholds` InterestThresholds: Cap and floor thresholds for the interest plan
    - `cap_threshold` number, double: Cap threshold value. If you pass a value for `cap_threshold`, you must also pass a value for `cap_effective_rate`.
    - `cap_effective_rate` number, double: Cap effective rate. If you pass a value for `cap_effective_rate`, you must also pass a value for `cap_threshold`.
    - `floor_threshold` number, double: Floor threshold value
    - `floor_effective_rate` number, double: Floor effective rate

## Response `200`

OK

- InterestPlanVersionResponse
  - `interest_plan_id` string, uuid: Interest plan ID generated during the plan's creation. Must be an alphanumeric UUID with the alphabetical characters in lowercase.
  - `version` string: ID for the new interest plan version

## Other responses

- `400`: Bad request
- `401`: Unauthorized. The response body is produced by the upstream authentication gateway and is not defined by this service.
- `404`: Not found
- `409`: Conflict: A version with this start date already exists
- `500`: Internal server error

---

[API](https://skmtc.dev/pismo/apis/banking-interest-engine.md) - [All operations](https://skmtc.dev/pismo/apis/banking-interest-engine/llms.txt) - [OpenAPI document](https://skmtc.dev/pismo/apis/banking-interest-engine/revisions/50c20b2cac0c?raw)
