---
title: "NSO exercise → ordinary income, withholding gap, sell-to-cover"
method: POST
path: "/v1/equity-comp/nso"
tags: ["Equity compensation"]
---

# NSO exercise → ordinary income, withholding gap, sell-to-cover

`POST /v1/equity-comp/nso`

## Request

- Base URL: `https://api.numeratica.com`
- URL: `https://api.numeratica.com/v1/equity-comp/nso`
- Auth: one of:
  - HTTP bearer
  - API key in header `X-API-Key`

The spread on a non-qualified stock-option exercise ((fmv − strike) × shares) is ordinary compensation income at exercise (regular tax, not AMT). Returns the income, the flat supplemental withholding (22% to $1M, 37% above), the true marginal tax (via the tax engine), the under/over-withholding gap, the sell-to-cover share count, and the per-share basis (= fmv at exercise). Deterministic; not tax advice.

## Request body

- EquityCompNSORequest
  - `tax_year` integer, required: Supported tax year (2025 or 2026).
  - `filing_status` 'single' | 'mfj' | 'mfs' | 'hoh', required
  - `other_ordinary_income` number: Wages/other income, to find the marginal rate.
  - `shares` number, required
  - `strike_price` number, required
  - `fmv_at_exercise` number, required

## Response `200`

NSO exercise breakdown

- EquityCompNSOResponse
  - `result_id` string
  - `engine_version` string
  - `inputs` EquityCompNSORequest
    - `tax_year` integer, required: Supported tax year (2025 or 2026).
    - `filing_status` 'single' | 'mfj' | 'mfs' | 'hoh', required
    - `other_ordinary_income` number: Wages/other income, to find the marginal rate.
    - `shares` number, required
    - `strike_price` number, required
    - `fmv_at_exercise` number, required
  - `result` object
    - `ordinary_income` number: (fmv − strike) × shares.
    - `supplemental_withholding` number: Flat 22% (37% above $1M).
    - `marginal_rate` number: True marginal rate on the spread.
    - `estimated_tax` number: Incremental federal tax from the spread income.
    - `withholding_gap` number: estimated_tax − supplemental_withholding.
    - `shares_sold_to_cover` number
    - `net_shares` number
    - `per_share_basis` number: = fmv at exercise.
  - `disclaimer` string

## Other responses

- `400`: Invalid request
- `401`: Missing or invalid API key.
- `405`: Method not allowed
- `429`: The key's per-minute request budget is exceeded. Retry after the delay in the Retry-After header.
- `503`: A dependency (e.g. the key store) is temporarily unavailable, or the request exceeded its compute deadline. Retryable.

---

[API](https://skmtc.dev/numeratica/apis/numeratica-financial-planning-calculations-api.md) · [All operations](https://skmtc.dev/numeratica/apis/numeratica-financial-planning-calculations-api/llms.txt) · [OpenAPI document](https://skmtc.dev/numeratica/apis/numeratica-financial-planning-calculations-api/revisions/075bcfbd1ebf?raw)
