Skip to main content

Bids

Overview

Bids are the top-level entity representing a complete construction estimate. Each bid contains scopes, which in turn contain estimation items across six modules.

Base Operations

List Bids

GET /api/bids
Cookie: sAccessToken=...; sRefreshToken=...

Roles: ADMIN, ESTIMATOR, PM


Get Pipeline Bids

GET /api/bids/pipeline
Cookie: sAccessToken=...; sRefreshToken=...

Roles: ADMIN, ESTIMATOR, PM

Returns bids grouped by status for pipeline/kanban views. Useful for dashboard displays showing bid progression through lifecycle stages.


Get Bid

GET /api/bids/:id
Cookie: sAccessToken=...; sRefreshToken=...

Roles: ADMIN, ESTIMATOR, PM


Create Bid

POST /api/bids
Cookie: sAccessToken=...; sRefreshToken=...
Content-Type: application/json

{
"bidNumber": "BID-2025-002",
"name": "Office Building Foundation",
"clientId": "uuid",
"location": "Houston, TX",
"overheadPercentage": 12.0,
"profitPercentage": 18.0,
"taxExempt": false,
"perDiemEnabled": true,
"equipmentBiddingMode": "GANTT"
}

Roles: ADMIN, ESTIMATOR

Required Fields:

  • bidNumber (string, unique) - User-defined identifier
  • name (string) - Job/project name
  • clientId (string, UUID) - Client reference

Optional Fields:

  • location (string) - Job location
  • overheadPercentage (number, default: global variable)
  • profitPercentage (number, default: global variable)
  • taxExempt (boolean, default: false)
  • perDiemEnabled (boolean, default: false)
  • status (enum: DRAFT, SUBMITTED, NEGOTIATION, AWARDED, LOST, COMPLETED)
  • equipmentBiddingMode (string: "TRADITIONAL" or "GANTT", default: "TRADITIONAL")

Update Bid

PUT /api/bids/:id
Cookie: sAccessToken=...; sRefreshToken=...
Content-Type: application/json

{
"name": "Updated Job Name",
"status": "SUBMITTED",
"overheadPercentage": 15.0
}

Roles: ADMIN, ESTIMATOR


Delete Bid

DELETE /api/bids/:id
Cookie: sAccessToken=...; sRefreshToken=...

Roles: ADMIN

warning

Only bids with status DRAFT can be deleted. Delete will cascade to all scopes and items.


Duplicate Bid

POST /api/bids/:id/duplicate
Cookie: sAccessToken=...; sRefreshToken=...
Content-Type: application/json

{
"bidNumber": "BID-2025-003",
"name": "Copy of Shopping Center Foundation"
}

Roles: ADMIN, ESTIMATOR

Features:

  • Deep copy of all scopes and items
  • Resets status to DRAFT
  • Creates new unique IDs
  • Preserves cost structure
  • Preserves all concrete item fields including second-mat rebar configuration (BM-86)
  • Gantt Mode: Copies equipment and labor distributions with remapped scope IDs (Feb 2026)
  • Timeline Costs: Preserves all timeline-based cost allocations for Gantt bidding mode

Bid Sharing

Generate Share Code

POST /api/bids/:id/share
Cookie: sAccessToken=...; sRefreshToken=...

Roles: ADMIN, ESTIMATOR (owner only)

Share codes are 8-character alphanumeric codes that allow other users to import your bid.


Revoke Share Code

DELETE /api/bids/:id/share
Cookie: sAccessToken=...; sRefreshToken=...

Roles: ADMIN, ESTIMATOR (owner only)


Preview Shared Bid

GET /api/bids/share/:code
Cookie: sAccessToken=...; sRefreshToken=...

Roles: ADMIN, ESTIMATOR, PM

info

Preview returns non-sensitive metadata only (no pricing, no scope details).


Import Bid

POST /api/bids/import/:code
Cookie: sAccessToken=...; sRefreshToken=...
Content-Type: application/json

{
"clientId": "uuid",
"newName": "My Copy of Shopping Center"
}

Roles: ADMIN, ESTIMATOR

Features:

  • Creates full deep copy
  • Tracks source with sourceBidId and sourceUserId
  • Status starts as DRAFT
  • New bid requires unique bidNumber
  • Gantt Mode: Copies equipment and labor distributions with remapped scope IDs (Feb 2026)
  • Timeline Costs: Preserves all timeline-based cost allocations for Gantt bidding mode

