Pay apps
Owner billings in AIA G702/G703 shape. Approved change orders land on the next pay app automatically.
The pay_app 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.
- numberintegerApplication number.
- statusenumdraft · submitted · approved · paid.
- period_startdateBilling period start.
- period_enddateBilling period end.
- formatenumaia_g702_g703 · custom.
- work_this_periodintegerWork completed this period, cents.
- retainage_pctnumberRetainage rate applied.
- retainage_this_periodintegerwork_this_period × retainage_pct.
- net_due_this_periodintegerwork_this_period − retainage_this_period.
- change_ordersarrayCOs billed on this application.
- lien_waivers_missingarrayVendors whose waivers are outstanding.
- 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.
object{17}
- id"pa_9"id
- object"pay_app"id
- project"prj_24118"id
- number9integer
- status"submitted"string
- period_start"2026-09-01"date
- period_end"2026-09-30"date
- format"aia_g702_g703"id
- work_this_period231040000integer$2,310,400.00
- retainage_pct10integer
- retainage_this_period23104000integer$231,040.00
- net_due_this_period207936000integer$2,079,360.00
change_ordersarray[1]
- 0"co_14"id
lien_waivers_missingarray[2]
- 0"vnd_apex_steel"id
- 1"vnd_coredry"id
- created_at
- updated_at
- audit_trail"/v1/pay-apps/pa_9/audit"string
/v1/pay-apps/{id}Retrieve a pay app
Header totals. Fetch G703 lines with /lines.
Parameters
- idstringpathrequiredThe pay app ID, e.g. pa_9.
Returns
The pay_app object. Errors use the standard error shape.
curl https://api.os.construction/v1/pay-apps/pa_9 \
-H "Authorization: Bearer $OS_API_KEY"const res = await fetch("https://api.os.construction/v1/pay-apps/pa_9", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.OS_API_KEY}`,
},
});
const obj = await res.json();import os, uuid, requests
res = requests.get(
"https://api.os.construction/v1/pay-apps/pa_9",
headers={
"Authorization": f"Bearer {os.environ['OS_API_KEY']}",
},
)
res.raise_for_status()
data = res.json(){
"id": "pa_9",
"object": "pay_app",
"project": "prj_24118",
"number": 9,
"status": "submitted",
"period_start": "2026-09-01",
"period_end": "2026-09-30",
"format": "aia_g702_g703",
"work_this_period": 231040000,
"retainage_pct": 10,
"retainage_this_period": 23104000,
"net_due_this_period": 207936000,
"change_orders": [
"co_14"
],
"lien_waivers_missing": [
"vnd_apex_steel",
"vnd_coredry"
],
"created_at": "2026-09-30T22:00:00Z",
"updated_at": "2026-10-01T15:30:00Z",
"audit_trail": "/v1/pay-apps/pa_9/audit"
}/v1/pay-apps/{id}/linesList SOV lines
G703 continuation sheet rows.
Parameters
- idstringpathrequiredThe pay app ID, e.g. pa_9.
- limitintegerqueryPage size, 1 to 100. Default 25.
- cursorstringqueryCursor from a previous page’s next_cursor.
Returns
A paginated list of pay_app objects. Errors use the standard error shape.
curl https://api.os.construction/v1/pay-apps/pa_9/lines \
-H "Authorization: Bearer $OS_API_KEY"const res = await fetch("https://api.os.construction/v1/pay-apps/pa_9/lines", {
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/pay-apps/pa_9/lines",
headers={
"Authorization": f"Bearer {os.environ['OS_API_KEY']}",
},
)
res.raise_for_status()
data = res.json(){
"object": "list",
"url": "/v1/pay-apps/pa_9/lines",
"has_more": true,
"next_cursor": "cur_9f2c",
"data": [
{
"object": "pay_app_line",
"item": "23-04",
"description": "CO #14 Fire dampers",
"scheduled_value": 8640000,
"previous": 0,
"this_period": 8640000,
"percent_complete": 100,
"retainage": 864000
}
]
}/v1/pay-apps/{id}/submitSubmit a pay app
Locks the period. Fails if required lien waivers are missing unless you pass allow_missing_waivers.
Idempotent. Send an Idempotency-Key; retries within 24 hours return the original result and never write twice.
Parameters
- idstringpathrequiredThe pay app ID, e.g. pa_9.
- Idempotency-KeystringheaderrequiredAny unique string. Replays return the first result instead of writing twice.
- allow_missing_waiversbooleanbodySubmit anyway and record it on the audit trail.
Returns
The pay_app object. Errors use the standard error shape.
curl -X POST https://api.os.construction/v1/pay-apps/pa_9/submit \
-H "Authorization: Bearer $OS_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"allow_missing_waivers": true
}'const res = await fetch("https://api.os.construction/v1/pay-apps/pa_9/submit", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.OS_API_KEY}`,
"Idempotency-Key": crypto.randomUUID(),
"Content-Type": "application/json",
},
body: JSON.stringify({
"allow_missing_waivers": true
}),
});
const obj = await res.json();import os, uuid, requests
res = requests.post(
"https://api.os.construction/v1/pay-apps/pa_9/submit",
headers={
"Authorization": f"Bearer {os.environ['OS_API_KEY']}",
"Idempotency-Key": str(uuid.uuid4()),
},
json={
"allow_missing_waivers": True
},
)
res.raise_for_status()
data = res.json(){
"id": "pa_9",
"object": "pay_app",
"project": "prj_24118",
"number": 9,
"status": "submitted",
"period_start": "2026-09-01",
"period_end": "2026-09-30",
"format": "aia_g702_g703",
"work_this_period": 231040000,
"retainage_pct": 10,
"retainage_this_period": 23104000,
"net_due_this_period": 207936000,
"change_orders": [
"co_14"
],
"lien_waivers_missing": [
"vnd_apex_steel",
"vnd_coredry"
],
"created_at": "2026-09-30T22:00:00Z",
"updated_at": "2026-10-01T15:30:00Z",
"audit_trail": "/v1/pay-apps/pa_9/audit"
}Events
Webhooks fire on every state change of a pay_app.