API reference
Audit log
Every change and sign-in in the workspace, tamper-evident (hash chained). Read, export, verify.
List audit log entries
GET/v0/tenants/{tenant_id}/audit
The audit log of your workspace, newest first: every change made in the console, through the API, by an integrator, by Cloudraw support or automatically. Filters combine (AND). Pages stay stable while new entries are written, so you can poll from the top and stop when you reach an entry you already have (compare tseq). Actor names are shown in readable form (for example "Cloudraw support (<name>) for case SC-…"); use GET …/audit/export for the stored entries as written.
To have entries pushed to your SIEM instead of polling, see the Log streaming endpoints (…/siem) under the Log streaming tag.
Token: read-only or full access · Created by: owner or security admin
Pagination: cursor based — see Pagination.
limit: 1-1000, default 200.
Path parameters
- tenant_idstringrequired
Your workspace id (Settings → Workspace in the console; it is also in every console URL).
Query parameters
- actionstring
Only actions starting with this text (prefix match):
device.= every device action,person.invite= invites. - actorstring
Only entries by this actor, exact match on the stored actor (an admin e-mail, or
token:<token name>). - targetstring
Only entries that name this id (person, device, app, connector, private network, rule, grant, session, token, …) — the "Activity" of one object. Up to 80 characters.
- sincestring (date-time)
Only entries at or after this time (ISO 8601, UTC).
- untilstring (date-time)
Only entries at or before this time (ISO 8601, UTC).
- actor_kindstring
Only actions by integrator staff (
partner) or by Cloudraw support (cloudraw_support). - partner_idstring
Everything about one integrator: its staff's actions and its access link events.
- support_grantstring
Every entry of one Cloudraw support access grant (request, decision, actions under it, end).
- limitinteger
Page size.
- cursorstring
Pass back
next_cursorfrom the previous page, unchanged. Omit for the first page.
Responses
200 One page of entries.
application/json
- itemsarray of AuditEntryrequired
Newest first.
items fields
- atstring (date-time)required
When it happened (UTC).
- tseqinteger | null
Your workspace's own sequence number: 1, 2, 3 … with no gaps. A gap in what you stored means you missed entries.
- actionstringrequired
What happened, dotted:
<object>.<verb>(for exampleperson.invite,device.quarantine,session.kill,audit.export).?action=matches a prefix, sodevice.returns every device action. - tenantstring
Your workspace id.
- actorstring
Who did it: an admin e-mail;
token:<token name>for an API token;Integrator <name> (<member>);Cloudraw support (<name>) for case <id>;Cloudraw staff (<name>);Cloudraw (automatic); orsystemfor scheduled work. - actor_kindstring
Set when the actor is not one of your own admins or tokens.
- actor_rolestring
Admin role of the actor at the time (
owner,security_admin,connector_op,auditor,helpdesk; an API token shows its role ceiling). - viastring
Channel:
panel(the Cloudraw console),api(an API token; entries written before 13 Oct 2026 showpanel),scim(SCIM provisioning),self-service,device,operator(Cloudraw staff), or a feature-specific value such asssoorconnector. - ipstring
Source IP address of the caller (the admin's browser for console actions).
- via_ipstring
The hop the request came through, when it differs from
ip. - req_idstring
Request id; quote it to Cloudraw support.
- partner_idstring | null
The integrator, when
actor_kindispartner. - support_grantstring | null
The support access grant, when
actor_kindiscloudraw_support. - support_casestring | null
The support case the grant belongs to.
- break_glassboolean
Emergency support access.
- support_suggestionstring
Set when an owner applied a change suggested by Cloudraw support.
- hashstring
Hash chaining this entry to the previous one (hex).
- algstring
Keyed hash; absent on older entries (plain SHA-256).
- next_cursorstring | nullrequired
Opaque cursor for the next (older) page; null on the last page.
- next_pagenull
Always null; kept for older clients. Use
next_cursor.
400 invalid-limit invalid-cursor invalid-partner-id invalid-actor-kind invalid-support-grant
invalid-limit: limit is not an integer from 1 to 1000.
invalid-cursor: cursor is not a next_cursor from this API (pass it back unchanged).
invalid-partner-id: partner_id is not an integrator id.
invalid-actor-kind: actor_kind is not partner or cloudraw_support.
invalid-support-grant: support_grant is not a support grant id.
401 unauthorized invalid-token token-expired
unauthorized: No Authorization: Bearer crw_… header was sent.
invalid-token: The token is unknown or was revoked.
token-expired: The token is past its expiry date. Create a new one.
403 insufficient-role tenant-assertion-mismatch
insufficient-role: The token's role ceiling does not allow this call.
tenant-assertion-mismatch: The token belongs to another workspace than {tenant_id}.
404 tenant-not-found
tenant-not-found: No workspace with this id.
503 audit-unavailable
audit-unavailable: The audit log cannot be read right now. Retry shortly.
curl -sS -X GET "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/audit" \
-H "Authorization: Bearer $CLOUDRAW_TOKEN"$headers = @{ Authorization = "Bearer $env:CLOUDRAW_TOKEN" }
Invoke-RestMethod -Method Get -Uri "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/audit" -Headers $headersimport os, uuid, requests
r = requests.get(
"https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/audit",
headers={"Authorization": f"Bearer {os.environ['CLOUDRAW_TOKEN']}"},
timeout=30,
)
r.raise_for_status()
print(r.json())const res = await fetch("https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/audit", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.CLOUDRAW_TOKEN}`,
},
});
if (!res.ok) throw new Error((await res.json()).code);
console.log(await res.json());{
"items": [
{
"at": "2026-10-13T09:24:11.000Z",
"tseq": 1842,
"action": "device.quarantine",
"tenant": "tq7x2m9k4ab",
"actor": "dana.levi@example.com",
"actor_role": "security_admin",
"via": "panel",
"ip": "203.0.113.24",
"req_id": "req_8k2x0m9s1d4f",
"device": "dvc_5mxq2b7r8k",
"reason": "Suspicious sign-in",
"sessions_cut": 1,
"sessions_failed": 0,
"alg": "hmac",
"hash": "6f1c2a9e0b4d7f38a5c1e2d9b0f4a7c3e8d1b6f2a9c0e7d4b3f8a1c6e2d9b0f4"
}
],
"next_cursor": "YTM6MTg0Mg",
"next_page": null
}Export the audit log
GET/v0/tenants/{tenant_id}/audit/export
Downloads audit entries as newline-delimited JSON (one entry per line, newest first), as a file attachment cloudraw-audit-<workspace>.jsonl. Takes the same filters as GET …/audit, up to 10,000 entries per call; use since / until (or cursor) to export larger ranges in parts. Entries are exactly as stored (actor fields are not rewritten for display), so their hashes can be checked. Every export is itself written to the audit log (audit.export), and so is a refused one (export.rate_limited).
Token: read-only or full access · Created by: owner or security admin
Pagination: cursor based — see Pagination.
Rate limit: 10 exports per hour per admin (or API token) per workspace, shared with the integrator review export. Over it: 429 rate-limited with Retry-After and retry_after_s.
limit: 1-10000, default 10000. The file has no next_cursor: to continue, pass until = the at of the last line, or cursor. For continuous delivery use Log streaming (…/siem, Log streaming tag).
Path parameters
- tenant_idstringrequired
Your workspace id (Settings → Workspace in the console; it is also in every console URL).
Query parameters
- actionstring
Only actions starting with this text (prefix match):
device.= every device action,person.invite= invites. - actorstring
Only entries by this actor, exact match on the stored actor (an admin e-mail, or
token:<token name>). - targetstring
Only entries that name this id (person, device, app, connector, private network, rule, grant, session, token, …) — the "Activity" of one object. Up to 80 characters.
- sincestring (date-time)
Only entries at or after this time (ISO 8601, UTC).
- untilstring (date-time)
Only entries at or before this time (ISO 8601, UTC).
- actor_kindstring
Only actions by integrator staff (
partner) or by Cloudraw support (cloudraw_support). - partner_idstring
Everything about one integrator: its staff's actions and its access link events.
- support_grantstring
Every entry of one Cloudraw support access grant (request, decision, actions under it, end).
- limitinteger
Page size.
- cursorstring
Pass back
next_cursorfrom the previous page, unchanged. Omit for the first page.
Responses
200 NDJSON file: one AuditEntry per line. Empty file when nothing matches.
application/x-ndjson
400 invalid-limit invalid-cursor invalid-partner-id invalid-actor-kind invalid-support-grant
invalid-limit: limit is not an integer from 1 to 10000.
invalid-cursor: cursor is not a next_cursor from this API.
invalid-partner-id: partner_id is not an integrator id.
invalid-actor-kind: actor_kind is not partner or cloudraw_support.
invalid-support-grant: support_grant is not a support grant id.
401 unauthorized invalid-token token-expired
unauthorized: No Authorization: Bearer crw_… header was sent.
invalid-token: The token is unknown or was revoked.
token-expired: The token is past its expiry date. Create a new one.
403 insufficient-role tenant-assertion-mismatch
insufficient-role: The token's role ceiling does not allow this call.
tenant-assertion-mismatch: The token belongs to another workspace than {tenant_id}.
404 tenant-not-found
tenant-not-found: No workspace with this id.
429 rate-limited
rate-limited: More than 10 exports in the last hour by this admin or token. Wait Retry-After seconds.
503 audit-unavailable
audit-unavailable: The audit log cannot be read right now. Retry shortly.
curl -sS -X GET "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/audit/export" \
-H "Authorization: Bearer $CLOUDRAW_TOKEN"$headers = @{ Authorization = "Bearer $env:CLOUDRAW_TOKEN" }
Invoke-RestMethod -Method Get -Uri "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/audit/export" -Headers $headersimport os, uuid, requests
r = requests.get(
"https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/audit/export",
headers={"Authorization": f"Bearer {os.environ['CLOUDRAW_TOKEN']}"},
timeout=30,
)
r.raise_for_status()
print(r.json())const res = await fetch("https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/audit/export", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.CLOUDRAW_TOKEN}`,
},
});
if (!res.ok) throw new Error((await res.json()).code);
console.log(await res.json());{"at":"2026-10-13T09:24:11.000Z","tseq":1842,"action":"device.quarantine","tenant":"tq7x2m9k4ab","actor":"dana.levi@example.com","actor_role":"security_admin","via":"panel","ip":"203.0.113.24","req_id":"req_8k2x0m9s1d4f","device":"dvc_5mxq2b7r8k","reason":"Suspicious sign-in","sessions_cut":1,"sessions_failed":0,"alg":"hmac","hash":"6f1c2a9e0b4d7f38a5c1e2d9b0f4a7c3e8d1b6f2a9c0e7d4b3f8a1c6e2d9b0f4"}
{"at":"2026-10-13T09:20:02.000Z","tseq":1841,"action":"person.invite","tenant":"tq7x2m9k4ab","actor":"token:hr-sync","actor_role":"owner","via":"api","ip":"198.51.100.7","req_id":"req_2m0x9k8s1d3a","person":"p4hd8s0qk2l","alg":"hmac","hash":"a0c4e8f2b6d1937c5e0a8f4b2d6c1e9a7f3b5d0c8e2a6f4b1d9c7e3a5f0b8d2c"}
Verify the audit log
GET/v0/tenants/{tenant_id}/audit/verify
Re-checks the tamper-evident hash chain the audit log is written in and tells you whether it is intact. Each entry's hash covers its content and the previous entry, so any edit, reordering or deletion breaks the chain. You get your workspace's entry count and highest tseq: if your stored copy has every number from 1 to tenant_seq_head, you have the complete log. A break is never repaired silently — Cloudraw operations is alerted and the break stays on record.
Token: read-only or full access · Created by: owner or security admin
Path parameters
- tenant_idstringrequired
Your workspace id (Settings → Workspace in the console; it is also in every console URL).
Responses
200 The verdict.
application/json
- okbooleanrequired
true = every entry of the audit chain verified, yours included; false = an unexplained break was found (Cloudraw operations is alerted).
- tenant_entriesintegerrequired
How many audit entries your workspace has.
- tenant_seq_headinteger
The highest
tseqin your workspace. With gap-free numbering this equalstenant_entries; compare it with the entries you have stored. - verified_atstring (date-time)required
- detailstringrequired
One-sentence verdict.
401 unauthorized invalid-token token-expired
unauthorized: No Authorization: Bearer crw_… header was sent.
invalid-token: The token is unknown or was revoked.
token-expired: The token is past its expiry date. Create a new one.
403 insufficient-role tenant-assertion-mismatch
insufficient-role: The token's role ceiling does not allow this call.
tenant-assertion-mismatch: The token belongs to another workspace than {tenant_id}.
404 tenant-not-found
tenant-not-found: No workspace with this id.
503 audit-unavailable
audit-unavailable: The audit log cannot be read right now. Retry shortly.
curl -sS -X GET "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/audit/verify" \
-H "Authorization: Bearer $CLOUDRAW_TOKEN"$headers = @{ Authorization = "Bearer $env:CLOUDRAW_TOKEN" }
Invoke-RestMethod -Method Get -Uri "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/audit/verify" -Headers $headersimport os, uuid, requests
r = requests.get(
"https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/audit/verify",
headers={"Authorization": f"Bearer {os.environ['CLOUDRAW_TOKEN']}"},
timeout=30,
)
r.raise_for_status()
print(r.json())const res = await fetch("https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/audit/verify", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.CLOUDRAW_TOKEN}`,
},
});
if (!res.ok) throw new Error((await res.json()).code);
console.log(await res.json());{
"ok": true,
"tenant_entries": 1842,
"tenant_seq_head": 1842,
"verified_at": "2026-10-13T09:24:11.000Z",
"detail": "Every entry in the platform audit chain verified; your entries are part of it."
}