Scopes
Overview
Scopes represent the work breakdown structure within a bid (e.g., "Foundation", "Grade Beam", "Slab"). Each scope contains estimation items across six modules and can have a parent-child hierarchy.
Base Operations
List Scopes for Bid
- Request
- Response
GET /api/scopes/bid/:bidId
Cookie: sAccessToken=...; sRefreshToken=...
[
{
"id": "uuid",
"bidId": "uuid",
"typeId": "uuid",
"name": "Foundation",
"multiplier": 1.0,
"shape": "RECTANGLE",
"length": 100.0,
"width": 50.0,
"height": 2.0,
"cubicYards": 37.04,
"concreteCost": 45000.00,
"laborCost": 22000.00,
"equipmentCost": 8000.00,
"materialCost": 5000.00,
"subcontractorCost": 3000.00,
"miscCost": 1000.00,
"totalCost": 84000.00,
"parentScopeId": null
},
...
]
Roles: ADMIN, ESTIMATOR, PM
Get Scope
- Request
- Response
GET /api/scopes/:id
Cookie: sAccessToken=...; sRefreshToken=...
{
"id": "uuid",
"bidId": "uuid",
"typeId": "uuid",
"name": "Foundation",
"multiplier": 1.0,
"totalCost": 84000.00,
"parentScopeId": null,
"scopeType": {
"id": "uuid",
"name": "Slab"
},
"concreteItems": [...],
"laborItems": [...],
"equipmentItems": [...],
"materialItems": [...],
"subcontractorItems": [...],
"miscItems": [...]
}
Roles: ADMIN, ESTIMATOR, PM
Create Scope
- Request
- Response
POST /api/scopes
Cookie: sAccessToken=...; sRefreshToken=...
Content-Type: application/json
{
"bidId": "uuid",
"name": "Grade Beam",
"typeId": "uuid",
"multiplier": 1.0
}
{
"id": "uuid",
"name": "Grade Beam",
"message": "Scope created successfully"
}
Roles: ADMIN, ESTIMATOR
Required Fields:
bidId(string, UUID) - Parent bidname(string) - Scope nametypeId(string, UUID) - Scope type (required as of BM-39)
Optional Fields:
multiplier(number, default: 1.0) - Cost scaling factor for repeated scopes
Update Scope
- Request
- Response
PUT /api/scopes/:id
Cookie: sAccessToken=...; sRefreshToken=...
Content-Type: application/json
{
"name": "Updated Scope Name",
"multiplier": 2.0
}
{
"id": "uuid",
"message": "Scope updated successfully"
}
Roles: ADMIN, ESTIMATOR
Delete Scope
- Request
- Response
DELETE /api/scopes/:id
Cookie: sAccessToken=...; sRefreshToken=...
{
"message": "Scope deleted successfully"
}
Roles: ADMIN, ESTIMATOR
Deleting a scope will cascade delete all associated items (concrete, labor, equipment, materials, subcontractor, misc).
Batch Update Scope Positions
- Request
- Response
PATCH /api/scopes/bid/:bidId/batch
Cookie: sAccessToken=...; sRefreshToken=...
Content-Type: application/json
{
"scopes": [
{ "id": "uuid1", "position": 0 },
{ "id": "uuid2", "position": 1 },
{ "id": "uuid3", "position": 2 }
]
}
{
"message": "Scope positions updated successfully"
}
Roles: ADMIN, ESTIMATOR (owner only)
Use this endpoint to reorder scopes within a bid. This is useful for drag-and-drop UI implementations.
Scope Types
Get Required Material Categories
- Request
- Response
GET /api/scopes/:id/required-material-categories
Cookie: sAccessToken=...; sRefreshToken=...
{
"categories": ["PPE", "Lumber", "Safety"],
"scopeTypeId": "uuid",
"scopeTypeName": "Slab",
"isFallback": false
}
Roles: ADMIN, ESTIMATOR, PM
Fallback Behavior:
- If scope has no type assigned → returns ALL categories with
isFallback: true - If scope type has no categories configured → returns ALL categories with
isFallback: true - Used by Materials module to display "missing category" chips
Scope Hierarchy
Link Scope to Parent
- Request
- Response
PUT /api/scopes/:id/link
Cookie: sAccessToken=...; sRefreshToken=...
Content-Type: application/json
{
"parentScopeId": "uuid",
"inheritanceSettings": {
"concreteDimensions": {
"enabled": true,
"inheritLength": true,
"inheritWidth": true,
"inheritDepth": true
},
"materials": {
"enabled": false
},
"rebar": {
"enabled": false
}
}
}
{
"message": "Scope linked successfully"
}
Roles: ADMIN, ESTIMATOR
Constraints:
- Single-level hierarchy only (parent cannot have parent)
- Must be within same bid
- One parent per scope
- Circular reference prevention
Unlink Scope from Parent
- Request
- Response
PUT /api/scopes/:id/unlink
Cookie: sAccessToken=...; sRefreshToken=...
{
"message": "Scope unlinked successfully"
}
Roles: ADMIN, ESTIMATOR
Get Scope Hierarchy
- Request
- Response
GET /api/scopes/:id/hierarchy
Cookie: sAccessToken=...; sRefreshToken=...
{
"id": "uuid",
"name": "Grade Beam",
"parent": {
"id": "uuid",
"name": "Foundation"
},
"children": [
{
"id": "uuid",
"name": "Child Scope 1"
},
...
],
"inheritanceSettings": {...}
}
Roles: ADMIN, ESTIMATOR, PM
Get All Scopes with Hierarchy
- Request
- Response
GET /api/scopes/bid/:bidId/hierarchy
Cookie: sAccessToken=...; sRefreshToken=...
[
{
"id": "uuid",
"name": "Foundation",
"parent": null,
"children": [
{
"id": "uuid",
"name": "Grade Beam",
"parent": { "id": "uuid", "name": "Foundation" },
"children": []
}
]
},
...
]
Roles: ADMIN, ESTIMATOR, PM
Update Inheritance Settings
- Request
- Response
PUT /api/scopes/:id/inheritance
Cookie: sAccessToken=...; sRefreshToken=...
Content-Type: application/json
{
"concreteDimensions": {
"enabled": true,
"inheritLength": true,
"inheritWidth": false,
"inheritDepth": true
}
}
{
"message": "Inheritance settings updated"
}
Roles: ADMIN, ESTIMATOR
Sync Child with Parent
- Request
- Response
PUT /api/scopes/:id/sync
Cookie: sAccessToken=...; sRefreshToken=...
{
"message": "Scope synced with parent",
"updatedFields": ["length", "depth"]
}
Roles: ADMIN, ESTIMATOR
Applies current inheritance settings to sync data from parent.
Data Model
interface Scope {
id: string; // UUID
bidId: string; // Parent bid UUID
typeId: string; // Scope type UUID (required)
name: string; // Scope name
multiplier: number; // Cost scaling factor (default: 1.0)
// Dimensions (optional, for concrete calculations)
shape: string | null; // RECTANGLE, CIRCULAR, etc.
length: number | null;
width: number | null;
height: number | null;
diameter: number | null;
cubicYards: number | null;
// Cost Totals (read-only, auto-calculated)
concreteCost: number;
laborCost: number;
equipmentCost: number;
materialCost: number;
subcontractorCost: number;
miscCost: number;
totalCost: number;
// Hierarchy
parentScopeId: string | null;
inheritanceSettings: InheritanceSettings | null;
lastSyncedAt: DateTime | null;
// Relations
scopeType: ScopeType;
parent: Scope | null;
children: Scope[];
concreteItems: ConcreteItem[];
laborItems: LaborItem[];
equipmentItems: EquipmentItem[];
materialItems: MaterialItem[];
subcontractorItems: SubcontractorItem[];
miscItems: MiscItem[];
}
interface InheritanceSettings {
concreteDimensions?: {
enabled: boolean;
inheritLength: boolean;
inheritWidth: boolean;
inheritDepth: boolean;
};
materials?: {
enabled: boolean;
};
rebar?: {
enabled: boolean;
};
}
Multiplier
The multiplier field scales all costs within a scope. Useful for repeated scopes (e.g., "Grade Beam x 4").
Example:
- Scope has $10,000 in items
- Multiplier set to 4.0
- Scope
totalCost= $40,000
Related Endpoints
- Bids
- Scope Types
- Concrete Items
- Cost Rollup