---
updatedAt: 2026-06-17T17:50:44.000Z
agentTools:
  siteIndex: https://developers.pismo.io/llms.txt
  projectIndex: https://developers.pismo.io/pismo-docs/llms.txt
---

# Get account interest

Get account interest details.

**Account identification.** The token identifies the account—the path alone is not
enough. Exactly one of `x-account-id` or `x-external-account-id` must be passed and must
match the `{accountId}` path parameter. Otherwise the request is rejected (`403` on a
mismatch or when neither header is passed, `400` when both are).

**Identifier validation.** The ID encoded in the token is confirmed to exist by calling
an external API before the interest account is read:

- `x-account-id`: An Accounts API call confirms the account ID exists. If it does not,
  the request fails with `400` and `account_id not found`.
- `x-external-account-id`: A Corporate API call resolves the external account ID to a
  Pismo `account_id`. If the external account ID does not exist, the request fails with
  `400` and `external_account_id not found`.

A `404` means the identifier is valid but the account has no interest configuration.
Any other failure of those APIs fails with `500`.


# OpenAPI definition

```json
{
  "openapi": "3.1.0",
  "info": {
    "title": "Banking - Interest engine",
    "version": "1.0.0",
    "description": "API to handle interest-bearing account operations",
    "termsOfService": "https://developers.pismo.io/terms/",
    "contact": {
      "name": "API Support",
      "url": "https://developers.pismolabs.io/pismo-docs/docs/support"
    },
    "license": {
      "name": "Copyright Pismo"
    }
  },
  "servers": [
    {
      "url": "https://sandbox.pismolabs.io/interest-engine",
      "description": "Sandbox API server for testing"
    },
    {
      "url": "https://sandbox.pismolabs.io/passport/v2/s2s/access-token",
      "description": "Sandbox API for oauth2"
    }
  ],
  "tags": [
    {
      "name": "Account interest",
      "description": "Manage account interest"
    }
  ],
  "components": {
    "parameters": {
      "AccountId": {
        "name": "accountId",
        "in": "path",
        "description": "Account ID. Must match the account encoded in the account token. This can be a Pismo account ID or an external account ID. A mismatch is rejected with `403 Forbidden`. Maximum 60 characters.",
        "required": true,
        "example": "8080",
        "schema": {
          "type": "string"
        }
      }
    },
    "schemas": {
      "Amount": {
        "type": [
          "number",
          "null"
        ],
        "format": "double",
        "description": "Amount in the `interest_by_tier`",
        "example": 1000
      },
      "BenchmarkResponse": {
        "type": "string",
        "description": "Market index returned in responses.\n  - `BOE`: Bank of England, UK\n  - `DI`: Interbank Deposit Contract, Brazil\n  - `FED`: Federal Reserve System, USA\n  - `FIXED`: Fixed interest rate, no market index\n  - `RBA`: Reserve Bank of Australia\n  - `RBI`: Reserve Bank of India\n  - `TO`: Overnight Interbank Target Rate (Tasa Objetivo), Mexico\n",
        "enum": [
          "BOE",
          "DI",
          "FED",
          "FIXED",
          "RBA",
          "RBI",
          "TO"
        ],
        "example": "FIXED"
      },
      "CapitalizationFrequency": {
        "type": "string",
        "description": "Interest payout frequency",
        "enum": [
          "DAILY",
          "MONTHLY",
          "QUARTERLY",
          "HALF_YEARLY",
          "YEARLY",
          "MATURITY"
        ],
        "example": "DAILY"
      },
      "ExternalAccountId": {
        "type": "string",
        "maxLength": 60,
        "description": "External account ID, at most 60 characters, provided by the client system that owns the account. It cannot be passed directly in a request body—it's parsed from an external account ID token, and it's included in responses and events for accounts that have it stored.",
        "example": "account-xyz-987"
      },
      "Days": {
        "type": "integer",
        "format": "int32",
        "description": "Number of days in `interest_by_tier`",
        "example": 30
      },
      "FeeProcessingCode": {
        "type": "string",
        "format": "number",
        "description": "Processing code configured in the [fee model](https://developers.pismo.io/pismo-docs/docs/fee-model) for charging a tax, penalty, or fee.",
        "example": "001100"
      },
      "TaxesExemption": {
        "type": "boolean",
        "description": "Is the account exempt from taxes?",
        "example": true
      },
      "WithholdingMoment": {
        "type": "string",
        "description": "Moment at which tax is withheld. When omitted, no withholding applies.",
        "enum": [
          "ACCRUAL",
          "CAPITALIZATION"
        ],
        "example": "ACCRUAL"
      },
      "TaxRule": {
        "type": "object",
        "description": "A single tax rule applied within a tax withholding configuration.",
        "required": [
          "description",
          "fixed_percentage"
        ],
        "properties": {
          "description": {
            "type": "string",
            "maxLength": 128,
            "description": "Description of the tax rule.",
            "example": "IOF"
          },
          "fixed_percentage": {
            "type": "number",
            "description": "Fixed percentage applied by the tax rule.",
            "example": 0.0038
          },
          "threshold_amount": {
            "type": [
              "number",
              "null"
            ],
            "format": "double",
            "description": "Optional monetary threshold amount associated with the tax rule. Use null when the rule does not depend on a threshold.",
            "example": null
          }
        }
      },
      "TaxWithholding": {
        "type": "object",
        "description": "Tax withholding configuration. Replaces the standalone `fee_processing_code` field.\nConditional rules enforced at creation/update time:\n- `ACCRUAL`: `fee_processing_code` is required; `tax_rules` must be omitted.\n- `CAPITALIZATION`: `tax_rules` is required; `fee_processing_code` must be omitted.\n- Omitted `withholding_moment`: both `fee_processing_code` and `tax_rules` must be omitted.\nIn GET responses, legacy plans that predate this field may return `fee_processing_code` with a null `withholding_moment`.\n",
        "required": [
          "withholding_moment"
        ],
        "properties": {
          "withholding_moment": {
            "$ref": "#/components/schemas/WithholdingMoment"
          },
          "fee_processing_code": {
            "$ref": "#/components/schemas/FeeProcessingCode"
          },
          "tax_rules": {
            "type": "array",
            "maxItems": 100,
            "items": {
              "$ref": "#/components/schemas/TaxRule"
            }
          }
        }
      },
      "FixedInterestRate": {
        "type": "number",
        "format": "float",
        "description": "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`.\n\nIf you pass a value for `benchmark`, this field must be null. Otherwise, it's required.\n",
        "example": 0.1
      },
      "GetInterestAccountResponse": {
        "title": "Get interest account response",
        "type": "object",
        "properties": {
          "benchmark": {
            "$ref": "#/components/schemas/BenchmarkResponse"
          },
          "fixed_interest_rate": {
            "$ref": "#/components/schemas/FixedInterestRate"
          },
          "margin_rate": {
            "$ref": "#/components/schemas/MarginRate"
          },
          "margin": {
            "$ref": "#/components/schemas/Margin"
          },
          "tax_withholding": {
            "$ref": "#/components/schemas/TaxWithholding"
          },
          "taxes_exemption": {
            "$ref": "#/components/schemas/TaxesExemption"
          },
          "interest_by_tiers": {
            "$ref": "#/components/schemas/InterestByTiers"
          },
          "capitalization_frequency": {
            "$ref": "#/components/schemas/CapitalizationFrequency",
            "description": "Account-level capitalization frequency configured for the interest account. Returned only when explicitly configured at account level. If not returned, the account uses the capitalization frequency from the associated interest plan during processing."
          },
          "external_account_id": {
            "$ref": "#/components/schemas/ExternalAccountId",
            "description": "This is the external account ID parsed from a request's account token. Returned only when a request was made with an external ID token. Omitted otherwise, including if the request used a Pismo account ID token, even if an external account ID was previously stored."
          },
          "account_id": {
            "type": "string",
            "description": "Pismo account ID. Returned only when the request was authenticated with a Pismo account ID token. Omitted otherwise.",
            "example": "8080"
          }
        }
      },
      "InterestByTiers": {
        "type": "object",
        "properties": {
          "type": {
            "$ref": "#/components/schemas/InterestByTiersType"
          },
          "tier_calculation": {
            "$ref": "#/components/schemas/TierCalculation"
          },
          "tiers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InterestByTiersArrayObject"
            }
          }
        },
        "required": [
          "type",
          "tier_calculation",
          "tiers"
        ],
        "description": "Interest by tiers configuration",
        "example": {
          "type": "TERM",
          "tier_calculation": "RETROACTIVE",
          "tiers": [
            {
              "days": 30,
              "amount": 1000,
              "margin_rate": 1,
              "fixed_interest_rate": 1.2
            },
            {
              "days": 60,
              "amount": 2000,
              "margin_rate": 1,
              "fixed_interest_rate": 1.3
            }
          ]
        }
      },
      "InterestByTiersArrayObject": {
        "type": "object",
        "properties": {
          "days": {
            "$ref": "#/components/schemas/Days"
          },
          "amount": {
            "$ref": "#/components/schemas/Amount"
          },
          "margin_rate": {
            "$ref": "#/components/schemas/MarginRate"
          },
          "fixed_interest_rate": {
            "$ref": "#/components/schemas/FixedInterestRate"
          }
        },
        "description": "Tier details for interest calculation"
      },
      "InterestByTiersType": {
        "type": "string",
        "description": "Interest type\n- `TERM`: Interest rate varies according to the period of time since the deposit was made.\n- `AMOUNT`: Interest rate varies according to the current balance.\n",
        "enum": [
          "TERM",
          "AMOUNT"
        ],
        "example": "TERM"
      },
      "Margin": {
        "type": "number",
        "format": "double",
        "description": "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.\n\nIf you pass a value for `benchmark`, this field is optional. If `benchmark` is null, this field must be null also.\n",
        "example": 0.02
      },
      "MarginRate": {
        "type": [
          "number",
          "null"
        ],
        "format": "double",
        "description": "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.\n\nIf you don't pass a value for `benchmark`, this field must be null. Otherwise, it's required.\n",
        "example": 1.1
      },
      "TierCalculation": {
        "type": "string",
        "description": "Tier calculation method\n- `RETROACTIVE`: Interest is recalculated from the beginning based on the new applicable rate.\n- `NON-RETROACTIVE`: Interest is calculated progressively based on each layer rate.\n",
        "enum": [
          "RETROACTIVE",
          "NON-RETROACTIVE"
        ],
        "example": "RETROACTIVE"
      },
      "ErrorResponse": {
        "type": "object",
        "description": "Standard error payload generated by the global exception handler.\n`message` is a single string for most errors and an array of strings\nwhen multiple bean-validation or request-binding errors occur in the same request.\n",
        "additionalProperties": false,
        "required": [
          "message"
        ],
        "properties": {
          "message": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            ]
          }
        },
        "example": {
          "message": "interest account not found"
        }
      },
      "ErrorResponseDeserialization": {
        "type": "object",
        "description": "Error payload generated only when the request body fails JSON deserialization\n(unknown field or invalid JSON structure). Returned with HTTP 400.\n",
        "additionalProperties": false,
        "required": [
          "error",
          "status"
        ],
        "properties": {
          "error": {
            "type": "string",
            "description": "Short error category."
          },
          "message": {
            "type": "string",
            "description": "Details about the field or structure that causes the error."
          },
          "field": {
            "type": "string",
            "description": "Name of the invalid field. Present only for unknown-field errors."
          },
          "status": {
            "type": "integer",
            "description": "HTTP status code, always 400 for this shape."
          }
        },
        "example": {
          "error": "Invalid field in request",
          "message": "Field 'foo' is not allowed. Only the following fields can be updated: start_date, description, fixed_interest_rate, margin_rate, margin, interest_by_tiers, interest_thresholds",
          "field": "foo",
          "status": 400
        }
      }
    },
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      }
    },
    "responses": {
      "400BadRequestForGetAccountInterest": {
        "description": "Bad request",
        "content": {
          "application/json": {
            "schema": {
              "anyOf": [
                {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                {
                  "$ref": "#/components/schemas/ErrorResponseDeserialization"
                }
              ]
            },
            "examples": {
              "tenantHeader": {
                "summary": "Tenant header missing or malformed",
                "value": {
                  "message": "x-tenant header is missing or malformed"
                }
              },
              "accountIdNotValid": {
                "summary": "Invalid account ID",
                "value": {
                  "message": "this account_id is not valid"
                }
              },
              "accountIdentifierNotValid": {
                "summary": "Invalid account identifier",
                "value": {
                  "message": "this account identifier is not valid"
                }
              },
              "missingAccountID": {
                "summary": "Account ID not passed",
                "value": {
                  "message": "account_id must be informed"
                }
              },
              "xAccountIdAndXExternalAccountIdBothPassed": {
                "summary": "x-account-id and x-external-account-id both passed",
                "value": {
                  "message": "x-account-id and x-external-account-id must not be informed together"
                }
              },
              "accountIdNotFound": {
                "summary": "Account ID not found",
                "value": {
                  "message": "account_id not found"
                }
              },
              "externalAccountIdNotFound": {
                "summary": "External account ID not found",
                "value": {
                  "message": "external_account_id not found"
                }
              }
            }
          }
        }
      },
      "401Unauthorized": {
        "description": "Unauthorized. The response body is produced by the upstream authentication gateway and is not defined by this service."
      },
      "403Forbidden": {
        "description": "Forbidden",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "message": "This request is forbidden"
            }
          }
        }
      },
      "404NotFound": {
        "description": "Not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "examples": {
              "interestAccountNotFound": {
                "summary": "Interest account not found",
                "value": {
                  "message": "interest account not found"
                }
              },
              "interestPlanNotFound": {
                "summary": "Interest plan not found",
                "value": {
                  "message": "interest plan not found"
                }
              },
              "benchmarkNotFound": {
                "summary": "Benchmark not found",
                "value": {
                  "message": "benchmark not found"
                }
              }
            }
          }
        }
      },
      "500InternalServerError": {
        "description": "Internal server error",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "message": "Failed to process your request"
            }
          }
        }
      }
    }
  },
  "security": [
    {
      "BearerAuth": []
    }
  ],
  "paths": {
    "/v1/interest/account/{accountId}": {
      "get": {
        "summary": "Get account interest",
        "description": "Get account interest details.\n\n**Account identification.** The token identifies the account—the path alone is not\nenough. Exactly one of `x-account-id` or `x-external-account-id` must be passed and must\nmatch the `{accountId}` path parameter. Otherwise the request is rejected (`403` on a\nmismatch or when neither header is passed, `400` when both are).\n\n**Identifier validation.** The ID encoded in the token is confirmed to exist by calling\nan external API before the interest account is read:\n\n- `x-account-id`: An Accounts API call confirms the account ID exists. If it does not,\n  the request fails with `400` and `account_id not found`.\n- `x-external-account-id`: A Corporate API call resolves the external account ID to a\n  Pismo `account_id`. If the external account ID does not exist, the request fails with\n  `400` and `external_account_id not found`.\n\nA `404` means the identifier is valid but the account has no interest configuration.\nAny other failure of those APIs fails with `500`.\n",
        "tags": [
          "Account interest"
        ],
        "operationId": "get-v1-interest-account",
        "parameters": [
          {
            "$ref": "#/components/parameters/AccountId"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetInterestAccountResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400BadRequestForGetAccountInterest"
          },
          "401": {
            "$ref": "#/components/responses/401Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/403Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/404NotFound"
          },
          "500": {
            "$ref": "#/components/responses/500InternalServerError"
          }
        }
      }
    }
  }
}
```