{"openapi":"3.1.0","info":{"title":"iComply API","version":"1.0.0","description":"Read-only access to an organisation's own iComply records (any organisation with the Integrations pack): the contractors on its register and their status on each site, sites, who's on site now, gate events, an incident summary, corrective actions and expiring documents. Keys are created by the organisation's administrator (Connections), shown once, and limited by scope and end date. 120 requests per minute per key. Every request is recorded in the organisation's access log. Webhooks (signed with HMAC-SHA256) are described under `x-webhooks`."},"servers":[{"url":"https://app.icomplyaustralia.com.au/api/v1"}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"An API key (ick_…). Scopes: read:subcontractors (Subcontractors and their status on each site); read:sites (Sites); read:gate (Who's on site now and gate events (sign-ins, refusals, overrides)); read:safety (Incident summary and corrective actions); read:compliance (Documents and tickets expiring); read:insights (Insights feed for Power BI: facts by site and month or day, injury rates (counts and hours; no names))."}}},"paths":{"/subcontractors":{"get":{"summary":"Subcontractors and their status","description":"Company-wide status, and status on each site they're on (the site's own requirements too). Scope: `read:subcontractors`.","security":[{"bearer":["read:subcontractors"]}],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"From the previous page's nextCursor"},{"name":"site","in":"query","schema":{"type":"string","format":"uuid"},"description":"Only subcontractors on this site"}],"responses":{"200":{"description":"OK. Strong ETag header.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Register link id"},"company":{"type":"string"},"abn":{"type":["string","null"]},"trade":{"type":["string","null"]},"category":{"type":"string"},"categoryLabel":{"type":"string"},"invitation":{"type":"string","enum":["invited","accepted","declined"]},"status":{"type":"string","enum":["cleared","cleared_expiring_or_in_review","not_cleared","invited"]},"cleared":{"type":"boolean"},"requirementsMet":{"type":"integer"},"requirementsTotal":{"type":"integer"},"nextExpiry":{"type":["string","null"],"description":"YYYY-MM-DD"},"sites":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string","enum":["cleared","cleared_expiring_or_in_review","not_cleared","invited"]},"cleared":{"type":"boolean"}}}}}}},"nextCursor":{"type":["string","null"],"description":"Pass as ?cursor= for the next page; null on the last page."}},"required":["data","nextCursor"]}}}},"304":{"description":"Not modified (If-None-Match matched the ETag)"},"400":{"description":"Bad query value","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Missing, malformed, unknown, expired or revoked key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"403":{"description":"The key doesn't have this scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"429":{"description":"Rate limited (Retry-After header, seconds)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/sites":{"get":{"summary":"Sites","description":"Scope: `read:sites`.","security":[{"bearer":["read:sites"]}],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"From the previous page's nextCursor"},{"name":"status","in":"query","schema":{"type":"string","enum":["active","closed"]}}],"responses":{"200":{"description":"OK. Strong ETag header.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"client":{"type":["string","null"]},"address":{"type":["string","null"]},"state":{"type":"string"},"status":{"type":"string","enum":["active","closed"]},"startsOn":{"type":["string","null"]},"endsOn":{"type":["string","null"]}}}},"nextCursor":{"type":["string","null"],"description":"Pass as ?cursor= for the next page; null on the last page."}},"required":["data","nextCursor"]}}}},"304":{"description":"Not modified (If-None-Match matched the ETag)"},"400":{"description":"Bad query value","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Missing, malformed, unknown, expired or revoked key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"403":{"description":"The key doesn't have this scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"429":{"description":"Rate limited (Retry-After header, seconds)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/sites/{id}/on-site":{"get":{"summary":"Who's on site now","description":"Names and companies only (no phone numbers). Scope: `read:gate`.","security":[{"bearer":["read:gate"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK. Strong ETag header.","content":{"application/json":{"schema":{"type":"object","properties":{"site":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}}},"count":{"type":"integer"},"data":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["contractor","worker","presenter","visitor"]},"name":{"type":"string"},"company":{"type":["string","null"]},"since":{"type":"string","description":"ISO 8601"}}}}}}}}},"304":{"description":"Not modified (If-None-Match matched the ETag)"},"400":{"description":"Bad query value","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Missing, malformed, unknown, expired or revoked key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"403":{"description":"The key doesn't have this scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"429":{"description":"Rate limited (Retry-After header, seconds)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/gate-events":{"get":{"summary":"Gate events","description":"Oldest first. A stop-list refusal says only \"Stop list\". Scope: `read:gate`.","security":[{"bearer":["read:gate"]}],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"From the previous page's nextCursor"},{"name":"site","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"from","in":"query","schema":{"type":"string","format":"date"},"description":"Default: 6 days before `to`"},{"name":"to","in":"query","schema":{"type":"string","format":"date"},"description":"Default: today (Australian local dates). 93 days at most."}],"responses":{"200":{"description":"OK. Strong ETag header.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["sign_in","override","refusal"]},"at":{"type":"string","description":"ISO 8601"},"site":{"type":"object"},"subcontractorId":{"type":["string","null"]},"company":{"type":["string","null"]},"worker":{"type":["object","null"]},"outcome":{"type":"string"},"reasons":{"type":"array","items":{"type":"string"}},"overrideReason":{"type":["string","null"]},"signedOutAt":{"type":["string","null"]}}}},"nextCursor":{"type":["string","null"],"description":"Pass as ?cursor= for the next page; null on the last page."}},"required":["data","nextCursor"]}}}},"304":{"description":"Not modified (If-None-Match matched the ETag)"},"400":{"description":"Bad query value","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Missing, malformed, unknown, expired or revoked key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"403":{"description":"The key doesn't have this scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"429":{"description":"Rate limited (Retry-After header, seconds)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/incidents/summary":{"get":{"summary":"Incident summary","description":"Counts only: no descriptions and no people. Scope: `read:safety`.","security":[{"bearer":["read:safety"]}],"parameters":[{"name":"site","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"from","in":"query","schema":{"type":"string","format":"date"}},{"name":"to","in":"query","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"OK. Strong ETag header.","content":{"application/json":{"schema":{"type":"object","properties":{"from":{"type":"string"},"to":{"type":"string"},"total":{"type":"integer"},"mayBeNotifiable":{"type":"integer"},"byKind":{"type":"object"},"bySeverity":{"type":"object"},"byStatus":{"type":"object"},"bySite":{"type":"array"}}}}}},"304":{"description":"Not modified (If-None-Match matched the ETag)"},"400":{"description":"Bad query value","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Missing, malformed, unknown, expired or revoked key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"403":{"description":"The key doesn't have this scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"429":{"description":"Rate limited (Retry-After header, seconds)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/corrective-actions":{"get":{"summary":"Corrective actions","description":"Owners aren't named. Scope: `read:safety`.","security":[{"bearer":["read:safety"]}],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"From the previous page's nextCursor"},{"name":"status","in":"query","schema":{"type":"string","enum":["open","done","verified","cancelled","overdue"]}},{"name":"site","in":"query","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK. Strong ETag header.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"site":{"type":["object","null"]},"source":{"type":"string"},"sourceRef":{"type":["string","null"]},"priority":{"type":"string"},"dueOn":{"type":"string"},"status":{"type":"string","enum":["open","done","verified","cancelled"]},"overdue":{"type":"boolean"},"raisedAt":{"type":"string"},"closedOutAt":{"type":["string","null"]},"verifiedAt":{"type":["string","null"]}}}},"nextCursor":{"type":["string","null"],"description":"Pass as ?cursor= for the next page; null on the last page."}},"required":["data","nextCursor"]}}}},"304":{"description":"Not modified (If-None-Match matched the ETag)"},"400":{"description":"Bad query value","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Missing, malformed, unknown, expired or revoked key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"403":{"description":"The key doesn't have this scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"429":{"description":"Rate limited (Retry-After header, seconds)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/expiries":{"get":{"summary":"Documents and tickets expiring","description":"Approved documents of accepted subcontractors expiring from today to today + days, soonest first. Scope: `read:compliance`.","security":[{"bearer":["read:compliance"]}],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"From the previous page's nextCursor"},{"name":"days","in":"query","schema":{"type":"integer","minimum":1,"maximum":365,"default":30}}],"responses":{"200":{"description":"OK. Strong ETag header.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"documentId":{"type":"string"},"subcontractorId":{"type":"string"},"company":{"type":"string"},"documentType":{"type":"string"},"label":{"type":"string"},"expiresOn":{"type":"string"},"daysLeft":{"type":"integer"},"holder":{"type":"string","enum":["business","worker"]},"workerId":{"type":["string","null"]}}}},"nextCursor":{"type":["string","null"],"description":"Pass as ?cursor= for the next page; null on the last page."}},"required":["data","nextCursor"]}}}},"304":{"description":"Not modified (If-None-Match matched the ETag)"},"400":{"description":"Bad query value","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Missing, malformed, unknown, expired or revoked key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"403":{"description":"The key doesn't have this scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"429":{"description":"Rate limited (Retry-After header, seconds)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/insights/{table}":{"get":{"summary":"Insights feed (Power BI)","description":"Flat tables of facts for reporting tools: `sites` (Sites (id, name, state, status)); `site-months` (Facts by site and month: hours, injuries by class, days lost, gate refusals and overrides, inspections done and due, findings, corrective actions, diary days signed off); `site-days` (Facts by site and day: the same daily events, plus the snapshot figures kept that day (compliance, open and overdue items, coverage, SDS currency, assets due)); `injury-rates` (Injury rates by site and month, for the month and the rolling 12 months (LTIFR, MTIFR, TRIFR) with the counts and hours behind them); `findings-months` (Findings by site, month, type and category: raised, closed, overdue at the end of the month, average days to close (companies by register id, not name)). Counts, hours and rates only: no people's names, and companies aren't named. Works while the organisation has Insights on; a key with only this scope works without Integrations. Scope: `read:insights`.","security":[{"bearer":["read:insights"]}],"parameters":[{"name":"table","in":"path","required":true,"schema":{"type":"string","enum":["sites","site-months","site-days","injury-rates","findings-months"]}},{"name":"from","in":"query","schema":{"type":"string"},"description":"A month (2026-01) for month tables; a date (2026-10-01) for site-days"},{"name":"to","in":"query","schema":{"type":"string"}},{"name":"site","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"format","in":"query","schema":{"type":"string","enum":["json","csv"]},"description":"csv: the same table as CSV (a header row, then the rows)"}],"responses":{"200":{"description":"OK. Strong ETag header.","content":{"application/json":{"schema":{"type":"object","properties":{"table":{"type":"string"},"generatedAt":{"type":"string","description":"ISO 8601"},"from":{"type":"string"},"to":{"type":"string"},"columns":{"type":"array","items":{"type":"string"}},"rows":{"type":"array","items":{"type":"array"}}},"required":["table","columns","rows"]}}}},"304":{"description":"Not modified (If-None-Match matched the ETag)"},"400":{"description":"Bad query value","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Missing, malformed, unknown, expired or revoked key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"403":{"description":"The key doesn't have this scope","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"429":{"description":"Rate limited (Retry-After header, seconds)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}}},"x-webhooks":{"signing":"Each delivery is a POST with JSON and the header `X-IComply-Signature: t=<unix seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\" with the endpoint's secret>`. Reject a timestamp more than 5 minutes old, and compare in constant time. Also `X-IComply-Event` and `X-IComply-Delivery`. Answer 2xx within 10 seconds; anything else is retried with backoff (1 minute, 5 minutes, 30 minutes, 2 hours, 6 hours, 24 hours), and an endpoint is switched off after 15 failures in a row.","events":[{"type":"subcontractor.status_changed","description":"A subcontractor's company-wide status changed (cleared, expiring or in review, not cleared)"},{"type":"gate.refused","description":"Someone was refused at a site's gate (not cleared, or on the stop list)"},{"type":"gate.override","description":"A refusal was overridden and the person let in"},{"type":"incident.reported","description":"An incident or near miss was reported"},{"type":"document.expiring","description":"An approved document or ticket expires in 30, 14, 7 or 0 days"},{"type":"corrective_action.overdue","description":"A corrective action went overdue"}],"envelope":{"id":"evt_…","type":"gate.refused","createdAt":"ISO 8601","data":{}}}}