Daily logs
What happened on site today: crews, hours, weather, notes, photos. Where most RFIs and change orders start.
The daily_log 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.
- projectstringProject ID.
- datedateLog date (site local).
- authorstringUser ID.
- weatherobjectcondition, high_f.
- crewarrayvendor, headcount, hours.
- notesstringFree text.
- photosarrayFile IDs.
- linkedarrayIDs of objects raised from this log.
- 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.
daily_log · sample data
object{13}
- id"dl_20260918"id
- object"daily_log"string
- project"prj_24118"id
- date"2026-09-18"date
- author"usr_mike_super"id
weatherobject{2}
- condition"clear"string
- high_f78integer
crewarray[2]
0object{3}
- vendor"vnd_volt_electric"id
- headcount9integer
- hours72integer
1object{3}
- vendor"vnd_apex_steel"id
- headcount6integer
- hours48integer
- notes"Opened L3 corridor ceiling. No fire dampers at duct penetrations through rated wall. Photos attached. RFI to follow."string
photosarray[2]
- 0"file_ph_3391"id
- 1"file_ph_3392"id
linkedarray[1]
- 0"rfi_212"id
- created_at
- updated_at
- audit_trail"/v1/daily-logs/dl_20260918/audit"string
GET
/v1/daily-logsList daily logs
Filter by project and date range.
Parameters
- projectstringqueryID of the project, e.g. prj_24118.
- fromdatequeryStart date.
- todatequeryEnd date.
- limitintegerqueryPage size, 1 to 100. Default 25.
- cursorstringqueryCursor from a previous page’s next_cursor.
Returns
A paginated list of daily_log objects. Errors use the standard error shape.
Request
curl https://api.os.construction/v1/daily-logs \
-H "Authorization: Bearer $OS_API_KEY"const res = await fetch("https://api.os.construction/v1/daily-logs", {
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/daily-logs",
headers={
"Authorization": f"Bearer {os.environ['OS_API_KEY']}",
},
)
res.raise_for_status()
data = res.json()Response · 200
{
"object": "list",
"url": "/v1/daily-logs",
"has_more": true,
"next_cursor": "cur_9f2c",
"data": [
{
"id": "dl_20260918",
"object": "daily_log",
"project": "prj_24118",
"date": "2026-09-18",
"author": "usr_mike_super",
"weather": {
"condition": "clear",
"high_f": 78
},
"crew": [
{
"vendor": "vnd_volt_electric",
"headcount": 9,
"hours": 72
},
{
"vendor": "vnd_apex_steel",
"headcount": 6,
"hours": 48
}
],
"notes": "Opened L3 corridor ceiling. No fire dampers at duct penetrations through rated wall. Photos attached. RFI to follow.",
"photos": [
"file_ph_3391",
"file_ph_3392"
],
"linked": [
"rfi_212"
],
"created_at": "2026-09-18T23:40:00Z",
"updated_at": "2026-09-18T23:40:00Z",
"audit_trail": "/v1/daily-logs/dl_20260918/audit"
}
]
}POST
/v1/daily-logsCreate a daily log
One per project per day; a second POST for the same date returns 409.
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.
- datedatebodyrequiredDate.
- notesstringbodyNotes.
Returns
The daily_log object. Errors use the standard error shape.
Request
curl -X POST https://api.os.construction/v1/daily-logs \
-H "Authorization: Bearer $OS_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"project": "prj_24118",
"date": "2026-09-18",
"notes": "Opened L3 corridor ceiling. No fire dampers at duct penetrations through rated wall. Photos attached. RFI to follow.",
"crew": [
{
"vendor": "vnd_volt_electric",
"headcount": 9,
"hours": 72
},
{
"vendor": "vnd_apex_steel",
"headcount": 6,
"hours": 48
}
]
}'const res = await fetch("https://api.os.construction/v1/daily-logs", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.OS_API_KEY}`,
"Idempotency-Key": crypto.randomUUID(),
"Content-Type": "application/json",
},
body: JSON.stringify({
"project": "prj_24118",
"date": "2026-09-18",
"notes": "Opened L3 corridor ceiling. No fire dampers at duct penetrations through rated wall. Photos attached. RFI to follow.",
"crew": [
{
"vendor": "vnd_volt_electric",
"headcount": 9,
"hours": 72
},
{
"vendor": "vnd_apex_steel",
"headcount": 6,
"hours": 48
}
]
}),
});
const obj = await res.json();import os, uuid, requests
res = requests.post(
"https://api.os.construction/v1/daily-logs",
headers={
"Authorization": f"Bearer {os.environ['OS_API_KEY']}",
"Idempotency-Key": str(uuid.uuid4()),
},
json={
"project": "prj_24118",
"date": "2026-09-18",
"notes": "Opened L3 corridor ceiling. No fire dampers at duct penetrations through rated wall. Photos attached. RFI to follow.",
"crew": [
{
"vendor": "vnd_volt_electric",
"headcount": 9,
"hours": 72
},
{
"vendor": "vnd_apex_steel",
"headcount": 6,
"hours": 48
}
]
},
)
res.raise_for_status()
data = res.json()Response · 201
{
"id": "dl_20260918",
"object": "daily_log",
"project": "prj_24118",
"date": "2026-09-18",
"author": "usr_mike_super",
"weather": {
"condition": "clear",
"high_f": 78
},
"crew": [
{
"vendor": "vnd_volt_electric",
"headcount": 9,
"hours": 72
},
{
"vendor": "vnd_apex_steel",
"headcount": 6,
"hours": 48
}
],
"notes": "Opened L3 corridor ceiling. No fire dampers at duct penetrations through rated wall. Photos attached. RFI to follow.",
"photos": [
"file_ph_3391",
"file_ph_3392"
],
"linked": [
"rfi_212"
],
"created_at": "2026-09-18T23:40:00Z",
"updated_at": "2026-09-18T23:40:00Z",
"audit_trail": "/v1/daily-logs/dl_20260918/audit"
}Events
Webhooks fire on every state change of a daily_log.