> ## Documentation Index
> Fetch the complete documentation index at: https://docs.portal.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Update Proposal Item Supplier Cost

> POST /public/proposals/{ProposalId}/items/{ProposalItemId}/cost — Sets an absolute supplier cost or a percentage-based cost on a proposal item.

Sets the per-unit supplier cost of a proposal item, as either an absolute `Cost` or a `CostPercentage` plus `CostPercentageBasis`. Exactly one of the two forms is required: supplying both, neither, or a percentage without its basis returns `400`. As with sell price, the two forms replace each other.

Percentages are whole numbers — `15` means 15%, rounded to 2 decimals. The bases match [update sell price](/api-reference/proposals/items/update-item-sell-price), plus `CostOfSellPrice`, which is valid for cost only and makes the cost a percentage of the item's own sell price.

Every basis is resolved when the proposal is read, not when you write it, so a percentage cost is never a fixed number: `ProposalTotal`, `PartTotal`, and `LaborTotal` move with the whole proposal, `AreaTotal`, `PartsInAreaTotal`, and `LaborInAreaTotal` move with the item's own area option, and `CostOfSellPrice` moves with the item's sell price. Re-read the proposal after a batch of writes rather than assuming the cost you sent is the cost stored.

<Note>
  A percentage cost is ignored while the item is marked as a recurring service.
</Note>

Writing a cost updates the item against its current supplier and refreshes `costUpdateDate`. It does not change which supplier the item uses — [set item supplier](/api-reference/proposals/items/set-item-supplier) does that. `cost` can come back `null` even on a successful write, if you do not have permission to see costs — the write still took effect.

<Note>
  A cost written here marks the item as carrying a hand-entered amount, which takes it out of every later [refresh item costs](/api-reference/proposals/items/refresh-item-costs) run on the proposal. That keeps a price you set on purpose from being reset by a catalog refresh, and there is no flag to opt back in.
</Note>

`SetDefault` also saves the cost in the catalog against the supplier the item uses, and updates the company's draft proposals and draft orders that carry the same part without a cost of their own. For a `Part` only an absolute cost is saved; a percentage-based update saves nothing and clears any cost saved there before. `Labor`, `CustomItem`, and `Fee` items keep the cost, percentage, and basis on their library item.

`UpdateAllInstances` applies the change to the proposal's other items from the same source item that share both its item type **and its assigned supplier**.

<Snippet file="hmac-signing.mdx" />


## OpenAPI

````yaml POST /public/proposals/{ProposalId}/items/{ProposalItemId}/cost
openapi: 3.1.1
info:
  title: Portal.io Public API
  version: '1.0'
servers:
  - url: https://sandbox.api.portal.io/
security:
  - mssApiAppId: []
    mssApiUserKey: []
    mssCustomDate: []
    mssSignature: []
paths:
  /public/proposals/{ProposalId}/items/{ProposalItemId}/cost:
    post:
      tags:
        - Proposals/Item
      summary: Update Proposal Item Supplier Cost
      description: >-
        Updates the per-unit supplier cost of a proposal item, as an absolute
        value or a percentage + basis. Returns the updated item, or every
        updated instance when updateAllInstances is true.
      operationId: postPublicProposalsByProposalIdItemsByProposalItemIdCost
      parameters:
        - name: ProposalId
          in: path
          required: true
          explode: true
          schema:
            type: integer
            description: Unique ID of the proposal (not the proposal number).
            format: int32
            x-default: 11538
        - name: ProposalItemId
          in: path
          required: true
          explode: true
          schema:
            type: integer
            description: Id of the proposal item to update. Must belong to the proposal.
            format: int32
            x-default: 92853
        - $ref: '#/components/parameters/Accept'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PublicProposalItemCostUpdateRequest'
            example:
              cost: 759.6
              costPercentage: 63.6
              costPercentageBasis: PartTotal
              setDefault: false
              updateAllInstances: false
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                title: ListOfPublicAreaItemModel
                type: array
                items:
                  $ref: '#/components/schemas/PublicAreaItemModel'
              example:
                - id: 81376
                  parentId: 42344
                  itemType: Part
                  referencedItemId: 63140
                  createdDate: '2030-08-21T00:22:19Z'
                  lastModifiedDate: '2031-02-06T00:22:19Z'
                  brand: Sonos
                  model: Amp
                  name: Installation Labor
                  shortDescription: Sonos Amp
                  clientNote: Mounted in the rack behind the display.
                  imageUrl: https://images.portal.io/catalog/sonos-amp.jpg
                  msrp: 901.23
                  sellPrice: 583.78
                  cost: 759.6
                  costUpdateDate: '2030-11-10T00:22:19Z'
                  supplier: Sonos Inc.
                  quantity: 9.6
                  total:
                    amount: 982.49
                    currency:
                      code: USD
                      symbol: $
                    isCombinedPrice: false
                  isTaxExempt: false
                  isRecurringService: false
                  linkedOrders:
                    - orderId: 21802
                      orderNumber: 182
                      orderNumberSuffix: A
                      supplier: Sonos Inc.
                      supplierRef: SN-10420
                      orderName: Living Room Sonos Amp
                      orderStatus: Submitted
        '400':
          description: >-
            Neither an absolute cost nor a percentage was supplied, both were
            supplied, or a percentage was supplied without its basis.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                responseStatus:
                  errorCode: BadRequest
                  message: >-
                    Neither an absolute cost nor a percentage was supplied, both
                    were supplied, or a percentage was supplied without its
                    basis.
        '401':
          description: >-
            Not Authorized. Ensure a valid session cookie or HMAC authentication
            headers are provided.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                responseStatus:
                  errorCode: Unauthorized
                  message: >-
                    Not Authorized. Ensure a valid session cookie or HMAC
                    authentication headers are provided.
        '402':
          description: >-
            The dealer's subscription is inactive or expired. An active
            subscription is required to use this endpoint.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                responseStatus:
                  errorCode: PaymentRequired
                  message: >-
                    The dealer's subscription is inactive or expired. An active
                    subscription is required to use this endpoint.
        '403':
          description: You do not have permission for this action.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                responseStatus:
                  errorCode: Forbidden
                  message: You do not have permission for this action.
        '404':
          description: Proposal or proposal item not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                responseStatus:
                  errorCode: NotFound
                  message: Proposal or proposal item not found.
        '409':
          description: Proposal is in a state that does not allow editing.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                responseStatus:
                  errorCode: Conflict
                  message: Proposal is in a state that does not allow editing.