Exports

PDF Export

GET /api/bids/:id/pdf
Cookie: sAccessToken=...; sRefreshToken=...

Roles: ADMIN, ESTIMATOR, PM


CSV Export

GET /api/bids/:id/csv
Cookie: sAccessToken=...; sRefreshToken=...

Roles: ADMIN, ESTIMATOR, PM


Excel Export

GET /api/bids/:id/excel
Cookie: sAccessToken=...; sRefreshToken=...

Roles: ADMIN, ESTIMATOR, PM


PM Export

POST /api/bids/:id/export/pm
Cookie: sAccessToken=...; sRefreshToken=...
Content-Type: application/json

{
"format": "google_sheets"
}

Roles: ADMIN, ESTIMATOR, PM

Formats:

  • google_sheets - Creates Google Sheet with tracking template
  • excel - Downloads Excel file

Template Sections:

  • GENERAL CONDITIONS → Miscellaneous items
  • LABOR → Labor items
  • CONCRETE MATERIAL → Material items (concrete)
  • PUMPING → Subcontractor items (pumps)
  • REINFORCING MATERIALS → Material items (rebar)
  • MATERIALS → Other material items
  • EQUIPMENT → Equipment items
  • FUEL & HAULING → Aggregated fuel/delivery costs
  • SUBCONTRACTORS → Non-pump subcontractor items

PDF Preview

POST /api/bids/:id/pdf/preview
Cookie: sAccessToken=...; sRefreshToken=...

Roles: ADMIN, ESTIMATOR, PM

Returns base64-encoded PDF for in-browser preview.

Bid Attachments

List Attachments

GET /api/bids/:bidId/attachments
Cookie: sAccessToken=...; sRefreshToken=...

Roles: ADMIN, ESTIMATOR, PM

info

URLs are signed with 24-hour expiration. They are regenerated on each request.


Upload Attachment

POST /api/bids/:bidId/attachments
Cookie: sAccessToken=...; sRefreshToken=...
Content-Type: multipart/form-data

{
"file": [binary]
}

Roles: ADMIN, ESTIMATOR

Requirements:

  • Max file size: 10MB
  • Allowed types: JPEG, PNG, GIF, WebP, PDF
  • Storage: Google Cloud Storage (gs://forge-475221-attachments)

Upload Multiple Attachments

POST /api/bids/:bidId/attachments/multiple
Cookie: sAccessToken=...; sRefreshToken=...
Content-Type: multipart/form-data

{
"files": [binary, binary, ...]
}

Roles: ADMIN, ESTIMATOR

Limits:

  • Max 10 files per request
  • Max 10MB per file

Delete Attachment

DELETE /api/bids/:bidId/attachments/:id
Cookie: sAccessToken=...; sRefreshToken=...

Roles: ADMIN, ESTIMATOR

Data Model

interface Bid {
id: string // UUID
bidNumber: string // Unique, user-defined
name: string // Job/project name
clientId: string // Client UUID
location: string | null // Job location
createdBy: string // User email
status: BidStatus // Lifecycle state

// Equipment Mode
equipmentBiddingMode: string // "TRADITIONAL" | "GANTT"

// Cost Totals (read-only, auto-calculated)
concreteCost: number
laborCost: number
equipmentCost: number
materialCost: number
subcontractorCost: number
miscCost: number
subtotalCost: number
overheadAmount: number
profitAmount: number
totalCost: number

// Settings
overheadPercentage: number
profitPercentage: number
taxExempt: boolean
perDiemEnabled: boolean

// Sharing
shareCode: string | null // BID-XXXXXXXX
shareCodeAt: DateTime | null
sourceBidId: string | null // If imported
sourceUserId: string | null // If imported

// Timestamps
createdAt: DateTime
lastUpdated: DateTime

// Relations
client: Client
scopes: Scope[]
attachments: Attachment[]
}

enum BidStatus {
DRAFT
SUBMITTED
NEGOTIATION
AWARDED
COMPLETED
LOST
}

Equipment Bidding Modes

TRADITIONAL Mode

  • Equipment items assigned to individual scopes
  • Scope-based cost allocation
  • Simple rental calculations

GANTT Mode

  • Equipment tracked at bid level with timeline
  • Timeline-based cost distribution across scopes
  • Overlap detection and proportional allocation
  • More accurate for multi-scope equipment usage

View Gantt Mode Equipment Endpoints →