Audit Log
Every mutation in your organization — administrator UI actions and public API calls alike — is recorded in a single audit stream. Use these endpoints to ship that stream into a SIEM, build internal compliance reports, or investigate a specific change. Required scope on the API key: audit-log:read.
Endpoints
| Method | Path | Scope | Purpose |
|---|---|---|---|
GET | /api/public/v1/audit-log | audit-log:read | Paginated list of audit events with optional filters. |
GET | /api/public/v1/audit-log/actions | audit-log:read | Distinct action names ever recorded for your org. Useful for building a filter dropdown. |
What gets recorded
Public API calls are auto-audited. The entry carries actorRole = "api_key" and actorEmail = "apikey:<apiKeyId>", where <apiKeyId> is the full UUID of the API key that made the call (not the scs_live_… token prefix). Administrator UI actions use the human's email and their org_admin role. The two streams are intermixed in the same log so a single export covers all change history.
List audit events
Returns events newest-first. All filters are optional and may be combined.
GET /api/public/v1/audit-log
?action=sarif.ingested
&actorEmail=apikey:7d8a3e0b-4f12-4cd6-b9e1-21f6cf5d4a73
&from=2026-05-01T00:00:00Z
&to=2026-05-29T23:59:59Z
&page=1
&pageSize=50
Authorization: Bearer scs_live_…Query parameters
| Parameter | Type | Default | Notes |
|---|---|---|---|
action | string | — | Exact-match action name. Pull valid values from /audit-log/actions. |
actorEmail | string | — | Exact-match actor email. For API-key entries use the form apikey:<api-key-uuid>. |
from | ISO 8601 | — | Inclusive lower bound on createdAt (UTC). |
to | ISO 8601 | — | Inclusive upper bound on createdAt (UTC). |
page | integer | 1 | 1-based page index. |
pageSize | integer | 50 | Capped at 200. Values outside 1–200 fall back to 50. |
Response
{
"items": [
{
"id": "0e7a3b4c-9d2f-4e1a-b6c8-2c4f8d5a1e90",
"createdAt": "2026-05-29T13:42:11.318Z",
"actorEmail": "apikey:7d8a3e0b-4f12-4cd6-b9e1-21f6cf5d4a73",
"actorRole": "api_key",
"action": "assignment.created",
"targetType": "assignment",
"targetId": "b1d8c2a0-7e34-4f9a-9d51-8e2c91a4f607",
"targetLabel": "jane.smith@acme.com / SQL Injection",
"metadata": "{\"topicId\":\"sql-injection\",\"deadlineDays\":14}",
"ipAddress": "203.0.113.42"
},
{
"id": "ba98c9d4-5f60-4b21-9c0e-3f72e1b58a44",
"createdAt": "2026-05-29T13:41:08.902Z",
"actorEmail": "amelia.ng@acme.com",
"actorRole": "org_admin",
"action": "user.invited",
"targetType": "user",
"targetId": "c4f1d22a-83b7-4d2c-9a01-7e6b5d1f9c33",
"targetLabel": "jane.smith@acme.com",
"metadata": null,
"ipAddress": "203.0.113.7"
}
],
"total": 2841,
"page": 1,
"pageSize": 50
}metadatais a JSON string (not an object). Parse it on the client; the shape varies per action.totalreflects the full filtered count, not just the current page — divide bypageSizeto derive page count.- User-agent and other request headers are stored server-side for forensics but are not returned in this response.
Example
curl -sS \
-H "Authorization: Bearer $SCH_API_KEY" \
"https://api.limeplate.com/api/public/v1/audit-log?from=2026-05-01T00:00:00Z&pageSize=200"List distinct actions
Returns every action name that has ever been recorded for your organization, sorted alphabetically. The list is org-scoped — a fresh tenant returns an empty array until events start flowing.
GET /api/public/v1/audit-log/actions
Authorization: Bearer scs_live_…Response
[
"apikey.created",
"apikey.revoked",
"assignment.completed",
"assignment.created",
"course.published",
"sarif.ingested",
"user.invited",
"user.role_changed",
"webhook.created"
]Example
curl -sS \
-H "Authorization: Bearer $SCH_API_KEY" \
https://api.limeplate.com/api/public/v1/audit-log/actionsShipping to a SIEM
The typical pattern is to poll /audit-log on a cron, passing from equal to the last createdAt you ingested and walking pages until items.length < pageSize. Because results are ordered newest-first, an incremental fetcher should reverse the page before emitting events to keep downstream order chronological. There is no streaming audit webhook in v1 — pair audit polling with the targeted domain webhooks documented under Webhooks when you also need low-latency reaction to specific events.