components:
  parameters:
    Accept:
      name: Accept
      in: header
      description: Accept Header
      required: true
      schema:
        enum:
          - application/json
        type: string
  schemas:
    PublicProposalItemCostUpdateRequest:
      title: PublicProposalItemCostUpdateRequest
      type: object
      properties:
        cost:
          type: number
          description: >-
            Absolute per-unit supplier cost, mutually exclusive with
            costPercentage. Supplying it clears any stored percentage and basis.
          format: double
        costPercentage:
          type: number
          description: >-
            Cost as a whole percent of the chosen basis (15 means 15%), with the
            resulting cost rounded to 2 decimals. Requires costPercentageBasis,
            is mutually exclusive with cost, and clears any stored absolute
            cost. Ignored while the item is a recurring service.
          format: double
        costPercentageBasis:
          $ref: '#/components/schemas/PercentageBasisTypes'
        setDefault:
          type: boolean
          description: >-
            When true, also save this cost in the catalog so later proposals
            start with it. For a Part, only an absolute cost is saved, against
            the supplier the item uses: a percentage-based update saves no cost
            and clears any cost saved there before. The company's draft
            proposals and draft orders that carry that part without a cost of
            their own are updated too. For a Labor, CustomItem, or Fee item, the
            cost, percentage, and basis are saved on the library item. Defaults
            to false.
        updateAllInstances:
          type: boolean
          description: >-
            When true, apply the change to every other instance of the same
            catalog item in this proposal that shares its item type and assigned
            supplier, across all area options. Defaults to false.
      description: Proposals Service
    PublicAreaItemModel:
      title: PublicAreaItemModel
      required:
        - id
        - referencedItemId
        - createdDate
        - quantity
      type: object
      properties:
        id:
          type: integer
          description: Unique numeric identifier of the proposal item
          format: int32
        parentId:
          type: integer
          description: >-
            Identifier of the parent item when this item is nested under another
            item
          format: int32
        itemType:
          $ref: '#/components/schemas/ItemTypes'
        referencedItemId:
          type: integer
          description: >-
            Identifier of the catalog, labor, custom, or fee item this proposal
            item was created from
          format: int32
        createdDate:
          type: string
          description: UTC timestamp when the proposal item was created
          format: date-time
        lastModifiedDate:
          type: string
          description: UTC timestamp when the proposal item was last modified
          format: date-time
        brand:
          type: string
          description: Brand name of the item
        model:
          type: string
          description: Model value of the item
        name:
          type: string
          description: Name of a Labor item
        shortDescription:
          type: string
          description: Short description shown for the proposal item
        clientNote:
          type: string
          description: Client-facing note for the proposal item
        imageUrl:
          type: string
          description: Image URL of the item
        msrp:
          type: number
          description: MSRP amount of the item
          format: double
        sellPrice:
          type: number
          description: Sell price for the proposal item
          format: double
        cost:
          type: number
          description: Supplier cost for the proposal item
          format: double
        costUpdateDate:
          type: string
          description: UTC timestamp when the supplier cost was last updated
          format: date-time
        supplier:
          type: string
          description: Display name of the supplier assigned to the item.
        quantity:
          type: number
          description: Quantity of the proposal item
          format: double
        total:
          $ref: '#/components/schemas/PublicItemTotalModel'
        isTaxExempt:
          type: boolean
          description: Whether the proposal item is tax exempt
        isRecurringService:
          type: boolean
          description: Whether the proposal item is a recurring service
        linkedOrders:
          type: array
          items:
            $ref: '#/components/schemas/PublicLinkedOrderModel'
          description: Linked orders created from this proposal item
      description: Proposal area item
    ErrorResponse:
      title: ErrorResponse
      type: object
      properties:
        responseStatus:
          $ref: '#/components/schemas/ResponseStatus'
      description: ErrorResponse
    PercentageBasisTypes:
      enum:
        - ProposalTotal
        - PartTotal
        - LaborTotal
        - AreaTotal
        - PartsInAreaTotal
        - LaborInAreaTotal
        - CostOfSellPrice
      type: string
    ItemTypes:
      enum:
        - Part
        - Labor
        - CustomItem
        - Fee
      type: string
    PublicItemTotalModel:
      title: PublicItemTotalModel
      required:
        - amount
      type: object
      properties:
        amount:
          type: number
          description: Per-unit sell price multiplied by quantity, before tax
          format: double
        currency:
          $ref: '#/components/schemas/PublicCurrencyModel'
        isCombinedPrice:
          type: boolean
          description: >-
            Whether the totals of nested items are included in this item's
            amount
      description: Total amount for a proposal item
    PublicLinkedOrderModel:
      title: PublicLinkedOrderModel
      required:
        - orderId
        - orderNumber
        - orderNumberSuffix
        - orderName
      type: object
      properties:
        orderId:
          type: integer
          description: Unique numeric identifier of the order
          format: int32
        orderNumber:
          type: integer
          description: Order number shown to the dealer
          format: int32
        orderNumberSuffix:
          type: string
          description: Order number suffix used for supplier-specific numbering
        supplier:
          type: string
          description: Supplier display name
        supplierRef:
          type: string
          description: Supplier reference or supplier order number
        orderName:
          type: string
          description: Display name of the order
        orderStatus:
          $ref: '#/components/schemas/OrderStatuses'
      description: Order summary linked to a proposal item
    ResponseStatus:
      title: ResponseStatus
      type: object
      properties:
        errorCode:
          type:
            - 'null'
            - string
        message:
          type:
            - 'null'
            - string
        stackTrace:
          type:
            - 'null'
            - string
        errors:
          type:
            - 'null'
            - array
          items:
            $ref: '#/components/schemas/ResponseError'
        meta:
          title: DictionaryOfStringAndString
          type:
            - 'null'
            - object
          additionalProperties:
            type:
              - 'null'
              - string
      description: ResponseStatus
    PublicCurrencyModel:
      title: PublicCurrencyModel
      required:
        - code
        - symbol
      type: object
      properties:
        code:
          type: string
          description: ISO 4217 code that identifies the currency used for the amount.
        symbol:
          type: string
          description: Symbol displayed alongside monetary values in this currency.
      description: Currency code and symbol used to display money values.
    OrderStatuses:
      enum:
        - Draft
        - Submitted
        - ViewedBySupplier
        - Accepted
        - Received
        - EmailFailed
        - Undefined
      type: string
    ResponseError:
      title: ResponseError
      type: object
      properties:
        errorCode:
          type:
            - 'null'
            - string
        fieldName:
          type:
            - 'null'
            - string
        message:
          type:
            - 'null'
            - string
        meta:
          title: DictionaryOfStringAndString
          type:
            - 'null'
            - object
          additionalProperties:
            type:
              - 'null'
              - string
      description: ResponseError
  securitySchemes:
    mssApiAppId:
      type: apiKey
      description: >-
        Portal application identifier used as part of HMAC-authenticated API
        requests.
      name: X-MSS-API-APPID
      in: header
    mssApiUserKey:
      type: apiKey
      description: Portal user API key used together with the HMAC signature headers.
      name: X-MSS-API-USERKEY
      in: header
    mssCustomDate:
      type: apiKey
      description: >-
        Timestamp header included in the signed request to prevent replay
        attacks.
      name: X-MSS-CUSTOM-DATE
      in: header
    mssSignature:
      type: apiKey
      description: >-
        HMAC-SHA256 signature for the request, calculated over the canonical
        string defined in the authentication docs.
      name: X-MSS-SIGNATURE
      in: header

````