---
title: "Attach deposit to account"
method: POST
path: "/v1/deposits/accounts/{accountId}/attach"
tags: ["Account attachment"]
---

# Attach deposit to account

`POST /v1/deposits/accounts/{accountId}/attach`

## Request

- Base URL: `https://sandbox.pismolabs.io/savings-products`
- URL: `https://sandbox.pismolabs.io/savings-products/v1/deposits/accounts/{accountId}/attach`
- Auth: HTTP bearer

Attach a time deposit product to an account.
This endpoint generates the [Account attached](https://developers.pismo.io/events/docs/deposit-product-account-attach-1) event.

## Path parameters

- `accountId` string, required

## Request body

- DepositAttachRequest
  - `product_id` string, required: Product identifier.
  - `effective_date` string, date: Backdated effective date for the attachment in `YYYY-MM-DD` format. This is the date starting from which the attachment is considered valid. - If omitted, it defaults to the current date - Must be less than or equal to the current date (cannot be in the future) - Cannot be more than `ATTACHMENT_MAX_BACKDATING_DAYS` (default: 90 days) in the past - Maturity date is calculated from this date, not from the date when you call the API. - No retroactive interest accrual, capitalization, or postings are triggered
  - `deposit_configs` DepositConfigs
    - `maturity_period` MaturityPeriod: Defines when the deposit matures. There are three usage modes: * **Relative period**: Sends `unit` + `value` (e.g. `MONTHS` + `6`). * **Explicit date**: Sends `calendar_maturity_date` (e.g. `2027-06-15`). * **Default**: Omits the field or sends `{}`. The product's configured default maturity term (`PRODUCT_DEFAULT_MATURITY_DATE_DAYS`, typically `10950` days ≈ 30 years) is applied. **NOTE**: `calendar_maturity_date` and `unit`/`value` are mutually exclusive, sending both in the same request returns a `400` validation error. In the **attach** endpoints, the response returns exactly what was sent in the request: * Send `unit` + `value` returns `unit` + `value` * Send `calendar_maturity_date` returns `calendar_maturity_date` * Send nothing (default fallback applied) returns `unit=DAYS` and `value` equal to the product's configured `PRODUCT_DEFAULT_MATURITY_DATE_DAYS` **NOTE**: this behavior applies only to attach. The `GET` attachment endpoints and `PATCH /v1/deposits/accounts/{accountId}/attachment` return the resolved term, with `unit`, `value`, and `calendar_maturity_date` populated together. A `PATCH` sent in explicit‑date form is returned normalized as `{unit: DAYS, value: <days>, calendar_maturity_date: <date>}`.
      - `unit` 'DAYS' | 'WEEKS' | 'MONTHS' | 'YEARS': Time unit for the relative maturity period. It's used together with `value` and cannot coincide with `calendar_maturity_date`. - `DAYS`: Uses `value` directly. Example: `value=90` → 90 days. - `WEEKS`: Multiplies `value` by 7. Example: `value=4` → 28 days. - `MONTHS`: Calculates calendar-month with end-of-month (EOM) clamping when the target day does not exist. The maturity date falls on the same day of the month as the start date. Example: `2026-09-22` + 3 months = `2026-12-22`; `2024-01-31` + 1 month = `2024-02-29` (leap year) or `2025-02-28` (non-leap year). - `YEARS`: Calculates calendar-year, for example: `2024-02-29` + 1 year = `2025-02-28`. Note that there is no Feb 29 in 2025. For `WEEKS`, `MONTHS`, and `YEARS`, the resulting calendar date is converted back to a day count to validate against the product's configured minimum or maximum term.
      - `value` integer: Number of time units until maturity. Must be greater than `0`. Mutually exclusive with `calendar_maturity_date`.
      - `calendar_maturity_date` string, date: Maturity date. Format is `YYYY-MM-DD`. The date must be a future date. This date cannot coincide with `unit`/`value`, sending both in the same request returns a `400` validation error.
    - `payout_account` PayoutAccount: The payout account defines where outbound payments are sent, and it is used in two operational contexts.<br> * **Capitalization flow**: When the capitalization mode is set to `PAYOUT`, the capitalized interest is directed to this account. If the mode is `REINVEST`, the payout account is not involved because the interest is added to the principal instead. * **Maturity instruction flow**: At maturity, this account receives principal or interest whenever the maturity instructions specify `PAY` for either `maturity_instructions.principal` or `maturity_instructions.interest`. This flow always relies on the payout account, regardless of how capitalization is configured. Both flows reference the same payout account settings. Choosing `REINVEST` for capitalization does not remove or disable the payout account, and it remains fully available for maturity‑related payments.
      - `label` string: Label to identify the account
      - `type` 'INTERNAL' | 'EXTERNAL': Payout account type, either `INTERNAL` or `EXTERNAL`
      - `internal_account_id` number: Internal account ID for the account that receives the payments. Required for type `INTERNAL` and not allowed for `EXTERNAL`.
      - `external_account` object: Contains user-defined key-value pairs that identify the external account receiving the payments. Note that external account information is client-provided. Required for type `EXTERNAL` and not allowed for `INTERNAL`.
    - `interest_capitalization_mode` 'REINVEST' | 'PAYOUT': Controls the treatment of capitalized interest. Optional field.<br> * `REINVEST` (default): The Pismo platform adds the capitalized amount to the principal. The new principal becomes the foundation for the next accrual cycle. No `payout_account` is required. * `PAYOUT` (explicit): The capitalized amount is routed to `payout_account`. A valid `payout_account` is **required** in this request when this value is passed explicitly—omitting it returns `400 EIBACC0379`. * `Omitted`: The Pismo platform applies `REINVEST`. Both the GET operation and events return `REINVEST`. This setting affects only the capitalization process. The maturity instruction flow always uses `payout_account`, regardless of the value of this field.
    - `overrides` AttachmentOverridesRequest: Per-attachment overrides applied on top of the product defaults. All sub-fields are optional. This object contains the per‑attachment overrides that supplement the product defaults. All sub‑fields are optional. Omitting a section causes the Pismo platform to follow the normal fallback sequence, moving from the account level to the program and then to the product defaults. Each penalty type provides `waived` as a required field, optional type‑specific fields, and an optional `valid_until` to schedule the revert.
      - `maturity_instructions` MaturityInstructionsOverrideRequest: Overrides the deposit’s behavior at maturity. If a field is omitted, the Pismo platform uses the value defined at the higher‑level configuration that governs this deposit.
        - `principal` 'ROLLOVER' | 'PAY': Specifies how the principal is handled once the deposit matures.
        - `interest` 'ROLLOVER' | 'PAY': Specifies how the interest is handled once the deposit matures.
        - `reason` string: Optional audit-trail reason.
      - `renewal_term` RenewalTermOverrideRequest: Specifies the recurring rollover term, not to be confused with the initial `maturity_period`. You must provide either `unit` with `value` or `renewal_calendar_maturity_date`. A `ROLLOVER` configuration in principal or interest is required. When you pass `renewal_calendar_maturity_date`, the Pismo platform converts the interval from today into a day count and stores it at attach time in normalized form: `{unit: DAYS, value: <calculated>}`.
        - `unit` 'DAYS' | 'WEEKS' | 'MONTHS' | 'YEARS': Time unit of the renewal term. Required together with `value` when calendar form is not used.
        - `value` integer: Number of units. Required together with `unit` when calendar form is not used.
        - `renewal_calendar_maturity_date` string, date: Explicit calendar date (`YYYY-MM-DD`), the date must be a future date, and does not coincide with `unit`+`value`.
      - `penalties` PenaltiesOverrideRequest: Per-type penalty overrides. Each type independently uses three-state semantics: omit (inherit) · `{waived: true}` (exempt) · `{waived: false, <fields>}` (customize).
        - `reason` string: Optional audit-trail reason for the entire penalties block.
        - `grace_period` GracePeriodOverrideRequest: Grace period override. Type-specific fields are optional pointers, when omitted, the Pismo platform follows the normal fallback sequence, moving from the account level to the program and then to the product defaults.
          - `waived` boolean, required: `true` = fully exempt; `false` = penalty active (customize via the fields below).
          - `duration_days` integer
          - `penalty_interest_days` integer
          - `valid_until` string, date-time: Schedules the revert of this override via EventBridge. This value must be a future date and follows the ISO 8601 standard.
        - `early_withdrawal_after_opening` EarlyWithdrawalAfterOpeningOverrideRequest: Override for early withdrawal after account opening.
          - `waived` boolean, required
          - `applicable_within_days` integer
          - `penalty_interest_days` integer
          - `valid_until` string, date-time
        - `withdrawal_fee` WithdrawalFeeOverrideRequest: Withdrawal fee override.
          - `waived` boolean, required
          - `type` 'PERCENTAGE' | 'FIXED'
          - `value` number: Same format as the product's `withdrawal_fee.value`.
          - `valid_until` string, date-time
        - `tiered_interest_forfeiture` TieredInterestForfeitureOverrideRequest: Tiered interest forfeiture override. Tiers replace the product's tiers when provided.
          - `waived` boolean, required
          - `tiers` TieredInterestForfeitureTierRequest[]
            - `min_days_held` integer, required
            - `max_days_held` integer: Optional. Open-ended tier when omitted.
            - `forfeited_interest_days` integer, required
          - `valid_until` string, date-time
        - `subsequent_withdrawals` SubsequentWithdrawalsOverrideRequest: Subsequent withdrawals (Regulation D) override.
          - `waived` boolean, required
          - `applicable_within_days` integer
          - `penalty_interest_days` integer
          - `window_behavior` 'ROLLING' | 'FIXED'
          - `valid_until` string, date-time
  - `metadata` object: The metadata object contains user-defined key-value pairs that provide additional context or custom information.<br> The platform has no control over its content, but rather controlled by the user.<br> **Note**: This field must not be used to send Personally Identifiable Information (PII), Payment Card Industry (PCI) data, or any sensitive/regulated information. Metadata fields are intended for operational, non-sensitive data only. For sensitive data, use the specific parameters designed for that purpose. For more information, refer to [Get started with Pismo APIs](ref:get-started-with-pismo-apis#metadata).

## Response `201`

Created

- DepositAttachAccountResponse: Response body returned when attaching a deposit product to an account
  - `account_id` integer: Account ID
  - `product_id` string: Product ID
  - `external_account_id` string: External account ID. Returned only when the account has an external account identifier.
  - `effective_date` string, date: The effective value date of the attachment. Format is `YYYY-MM-DD`. This is the date when the attachment becomes valid. Maturity is calculated from this date.
  - `deposit_configs` object
    - `maturity_period` MaturityPeriod: Defines when the deposit matures. There are three usage modes: * **Relative period**: Sends `unit` + `value` (e.g. `MONTHS` + `6`). * **Explicit date**: Sends `calendar_maturity_date` (e.g. `2027-06-15`). * **Default**: Omits the field or sends `{}`. The product's configured default maturity term (`PRODUCT_DEFAULT_MATURITY_DATE_DAYS`, typically `10950` days ≈ 30 years) is applied. **NOTE**: `calendar_maturity_date` and `unit`/`value` are mutually exclusive, sending both in the same request returns a `400` validation error. In the **attach** endpoints, the response returns exactly what was sent in the request: * Send `unit` + `value` returns `unit` + `value` * Send `calendar_maturity_date` returns `calendar_maturity_date` * Send nothing (default fallback applied) returns `unit=DAYS` and `value` equal to the product's configured `PRODUCT_DEFAULT_MATURITY_DATE_DAYS` **NOTE**: this behavior applies only to attach. The `GET` attachment endpoints and `PATCH /v1/deposits/accounts/{accountId}/attachment` return the resolved term, with `unit`, `value`, and `calendar_maturity_date` populated together. A `PATCH` sent in explicit‑date form is returned normalized as `{unit: DAYS, value: <days>, calendar_maturity_date: <date>}`.
      - `unit` 'DAYS' | 'WEEKS' | 'MONTHS' | 'YEARS': Time unit for the relative maturity period. It's used together with `value` and cannot coincide with `calendar_maturity_date`. - `DAYS`: Uses `value` directly. Example: `value=90` → 90 days. - `WEEKS`: Multiplies `value` by 7. Example: `value=4` → 28 days. - `MONTHS`: Calculates calendar-month with end-of-month (EOM) clamping when the target day does not exist. The maturity date falls on the same day of the month as the start date. Example: `2026-09-22` + 3 months = `2026-12-22`; `2024-01-31` + 1 month = `2024-02-29` (leap year) or `2025-02-28` (non-leap year). - `YEARS`: Calculates calendar-year, for example: `2024-02-29` + 1 year = `2025-02-28`. Note that there is no Feb 29 in 2025. For `WEEKS`, `MONTHS`, and `YEARS`, the resulting calendar date is converted back to a day count to validate against the product's configured minimum or maximum term.
      - `value` integer: Number of time units until maturity. Must be greater than `0`. Mutually exclusive with `calendar_maturity_date`.
      - `calendar_maturity_date` string, date: Maturity date. Format is `YYYY-MM-DD`. The date must be a future date. This date cannot coincide with `unit`/`value`, sending both in the same request returns a `400` validation error.
    - `interest_capitalization_mode` 'PAYOUT' | 'REINVEST': Present only when the request included `interest_capitalization_mode`. Reflects the value stored on the attachment.
    - `accrual_model` 'DEPOSIT_BASIS' | 'BALANCE_BASIS': Accrual model inherited from the attached product. `DEPOSIT_BASIS` or `BALANCE_BASIS`.
    - `balance_type` 'VALUE_DATED_BALANCE' | 'LEDGER_BALANCE': Balance type inherited from the attached product. Only meaningful when `accrual_model` is `BALANCE_BASIS`.
    - `overrides` AttachmentOverridesSnapshot: Representation of the persisted overrides, present only when the request defined at least one override. Sub-fields are included only when set. The `renewal_term` always returns all three fields together (`unit`, `value` and `renewal_calendar_maturity_date`), mirroring the behavior of `maturity_period`.
      - `maturity_instructions` MaturityInstructionsOverrideRequest: Overrides the deposit’s behavior at maturity. If a field is omitted, the Pismo platform uses the value defined at the higher‑level configuration that governs this deposit.
        - `principal` 'ROLLOVER' | 'PAY': Specifies how the principal is handled once the deposit matures.
        - `interest` 'ROLLOVER' | 'PAY': Specifies how the interest is handled once the deposit matures.
        - `reason` string: Optional audit-trail reason.
      - `renewal_term` RenewalTermResponse: Renewal term applied on each rollover. Always returns all three fields together — `unit`, `value` and `renewal_calendar_maturity_date` — regardless of the form the client used to configure it, mirroring `maturity_period`. Legacy terms persisted before the calendar date was stored return only `unit`+`value`.
        - `unit` 'DAYS' | 'WEEKS' | 'MONTHS' | 'YEARS'
        - `value` integer
        - `renewal_calendar_maturity_date` string, date: Returned only when the request uses the calendar format. Format = `YYYY-MM-DD`.
      - `penalties` PenaltiesOverrideSnapshot: Persisted penalty overrides for each type. Types appear only when set. Each entry includes `waived`, the relevant type-specific fields, and an optional `valid_until` for scheduling the revert.
        - `reason` string
        - `grace_period` GracePeriodOverrideRequest: Grace period override. Type-specific fields are optional pointers, when omitted, the Pismo platform follows the normal fallback sequence, moving from the account level to the program and then to the product defaults.
          - `waived` boolean, required: `true` = fully exempt; `false` = penalty active (customize via the fields below).
          - `duration_days` integer
          - `penalty_interest_days` integer
          - `valid_until` string, date-time: Schedules the revert of this override via EventBridge. This value must be a future date and follows the ISO 8601 standard.
        - `early_withdrawal_after_opening` EarlyWithdrawalAfterOpeningOverrideRequest: Override for early withdrawal after account opening.
          - `waived` boolean, required
          - `applicable_within_days` integer
          - `penalty_interest_days` integer
          - `valid_until` string, date-time
        - `withdrawal_fee` WithdrawalFeeOverrideRequest: Withdrawal fee override.
          - `waived` boolean, required
          - `type` 'PERCENTAGE' | 'FIXED'
          - `value` number: Same format as the product's `withdrawal_fee.value`.
          - `valid_until` string, date-time
        - `tiered_interest_forfeiture` TieredInterestForfeitureOverrideRequest: Tiered interest forfeiture override. Tiers replace the product's tiers when provided.
          - `waived` boolean, required
          - `tiers` TieredInterestForfeitureTierRequest[]
            - `min_days_held` integer, required
            - `max_days_held` integer: Optional. Open-ended tier when omitted.
            - `forfeited_interest_days` integer, required
          - `valid_until` string, date-time
        - `subsequent_withdrawals` SubsequentWithdrawalsOverrideRequest: Subsequent withdrawals (Regulation D) override.
          - `waived` boolean, required
          - `applicable_within_days` integer
          - `penalty_interest_days` integer
          - `window_behavior` 'ROLLING' | 'FIXED'
          - `valid_until` string, date-time

## Other responses

- `400`: Bad Request
- `404`: Bad request
- `409`: Conflict
- `500`: Internal Server Error

---

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