---
title: "ESPP sale → qualifying vs disqualifying income split (§423)"
method: POST
path: "/v1/equity-comp/espp"
tags: ["Equity compensation"]
---

# ESPP sale → qualifying vs disqualifying income split (§423)

`POST /v1/equity-comp/espp`

## Request

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

Splits the gain on a §423 employee-stock-purchase-plan lot into ordinary income and capital gain under both a qualifying and a disqualifying disposition. The purchase price reflects the lookback discount (the discount off the lower of the offering- and purchase-date prices). Qualifying ordinary income is the lesser of the actual gain and the discount on the offering-date price; disqualifying ordinary income is the bargain at purchase. The tax of the split is the caller's (run /v1/tax/estimate with the components); the disqualifying capital gain's short/long character depends on the holding period from purchase. Not tax advice.

## Request body

- EquityCompESPPRequest
  - `shares` number, required
  - `offering_date_price` number, required: FMV at the offering/grant date.
  - `purchase_date_price` number, required: FMV at the purchase date.
  - `sale_price` number, required
  - `discount_pct` number, required: Plan discount (e.g. 0.15 for 15%); applied to the lower of the two prices (lookback).

## Response `200`

ESPP income split

- EquityCompESPPResponse
  - `result_id` string
  - `engine_version` string
  - `inputs` EquityCompESPPRequest
    - `shares` number, required
    - `offering_date_price` number, required: FMV at the offering/grant date.
    - `purchase_date_price` number, required: FMV at the purchase date.
    - `sale_price` number, required
    - `discount_pct` number, required: Plan discount (e.g. 0.15 for 15%); applied to the lower of the two prices (lookback).
  - `result` object
    - `purchase_price` number: Price paid per share after the lookback discount.
    - `qualifying` object
      - `ordinary_income` number: Lesser of the gain and the offering-date discount.
      - `capital_gain` number: Remainder (long-term).
    - `disqualifying` object
      - `ordinary_income` number: Bargain at purchase (FMV − price paid).
      - `capital_gain` number: Sale − purchase-date FMV (short/long per holding period).
  - `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)
