The audit feed lets your security monitoring tool (SIEM) collect your workspace's audit log: every change made in the app or through the API, sign-ins, exports and super-admin activity. It returns the same rows as Settings → Audit log, oldest first, so you can poll it with updatedSince and a cursor.
All endpoints sit under /api/v1 and need an API key (Authorization: Bearer jdr_live_…) created by your Workspace Admin in Settings → Integrations.
Endpoints
| Method and path | What it does | Permission |
|---|---|---|
GET /api/v1/audit-events | List audit rows, oldest first (cursor pagination, updatedSince) | audit.view |
API reads are not audited, so the feed carries writes, sign-ins and exports only.
The audit event object
| Field | Type | Notes |
|---|---|---|
id | string | |
workspaceId | string or null | Your workspace. |
action | string | The action key, e.g. recruitment.application.stage_changed, auth.signed_in, audit.log.exported. |
actor | object | { type, id, name }. type is user (a workspace user), integration (an API key; name is the integration's name; id is null once the integration is deleted) or system (automation by metadata.source, or a super admin acting from the platform console). |
target | object or null | { type, id, label }: the record the action was on. label stays readable after the record is deleted. |
metadata | object or null | As stored: changes ({ field: { from, to } }), label, source, actorIntegration ({ name, keyPrefix } for API writes) and action-specific details. |
ipAddress, userAgent | string or null | Of the request that made the change. |
occurredAt | ISO 8601 | When it happened. |
Passwords, tokens and other secrets are blanked ([redacted]) when the row is written. Candidate contact values (email, phone, national ID) in metadata.changes read [redacted] for keys without recruitment.candidate.contact. On job description rows, metadata.changes leaves out internal grading fields that are not part of the API (the evaluation grade and the placeholder flag). For keys without structure.functional.salary, pay is left out: the pay keys in metadata.changes of position rows (payScaleId, payGradeId, payStepNumber, baseSalary) and job description rows (payScaleId, payGradeId, salaryMin, salaryMax), the whole metadata.changes of pay scale rows (grade amounts included), a pay scale row's grade metadata.rank, and pay values stored at the top level of metadata on any row (payScaleId, payGradeId, payStepNumber, baseSalary, payPeriod, salaryMin, salaryMax, gradeCode), such as the pay ids on a position or opening creation. Ids and labels, such as the repriced positions and job descriptions listed on a pay grade edit, stay.
Polling
updatedSincefilters onoccurredAt: rows recorded at or after that time. Audit rows never change.- Rows come oldest first; follow
nextCursoruntil it isnull, then poll again later withupdatedSinceset to the lastoccurredAtyou stored (deduplicate byid). limitis 1–100 (default 50).
The same object is sent as the opt-in audit.recorded webhook event: pick it explicitly on an endpoint (it is not part of *).
Errors
| Status and code | Meaning |
|---|---|
403 forbidden | The key lacks audit.view. |
422 validation_failed | Invalid limit, cursor or updatedSince. |
Example
curl "https://jadiroon.com/api/v1/audit-events?updatedSince=2026-10-24T09:00:00Z&limit=1" \
-H "Authorization: Bearer $JADIROON_KEY"
{
"data": [
{
"id": "cmvm7ru0q0006kndle0fx4ivt",
"workspaceId": "cmvikf7rn0001knoq5veyug12",
"action": "recruitment.interview.reproposed",
"actor": { "type": "integration", "id": "cmvjkkvpz0001kndd3kvfcsj7", "name": "ERP sync" },
"target": { "type": "interview", "id": "cmvm7rmyv0001kndlb0qdm315", "label": "Turki Alanazi" },
"metadata": {
"label": "Turki Alanazi",
"changes": { "location": { "from": "HQ room 2", "to": "Online" }, "durationMinutes": { "from": 45, "to": 60 } },
"actorIntegration": { "name": "ERP sync", "keyPrefix": "jdr_live_ITY" }
},
"ipAddress": "203.0.113.10",
"userAgent": "curl/8.7.1",
"occurredAt": "2026-10-24T09:46:14.331Z"
}
],
"nextCursor": "Y212bTdydTBxMDAwNmtuZGxlMGZ4NGl2dA"
}