---
title: "Send a bid to the customer"
method: POST
path: "/bids/{id}/send"
tags: ["Bids"]
---

# Send a bid to the customer

`POST /bids/{id}/send`

## Request

- Base URL: `https://app.buildworkpro.com/api/v1`
- URL: `https://app.buildworkpro.com/api/v1/bids/{id}/send`
- Auth: HTTP bearer

Emails a draft bid to the customer with the PDF attached, then marks it sent. `to` and `cc` are optional; when `to` is omitted the bid's contact email is used. If there is no recipient, the bid is left unchanged. A `validUntil` already in the past is moved to today plus the organization's default bid validity, so the bid is not re-expired the night it is sent. Set `requestSignature` to true to include a signing link in that same email. That also requires the `signatures:send` scope, a signer name, and e-signature to be enabled for the organization. The signer email defaults to the bid contact, then the first To address. The response includes `signatureRequested` and, when a request was created, `signatureRequestId`. It never includes a signing URL or recipient token. A soft-deleted bid is not found.

## Path parameters

- `id` integer, required

## Headers

- `Idempotency-Key` string, uuid

## Request body

- SendBidBody
  - `to` union
    - string, email
    - string[]
  - `cc` string[]
  - `templateId` integer
  - `subject` string
  - `body` string
  - `customMessage` string
  - `requestSignature` boolean: When true, this send also starts an e-signature and the email includes the signing link. Defaults to false. Also requires the signatures:send scope and a signer name.
  - `signerEmail` string, email: Signer email. Defaults to the bid contact's email, then the first To address. Must be one of the recipients.
  - `signerName` string: Signer name. Required when requestSignature is true.

## Response `200`

Sent

- object
  - `data` SentBid, required
    - `id` integer, required
    - `bidNumber` string, required
    - `contactId` integer, nullable, required
    - `leadId` integer, nullable, required
    - `projectId` integer, nullable, required
    - `status` string, required
    - `subtotal` string, nullable, required
    - `taxAmount` string, nullable, required
    - `total` string, nullable, required
    - `lineItems` BidLineItem[]: Present on GET /bids/{id}. unitPrice and total are pre-markup cost; customerUnitPrice and customerTotal are the customer-facing prices. Omitted from list responses.
      - `id` integer, required
      - `bidId` integer, required
      - `kind` 'item' | 'section' | 'note', required: item = priced line; section = header grouping the rows after it; note = customer-visible text.
      - `isOptional` boolean, required: An optional (alternate) priced line, quoted outside the bid total.
      - `markName` string, nullable, required: Human-friendly mark name, e.g. W-01. Null on section and note rows.
      - `description` string, nullable, required
      - `quantity` string, nullable, required: Quantity. Sections and notes are not priced.
      - `unitPrice` string, nullable, required: Pre-markup direct cost per unit (before margin, overhead, commission, and distributed project costs). Not the customer price — use customerUnitPrice.
      - `total` string, nullable, required: Pre-markup line cost. Summing these does not equal the bid subtotal. Use customerTotal.
      - `customerUnitPrice` string, nullable, required: Customer-facing unit price after markup and this line's share of distributed costs. Null on section and note rows. An optional line is priced on its own and is excluded from the bid subtotal.
      - `customerTotal` string, nullable, required: Customer-facing line total in dollars, reconciled to the cent. Null on section and note rows. The sum over priced, non-optional lines equals the bid's pre-discount subtotal.
      - `sellTaxPercent` string, nullable, required: Per-line sales-tax rate (0–100). Null inherits the bid's tax rate; 0 exempts the line.
      - `buyTaxPercent` string, nullable, required: Per-line purchase-tax rate (0–100) on a flat line's cost. Null inherits the product's rate.
      - `order` integer, nullable, required: Sort position within the bid. A section covers every following row until the next section.
    - `discountAmount` string, nullable
    - `taxRate` string, nullable, required
    - `discount` string, nullable, required
    - `discountType` string, nullable, required
    - `validUntil` union, required
      - string, date-time
      - string
    - `notes` string, nullable, required
    - `terms` string, nullable, required
    - `siteAddress` string, nullable, required
    - `siteCity` string, nullable
    - `siteState` string, nullable
    - `siteZipCode` string, nullable
    - `sentAt` union, required
      - string, date-time
      - string
    - `acceptedAt` union, required
      - string, date-time
      - string
    - `acceptedBy` string, nullable, required
    - `createdAt` union, required
      - string, date-time
      - string
    - `updatedAt` union, required
      - string, date-time
      - string
    - `isPractice` boolean: Read-only. Present on GET /bids/{id}. True for the onboarding practice bid a user sends to themselves; it becomes a normal bid (false) once it is sent to anyone outside the organization.
    - `proposalDetail` 'total' | 'line_items' | 'full', required: What the customer sees: total (a scope paragraph and the totals, no line table), line_items (the line table, no sub-lines) or full (the line table with each line's sub-lines).
    - `proposalShowQuantities` boolean, required: Whether the proposal prints the Qty column.
    - `proposalShowUnitPrices` boolean, required: Whether the proposal prints the Unit price column.
    - `showSublines` boolean, nullable: Deprecated: equals proposalDetail = full. Read proposalDetail instead; writing it alone maps to full or line_items.
    - `signatureRequested` boolean, required: True when this send created an e-signature request.
    - `signatureRequestId` integer: Id of the signature request created by this send. Absent when signatureRequested is false. Never a signing URL or recipient token.
  - `meta` ResponseMeta, required
    - `request_id` string: Server-generated request identifier
    - `pagination` PaginationMeta
      - `cursor` string, nullable, required: Opaque cursor for the next page; null when no more results
      - `has_more` boolean, required: Whether more pages are available after this one
      - `count` integer, required: Items in this page

## Other responses

- `400`: Error
- `403`: Error
- `404`: Error
- `409`: Error
- `422`: Error
- `503`: Error

---

[API](https://skmtc.dev/buildworkpro/apis/buildworkpro-api.md) · [All operations](https://skmtc.dev/buildworkpro/apis/buildworkpro-api/llms.txt) · [OpenAPI document](https://skmtc.dev/buildworkpro/apis/buildworkpro-api/revisions/441cf40012f7?raw)
