---
title: "Create Term Sheet"
method: POST
path: "/api/external/v2/deals/{deal_id}/term-sheets"
tags: ["external-v2-term-sheets"]
---

# Create Term Sheet

`POST /api/external/v2/deals/{deal_id}/term-sheets`

Create a new term sheet against a placement on this deal.

Required body fields: ``placement_id``, ``total_rate``, ``initial_funding``,
``quote_type``, ``rate_type`` (mirrors the GraphQL ``CreateTermSheetMutation``
requirements).  The deal_id in the path must match the placement's deal.

## Path parameters

- `deal_id` integer, required

## Request body

- CreateTermSheetRequest — POST /api/external/v2/deals/<deal_id>/term-sheets request body. ``placement_id``, ``total_rate``, ``initial_funding``, ``quote_type``, and ``rate_type`` are required — they mirror the constraints from the GraphQL ``TermSheetInputWithRequirements``. All other fields are optional. The target deal_id is implied by the URL path and need not appear in the body.
  - `placement_id` integer, required — ID of the placement (lender outreach) this term sheet belongs to. The placement must already exist on this deal.
  - `total_rate` number, required — Rate as a percent (e.g. 7.53 = 7.53%). Interpret relative to the term sheet's ``base_rate``: if ``base_rate`` is set, ``total_rate`` is the spread over that base rate; if ``base_rate`` is null or ``'none-fixed'``, ``total_rate`` is the all-in fixed rate.
  - `initial_funding` integer, required — Provided loan amount.
  - `quote_type` 'Guidance' | 'Indication' | 'Soft Quote' | 'Hard Quote' | 'Term Sheet', required
  - `rate_type` 'Fixed' | 'Floating', required
  - `title` string, nullable — Free-text title of the term sheet.
  - `winning` boolean, nullable — Set true to mark this as the winning term sheet on the deal.
  - `base_rate` string, nullable — Base rate identifier — accepts ``BaseRateNames`` member names (e.g. ``treasury_y5``, ``sofr_m1``, ``prime_rate``) or the literal string ``'none-fixed'`` for fixed-rate quotes. When this is a real base-rate identifier, send ``total_rate`` as the spread over that base rate. Unknown names return 422 with the full list of valid options. See ``app/models/enums.py::BaseRateNames`` for the full enum.
  - `max_ltv` number, nullable — Maximum loan-to-value ratio as a percent.
  - `max_ltc` number, nullable — Maximum loan-to-cost ratio as a percent.
  - `additional_funding` integer, nullable — Additional funding amount.
  - `floor` number, nullable — Rate floor as a percent.
  - `floor_type` 'base_rate' | 'total_rate'
  - `term` integer, nullable — Term length in months.
  - `amortization` integer, nullable — Amortization period in months.
  - `io_period` integer, nullable — Interest-only period in months.
  - `extension_one` integer, nullable — First extension period in months.
  - `extension_two` integer, nullable — Second extension period in months.
  - `extension_three` integer, nullable — Third extension period in months.
  - `recourse` 'Personal Recourse' | 'Fund / Corporate Recourse' | 'Non-Recourse'
  - `recourse_type` 'Full' | 'Partial' | 'Burn Off'
  - `prepayment_penalty` 'Step-down' | 'Defeasance' | 'Minimum Interest' | 'Yield Maintenance' | 'Minimum Multiple' | 'Swap Breakage' | 'No Prepayment Penalty' | 'No Ability to Prepay' | 'Flat Fee' | 'Other'
  - `prepayment_penalty_details` string, nullable — Free-text details of the prepayment penalty structure.
  - `min_dscr` number, nullable — Minimum debt service coverage ratio as a percent.
  - `min_debt_yield` number, nullable — Minimum debt yield as a percent.
  - `origination_fee` number, nullable — Origination fee as a percent.
  - `extension_fee` number, nullable — Extension fee as a percent.
  - `exit_fee` number, nullable — Exit fee as a percent.
  - `good_faith_deposit` number, nullable — Good-faith deposit amount.
  - `notes` string, nullable — Free-text notes on the term sheet.
  - `ir_details` string, nullable — Free-text interest rate details.
  - `is_visible_to_borrower` boolean, nullable — Whether the term sheet is visible to the borrower (default true on the model).
  - `payment_method` 'Accrued' | 'Partial' | 'Current Pay'
  - `capital_source_type` 'Balance Sheet' | 'Agency' | 'CMBS/CLO' | 'Warehouse' | 'SBA'

## Response `201`

Successful Response

- TermSheetObjectResponse — OpenAPI schema for GET /api/external/v2/deals/<deal_id>/term-sheets/<term_sheet_id> (object envelope).
  - `request_id` string, required
  - `timestamp` string, required
  - `data` TermSheetDetailResponse, required — Term sheet detail fields — extends summary with additional financial/structural fields.
    - `id` integer, required
    - `deal_id` integer, nullable, required
    - `title` string, nullable, required
    - `quote_type` string, nullable, required
    - `initial_funding` integer, nullable, required
    - `total_rate` number, nullable, required — Rate as a percent (e.g. 7.53 = 7.53%). Interpret relative to the term sheet's ``base_rate``: if ``base_rate`` is set, ``total_rate`` is the spread over that base rate; if ``base_rate`` is null or ``'none-fixed'``, ``total_rate`` is the all-in fixed rate.
    - `base_rate` string, nullable, required
    - `base_rate_value` number, nullable — Base-rate snapshot as a percent. For base-rate quotes, the displayed all-in rate is ``base_rate_value + total_rate`` when both values are known.
    - `effective_spread` number, nullable — Effective spread as a percent for underwriting and comparison. For base-rate quotes, this normally equals ``total_rate``.
    - `rate_type` string, nullable, required
    - `term` integer, nullable, required
    - `io_period` integer, nullable, required
    - `recourse` string, nullable, required
    - `max_ltv` number, nullable, required
    - `max_ltc` number, nullable, required
    - `origination_fee` number, nullable, required
    - `exit_fee` number, nullable, required
    - `notes` string, nullable
    - `lender_name` string, nullable — Lender display name for this term sheet. For non-owner viewers of masked placements, this is a stable masked label such as 'Lender A'.
    - `org_id` integer, nullable, required — Canonical lender Organization ID. Null for non-owner viewers of masked placements.
    - `placement_id` integer, nullable, required
    - `winning` boolean, nullable, required
    - `is_visible_to_borrower` boolean, required
    - `created_at` string, nullable
    - `updated_at` string, nullable
    - `floor` number, nullable
    - `floor_type` string, nullable
    - `amortization` integer, nullable
    - `extension_one` integer, nullable
    - `extension_two` integer, nullable
    - `extension_three` integer, nullable
    - `prepayment_penalty` string, nullable
    - `prepayment_penalty_details` string, nullable
    - `recourse_type` string, nullable
    - `min_dscr` number, nullable
    - `min_debt_yield` number, nullable
    - `good_faith_deposit` number, nullable
    - `ir_details` string, nullable
    - `capital_source_type` string, nullable
    - `payment_method` string, nullable

## Other responses

- `422` — Validation Error

---

[API](https://skmtc.net/lev/apis/lev-api.md) · [All operations](https://skmtc.net/lev/apis/lev-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/lev/lev-api/versions/5bfe74cf6f12/schema)
