---
title: "Apply discount"
method: POST
path: "/assistedSales/v2/opportunities/{opportunityId}/applyDiscount"
tags: ["AppResellerOpportunities"]
---

# Apply discount

`POST /assistedSales/v2/opportunities/{opportunityId}/applyDiscount`

## Request

- Base URL: `https://marketplace.appdirect.com/api`
- URL: `https://marketplace.appdirect.com/api/assistedSales/v2/opportunities/{opportunityId}/applyDiscount`
- Auth: none declared
- TypeScript: <https://skmtc.dev/appdirect/apis/companies/docs/assistedSales/v2/opportunities/:opportunityId/applyDiscount/post.ts> (a function with typed inputs; its response is checked against the schema)

Apply a discount to an opportunity. More than one discount (one per call) can be applied to an opportunity. The response is an updated opportunity summary.
The discount is applied to all eligible products. However, redemption limits apply. When the redemption limits exceed the contents of the opportunity, the discount is not applied.

Required: Accept-Language header with Locale format. For example: en-US

## Path parameters

- `opportunityId` string, required

## Request body

- DiscountRequest: Details about the discount to be applied to the product
  - `discountCode` string: The discount code can be a combination of letters, numbers, and special characters
  - `itemIds` string[]: The opportunity's item IDs to which the discount is applied or removed

## Response `200`

The discount was applied and the request returned an updated opportunity summary

