API reference
Log streaming
Stream the audit log and alerts to your SIEM.
List log streaming destinations
GET/v0/tenants/{tenant_id}/siem
Returns your SIEM / log destinations with their delivery status, plus the supported types, streams and setup guides. Secret settings are always masked.
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 destinations.
application/json
- itemsarray of SiemDestinationrequired
items fields
- idstringrequired
- typestringrequired
- configobjectrequired
The destination settings as saved. Secret fields (
hec_token,key,client_secret,access_key,secret_key,token…) are always returned as••••••••. - streamsarray of stringrequired
audit= the audit log;alerts= alerts and their triage changes. - statusstringrequired
configureduntil the first delivery;streamingafter a success;errorafter a failure. - created_atstring (date-time)required
- last_eventstring | null (date-time)
Last successful delivery.
- guideobject | null
Setup guide for this destination type (
id,section,title,url,pdf_url). - deliveryobject | null
Alerts stream queue:
queued,delivered,dropped,failing,attempt,next_retry_at,last_ok_at,last_error(or, after a test only,{at, ok, error}). Null before anything was queued. - audit_shippingobject | null
Audit stream progress:
cursorand, once shipping ran,failing,failing_since,next_retry_at,last_ok_at,last_error. Null when the destination does not take theauditstream.
- typesarray of stringrequired
Supported destination types.
- type_guidesobject
Setup guide per type (null when none).
- guideobject | null
The general log-streaming guide.
- streamsarray of stringrequired
- next_pagenull
Always null (at most 10 destinations).
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.
curl -sS -X GET "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/siem" \
-H "Authorization: Bearer $CLOUDRAW_TOKEN"$headers = @{ Authorization = "Bearer $env:CLOUDRAW_TOKEN" }
Invoke-RestMethod -Method Get -Uri "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/siem" -Headers $headersimport os, uuid, requests
r = requests.get(
"https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/siem",
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/siem", {
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": [
{
"id": "siem_2k9x0d8s1m",
"type": "splunk",
"config": {
"url": "https://splunk.example.com:8088/services/collector/event",
"hec_token": "••••••••",
"index": "cloudraw",
"sourcetype": null
},
"streams": [
"audit",
"alerts"
],
"status": "configured",
"created_at": "2026-10-13T09:24:11.000Z",
"last_event": null,
"guide": {
"id": "siem-splunk",
"section": null,
"title": "Stream logs to Splunk",
"url": "https://docs.example.com/guides/siem-splunk",
"pdf_url": null
},
"delivery": null,
"audit_shipping": {
"cursor": null
}
}
],
"types": [
"splunk",
"sentinel",
"datadog",
"s3",
"syslog",
"http"
],
"type_guides": {
"splunk": {
"id": "siem-splunk",
"section": null,
"title": "Stream logs to Splunk",
"url": "https://docs.example.com/guides/siem-splunk",
"pdf_url": null
}
},
"guide": null,
"streams": [
"audit",
"alerts"
],
"next_page": null
}Add a log streaming destination
POST/v0/tenants/{tenant_id}/siem
Starts streaming your audit log and/or alerts to a SIEM or log store. The audit stream starts from now (no history is back-filled), is delivered at least once in batches of up to 100, and survives outages: a failing destination is retried with backoff and you get an alert after 15 minutes of failures. At most 10 destinations. Secrets are encrypted at rest and never returned. Audited (without the secrets).
config by type (unknown keys are dropped): - splunk: url (HEC endpoint, https), hec_token; optional index, sourcetype. - datadog: key (API key); optional site (datadoghq.com default, us3.datadoghq.com, us5.datadoghq.com, datadoghq.eu, ap1.datadoghq.com, ap2.datadoghq.com, ddog-gov.com), service. - sentinel (Microsoft Sentinel / Azure Monitor Logs ingestion): tenant_id and client_id (GUIDs), client_secret, endpoint (https://….ingest.monitor.azure.com), dcr_immutable_id (dcr-<32 hex>), stream_name (Custom-<Table>). - s3: bucket (lowercase, no dots), region (like eu-central-1), access_key, secret_key; optional prefix. - syslog (RFC 5425 over TLS): host (public DNS name or IPv4), port (default 6514); optional ca_pem (a CA certificate for a private CA). - http: url (https); optional token (sent as a bearer token).
URLs must be public https endpoints on an allowed port (443, 8088, 8443).
Token: full access · Created by: owner
Idempotency: send Idempotency-Key to retry safely — the same key and body within 24 h returns the first answer.
Path parameters
- tenant_idstringrequired
Your workspace id (Settings → Workspace in the console; it is also in every console URL).
Headers
- Idempotency-Keystring
A unique value (e.g. a UUID) per logical operation. Retrying with the same key and body within 24 hours returns the first answer instead of doing the work twice.
Request body application/json
- typestringrequired
- configobjectrequired
Settings for the type (see above).
- streamsarray of string
Non-empty. Default: both.
Responses
201 The destination (secrets masked).
application/json
- idstringrequired
- typestringrequired
- configobjectrequired
The destination settings as saved. Secret fields (
hec_token,key,client_secret,access_key,secret_key,token…) are always returned as••••••••. - streamsarray of stringrequired
audit= the audit log;alerts= alerts and their triage changes. - statusstringrequired
configureduntil the first delivery;streamingafter a success;errorafter a failure. - created_atstring (date-time)required
- last_eventstring | null (date-time)
Last successful delivery.
- guideobject | null
Setup guide for this destination type (
id,section,title,url,pdf_url). - deliveryobject | null
Alerts stream queue:
queued,delivered,dropped,failing,attempt,next_retry_at,last_ok_at,last_error(or, after a test only,{at, ok, error}). Null before anything was queued. - audit_shippingobject | null
Audit stream progress:
cursorand, once shipping ran,failing,failing_since,next_retry_at,last_ok_at,last_error. Null when the destination does not take theauditstream.
400 invalid-type config-object-required invalid-streams invalid-siem-config
invalid-type: type is not a supported destination type.
config-object-required: config is not an object.
invalid-streams: streams is empty or contains something other than audit / alerts.
invalid-siem-config: A required setting is missing or invalid (URL not allowed, bad GUID, bucket name …); detail says which.
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-scope insufficient-role tenant-assertion-mismatch
insufficient-scope: The token is read-only and this call changes something.
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.
409 siem-destination-limit idempotency-key-reuse
siem-destination-limit: The workspace already has 10 destinations.
idempotency-key-reuse: The same Idempotency-Key was used with a different body within 24 hours.
503 secret-storage-unavailable busy
secret-storage-unavailable: Secrets cannot be stored safely right now. Retry later.
busy: Cloudraw is switching servers or cannot save right now. Retry after Retry-After seconds.
curl -sS -X POST "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/siem" \
-H "Authorization: Bearer $CLOUDRAW_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"type": "splunk",
"config": {
"url": "https://splunk.example.com:8088/services/collector/event",
"hec_token": "0f6c2b9e-4d1a-4c7e-9b8a-2e5d7f1c3a90",
"index": "cloudraw"
},
"streams": [
"audit",
"alerts"
]
}'$body = @'
{
"type": "splunk",
"config": {
"url": "https://splunk.example.com:8088/services/collector/event",
"hec_token": "0f6c2b9e-4d1a-4c7e-9b8a-2e5d7f1c3a90",
"index": "cloudraw"
},
"streams": [
"audit",
"alerts"
]
}
'@
$headers = @{ Authorization = "Bearer $env:CLOUDRAW_TOKEN"; "Idempotency-Key" = [guid]::NewGuid().ToString() }
Invoke-RestMethod -Method Post -Uri "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/siem" -Headers $headers -ContentType "application/json" -Body $bodyimport os, uuid, requests
r = requests.post(
"https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/siem",
headers={"Authorization": f"Bearer {os.environ['CLOUDRAW_TOKEN']}", "Idempotency-Key": str(uuid.uuid4())},
json={
"type": "splunk",
"config": {
"url": "https://splunk.example.com:8088/services/collector/event",
"hec_token": "0f6c2b9e-4d1a-4c7e-9b8a-2e5d7f1c3a90",
"index": "cloudraw"
},
"streams": [
"audit",
"alerts"
]
},
timeout=30,
)
r.raise_for_status()
print(r.json())const res = await fetch("https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/siem", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.CLOUDRAW_TOKEN}`,
"Idempotency-Key": crypto.randomUUID(),
"Content-Type": "application/json",
},
body: JSON.stringify({
"type": "splunk",
"config": {
"url": "https://splunk.example.com:8088/services/collector/event",
"hec_token": "0f6c2b9e-4d1a-4c7e-9b8a-2e5d7f1c3a90",
"index": "cloudraw"
},
"streams": [
"audit",
"alerts"
]
}),
});
if (!res.ok) throw new Error((await res.json()).code);
console.log(await res.json());{
"id": "siem_2k9x0d8s1m",
"type": "splunk",
"config": {
"url": "https://splunk.example.com:8088/services/collector/event",
"hec_token": "••••••••",
"index": "cloudraw",
"sourcetype": null
},
"streams": [
"audit",
"alerts"
],
"status": "configured",
"created_at": "2026-10-13T09:24:11.000Z",
"last_event": null,
"guide": {
"id": "siem-splunk",
"section": null,
"title": "Stream logs to Splunk",
"url": "https://docs.example.com/guides/siem-splunk",
"pdf_url": null
},
"delivery": null,
"audit_shipping": {
"cursor": null
}
}Remove a log streaming destination
DELETE/v0/tenants/{tenant_id}/siem/{destination_id}
Stops streaming to the destination at once (queued events for it are dropped) and deletes its stored credentials. Audited.
Token: full access · Created by: owner
Path parameters
- tenant_idstringrequired
Your workspace id (Settings → Workspace in the console; it is also in every console URL).
- destination_idstringrequired
Log streaming destination id.
Responses
202 Done (the task is already complete).
application/json
- idstringrequired
- tenant_idstring
- statestringrequired
- result_uristring | null
- errorobject | string | null
Why it failed, or a short status note (e.g.
revoke_pending).
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-scope insufficient-role tenant-assertion-mismatch
insufficient-scope: The token is read-only and this call changes something.
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 destination-not-found tenant-not-found
destination-not-found: No destination with this id.
tenant-not-found: No workspace with this id.
503 busy
busy: Cloudraw is switching servers or cannot save right now. Retry after Retry-After seconds.
curl -sS -X DELETE "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/siem/siem_2k9x0d8s1m" \
-H "Authorization: Bearer $CLOUDRAW_TOKEN"$headers = @{ Authorization = "Bearer $env:CLOUDRAW_TOKEN" }
Invoke-RestMethod -Method Delete -Uri "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/siem/siem_2k9x0d8s1m" -Headers $headersimport os, uuid, requests
r = requests.delete(
"https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/siem/siem_2k9x0d8s1m",
headers={"Authorization": f"Bearer {os.environ['CLOUDRAW_TOKEN']}"},
timeout=30,
)
r.raise_for_status()
print(r.status_code)const res = await fetch("https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/siem/siem_2k9x0d8s1m", {
method: "DELETE",
headers: {
Authorization: `Bearer ${process.env.CLOUDRAW_TOKEN}`,
},
});
if (!res.ok) throw new Error((await res.json()).code);
console.log(res.status);{
"id": "task_8s2k0x9m1d",
"tenant_id": "tq7x2m9k4ab",
"state": "done",
"result_uri": null,
"error": null
}Send a test event
POST/v0/tenants/{tenant_id}/siem/{destination_id}/test
Sends one test event (action siem.test) to the destination now and reports the answer — no retries. Sets the destination status to streaming or error. Audited.
Token: full access · Created by: owner
Rate limit: 10 test events per hour per destination.
Path parameters
- tenant_idstringrequired
Your workspace id (Settings → Workspace in the console; it is also in every console URL).
- destination_idstringrequired
Log streaming destination id.
Responses
200 The result.
application/json
- okbooleanrequired
- statusstringrequired
- errorstring | null
What the destination answered on failure.
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-scope insufficient-role tenant-assertion-mismatch
insufficient-scope: The token is read-only and this call changes something.
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 destination-not-found tenant-not-found
destination-not-found: No destination with this id.
tenant-not-found: No workspace with this id.
429 test-rate-limited
test-rate-limited: More than 10 test events for this destination this hour.
500 test-failed
test-failed: The test could not be sent; detail says why.
503 busy
busy: Cloudraw is switching servers or cannot save right now. Retry after Retry-After seconds.
curl -sS -X POST "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/siem/siem_2k9x0d8s1m/test" \
-H "Authorization: Bearer $CLOUDRAW_TOKEN"$headers = @{ Authorization = "Bearer $env:CLOUDRAW_TOKEN" }
Invoke-RestMethod -Method Post -Uri "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/siem/siem_2k9x0d8s1m/test" -Headers $headersimport os, uuid, requests
r = requests.post(
"https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/siem/siem_2k9x0d8s1m/test",
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/siem/siem_2k9x0d8s1m/test", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.CLOUDRAW_TOKEN}`,
},
});
if (!res.ok) throw new Error((await res.json()).code);
console.log(await res.json());{
"ok": true,
"status": "streaming",
"error": null
}