Cost codes
The spine of job cost. CSI-style codes per project, shared by budgets, commitments, invoices and change orders.
The cost_code object
Every object carries an id, timestamps, and an audit_trail. Money is integer cents. Expand any node in the explorer to see how it links to the rest of the record.
- idstringUnique, stable identifier. Prefixed by object type.
- objectstringString naming the object type.
- projectstringOwning project.
- codestringCode as you write it, e.g. 23 33 00.
- namestringDescription.
- divisionstringDivision label.
- cost_typeenumlabor · material · equipment · subcontract · other.
- activebooleanInactive codes reject new postings.
- created_attimestampISO 8601, UTC.
- updated_attimestampISO 8601, UTC. Changes on every write.
- audit_trailstringPath to the append-only history of who changed what, and when.
cost_code · sample data
object{11}
- id"cc_233300"id
- object"cost_code"id
- project"prj_24118"id
- code"23 33 00"string
- name"Air Duct Accessories"string
- division"23 · HVAC"string
- cost_type"subcontract"string
- activetrueboolean
- created_at
- updated_at
- audit_trail"/v1/cost-codes/cc_233300/audit"string
GET
/v1/cost-codesList cost codes
Cost codes for one project.
Parameters
- projectstringqueryrequiredID of the project, e.g. prj_24118.
- limitintegerqueryPage size, 1 to 100. Default 25.
- cursorstringqueryCursor from a previous page’s next_cursor.
Returns
A paginated list of cost_code objects. Errors use the standard error shape.
Request
curl https://api.os.construction/v1/cost-codes \
-H "Authorization: Bearer $OS_API_KEY"const res = await fetch("https://api.os.construction/v1/cost-codes", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.OS_API_KEY}`,
},
});
const page = await res.json();import os, uuid, requests
res = requests.get(
"https://api.os.construction/v1/cost-codes",
headers={
"Authorization": f"Bearer {os.environ['OS_API_KEY']}",
},
)
res.raise_for_status()
data = res.json()Response · 200
{
"object": "list",
"url": "/v1/cost-codes",
"has_more": false,
"next_cursor": null,
"data": [
{
"id": "cc_233300",
"object": "cost_code",
"project": "prj_24118",
"code": "23 33 00",
"name": "Air Duct Accessories",
"division": "23 · HVAC",
"cost_type": "subcontract",
"active": true,
"created_at": "2026-01-12T15:10:00Z",
"updated_at": "2026-01-12T15:10:00Z",
"audit_trail": "/v1/cost-codes/cc_233300/audit"
},
{
"id": "cc_260500",
"object": "cost_code",
"project": "prj_24118",
"code": "26 05 00",
"name": "Common Work Results for Electrical",
"division": "26 · Electrical",
"cost_type": "subcontract",
"active": true,
"created_at": "2026-01-12T15:10:00Z",
"updated_at": "2026-01-12T15:10:00Z",
"audit_trail": "/v1/cost-codes/cc_260500/audit"
}
]
}POST
/v1/cost-codesCreate a cost code
Adds a code to a project.
Idempotent. Send an Idempotency-Key; retries within 24 hours return the original result and never write twice.
Parameters
- Idempotency-KeystringheaderrequiredAny unique string. Replays return the first result instead of writing twice.
- projectstringbodyrequiredProject ID.
- codestringbodyrequiredCode.
- namestringbodyrequiredDescription.
- cost_typeenumbodyCost type.
Returns
The cost_code object. Errors use the standard error shape.
Request
curl -X POST https://api.os.construction/v1/cost-codes \
-H "Authorization: Bearer $OS_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"project": "prj_24118",
"code": "23 33 00",
"name": "Air Duct Accessories",
"cost_type": "subcontract"
}'const res = await fetch("https://api.os.construction/v1/cost-codes", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.OS_API_KEY}`,
"Idempotency-Key": crypto.randomUUID(),
"Content-Type": "application/json",
},
body: JSON.stringify({
"project": "prj_24118",
"code": "23 33 00",
"name": "Air Duct Accessories",
"cost_type": "subcontract"
}),
});
const obj = await res.json();import os, uuid, requests
res = requests.post(
"https://api.os.construction/v1/cost-codes",
headers={
"Authorization": f"Bearer {os.environ['OS_API_KEY']}",
"Idempotency-Key": str(uuid.uuid4()),
},
json={
"project": "prj_24118",
"code": "23 33 00",
"name": "Air Duct Accessories",
"cost_type": "subcontract"
},
)
res.raise_for_status()
data = res.json()Response · 201
{
"id": "cc_233300",
"object": "cost_code",
"project": "prj_24118",
"code": "23 33 00",
"name": "Air Duct Accessories",
"division": "23 · HVAC",
"cost_type": "subcontract",
"active": true,
"created_at": "2026-01-12T15:10:00Z",
"updated_at": "2026-01-12T15:10:00Z",
"audit_trail": "/v1/cost-codes/cc_233300/audit"
}Events
Webhooks fire on every state change of a cost_code.