- OpportunitySummary: Opportunity taxes, subtotals, totals and recurring totals
  - `amountDueBeforeTax` string: Amount due before taxes
  - `taxSummary` TaxDetail[]: Details of a specific type of tax applied to a charged cost
    - `description` string: Description of the tax
    - `taxAmount` string: The tax amount
  - `amountDueAfterTax` string: Amount due after taxes
  - `items` OpportunityItemDetail[]: List of item details
    - `id` string: Item ID
    - `product` object: Product information
      - `id` string: Product ID
      - `name` string: Product name
      - `type` string: Product type
      - `logo` string: Product logo URL
    - `pricingPlan` object: Pricing plan information
      - `id` string: Pricing plan ID
      - `name` string: Pricing plan name
    - `units` Unit[]: List of units (quantity and type) associated with the item
      - `quantity` number: Quantity
      - `unit` string: Unit
    - `pricing` OpportunityPricing[]: Cost of each quantifiable unit and flat rates
      - `costId` string: The cost ID
      - `costTypeCategory` 'RECURRING' | 'ONE_TIME', required: Category of cost
      - `costType` 'RECURRING_FLAT' | 'ONE_TIME_FLAT' | 'INCLUDED' | 'SETUP_PER_UNIT' | 'RECURRING_PER_UNIT' | 'ONE_TIME_PER_UNIT' | 'SETUP_FEE' | 'CONTRACT_FEE' | 'DISCOUNT_PER_UNIT' | 'DISCOUNT_FLAT' | 'METERED_USAGE', required: Type of cost
      - `frequency` 'ONE_TIME' | 'DAILY' | 'MONTHLY' | 'QUARTERLY' | 'SIX_MONTHS' | 'YEARLY' | 'TWO_YEARS' | 'THREE_YEARS': The pricing period. The billing frequency for the pricing plan.
      - `pricingStrategy` 'FREE' | 'FLAT' | 'UNIT' | 'VOLUME' | 'TIERED' | 'UNLIMITED' | 'CUSTOM', required: Pricing strategy
      - `priceRanges` PriceRangeItem[]: Range of units for which the price is valid
        - `min` string: Minimum number of units for the price range
        - `max` string: Maximum number of units for the price range
      - `description` string: Description of each pricing line
      - `unit` string: Unit
      - `quantity` string: Quantity
      - `salePrice` string, required: Sale price
      - `wholesalePrice` string, required: Wholesale price
      - `totalSalePrice` string, required: Total sale price
    - `contractConfiguration` object: Contract configuration
      - `minimumServiceLength` integer: Contract length. The number of minimumServiceLengthUnits that defines contract duration.
      - `minimumServiceLengthUnit` 'DAILY' | 'MONTHLY' | 'QUARTERLY' | 'SIX_MONTHS' | 'YEARLY' | 'TWO_YEARS' | 'THREE_YEARS': Time unit for contract length. This property must have the same value as the contract length unit configured for the pricing plan.
      - `renewalConfiguration` 'MONTH_TO_MONTH' | 'AUTO_RENEW' | 'CANCEL_SUBSCRIPTION': Contract renewal configuration. Whether the contract is renewed and, if so, with what terms.
      - `terminationFee` TerminationFeeAS: Termination fee
        - `feeType` 'NONE' | 'PERCENTAGE' | 'FIXED': Contract termination fee type
        - `amount` number
        - `description` string
      - `terminationFeeGracePeriod` integer: Termination fee grace period duration. Number of terminationFeeGracePeriodUnits that define the risk-free period after the contract starts, during which no termination fee is charged if the customer cancels the contract.
      - `terminationFeeGracePeriodUnit` 'NONE' | 'DAY' | 'MONTH': Termination fee grace period unit. Time unit by which the terminationFeeGracePeriod is measured.
      - `endOfContractGracePeriod` integer: End of contract grace period duration. Number of endofContractGracePeriodUnits that define the period after the contract ends, during which customers can resubscribe before their account and data might be deleted.
      - `endOfContractGracePeriodUnit` 'NONE' | 'INFINITY' | 'DAY' | 'MONTH': End-of-contract grace period unit. Time unit by which the endOfContractGracePeriod is measured.
      - `contractCancellationPeriodLimit` integer: Contract cancellation period limit duration. Number of contractCancellationPeriodUnits that define the period before the contract ends, during which customers can no longer cancel the contract and it is renewed.
      - `contractCancellationPeriodUnit` 'NONE' | 'DAY': Cancellation period unit. Time unit by which the contractCancellationPeriodLimit is measured.
      - `unitTerms` object: Maps a unit type (for example, user) to UnitContractTerms (see object definition). Enabled terms restrict mid-contract quantity changes for the unit type on subscriptions. See example.
        - `default` string
      - `blockContractUpgrades` boolean: Whether subscriptions can be upgraded mid-contract term
      - `blockContractDowngrades` boolean: Whether subscriptions can be downgraded mid-contract term
      - `blockSwitchToShorterContract` boolean: Whether subscriptions can be changed to plans with shorter or no contracts.
      - `keepContractDateOnPlanChange` boolean: Whether the remaining contract duration changes when a user changes a subscription pricing plan
      - `isDefault` boolean: Whether it is a default or custom contract
    - `provisioningConfiguration` object: Custom service activation dates
      - `date` number: Custom service activation date in UNIX Epoch milliseconds. This date is required when the provisioning strategy is CUSTOM. Do not set the date when the strategy is IMMEDIATELY.
      - `strategy` 'CUSTOM' | 'IMMEDIATELY'
    - `billingConfiguration` object: Custom billing dates
      - `date` number: Custom billing activation date in UNIX Epoch milliseconds. This date is required when the billing strategy is CUSTOM. Do not set the date when the strategy is UPON_SERVICE_ACTIVATION or NEXT_BILLING_CYCLE.
      - `strategy` 'CUSTOM' | 'NEXT_BILLING_CYCLE' | 'UPON_SERVICE_ACTIVATION'
    - `subscriptionCustomAttributes` object: Custom attributes related to the subscription
    - `vendorRequiredFields` object: Custom attributes related to vendor required fields for the subscription
  - `recurringTotals` TotalRecurring[]: Recurring charge totals
    - `totalSalePrice` string: The total sale price
    - `totalWholeSalePrice` string: The total wholesale price
    - `nextInvoiceDate` string: Date for the next invoice
    - `billingCycle` BillingCycle: The billing cycle
      - `period` 'ONE_TIME' | 'DAILY' | 'MONTHLY' | 'QUARTERLY' | 'SIX_MONTHS' | 'YEARLY' | 'TWO_YEARS' | 'THREE_YEARS': The pricing period. The billing frequency for the pricing plan.
      - `dayOfMonth` integer: Day of the month on which invoicing should be triggered

## Other responses

- `400`: Either the discount code is invalid or one of the required parameters is missing or invalid
- `401`: Unauthorized
- `403`: The user does not have access to the opportunity or have the permission to execute the action, or the opportunity status does not allow the action
- `404`: Invalid opportunity ID
- `409`: The discount could not be applied because the redemption limits have exceeded
- `410`: The discount has expired

## Changes

- **2026-11-06** `1fc240f06971`: 8 breaking, 31 info
  - the request's body type changed from no type to `object`
  - the response's body type changed from no type to `object` for status `200`
  - the response's body type changed from no type to `object` for status `400`
  - the response's body type changed from no type to `object` for status `401`
  - …35 more

[Operation history](https://skmtc.dev/appdirect/apis/companies/changes/assistedSales/v2/opportunities/:opportunityId/applyDiscount/post.md)

---

[API](https://skmtc.dev/appdirect/apis/companies.md) - [All operations](https://skmtc.dev/appdirect/apis/companies/llms.txt) - [OpenAPI document](https://skmtc.dev/appdirect/apis/companies/revisions/1fc240f06971?raw)
