AxioRankDocs

Audit log export

Pull redacted audit rows as NDJSON into your SIEM, or download CSV from the Logs page in one click.

Every gateway decision lands in your audit log. Getting it out has two surfaces:

SurfaceAuthFormatsDefault windowCap
GET /api/v1/audit/exportAPI key with logs:readNDJSONlast 24 hours5,000 rows per page, cursor to continue
Logs page download buttonsDashboard session, any member (viewer role and above)CSV or NDJSONlast 30 days50,000 rows

Both require the siemExport plan feature (Team and above; otherwise 403), and both serve the same rows. Payloads are redacted at write time, so nothing sensitive leaves through an export.

The dashboard download (/api/audit/export-download) accepts the same from / to / source / decision filters as the API and pages internally up to its cap. A capped file carries an x-axiorank-truncated: 50000 response header: narrow the window, or switch to the API endpoint for anything ongoing.

The endpoint

GET /api/v1/audit/export. The versioned path is canonical; unversioned /api/audit/export remains an alias (see Versioning & stability).

curl -s "https://app.axiorank.com/api/v1/audit/export?limit=1000" \
  -H "Authorization: Bearer axr_live_..."

Authenticate with a bearer API key carrying the logs:read scope. A missing or invalid key returns 401; a plan without siemExport returns 403.

Query parameters

ParamTypeDefaultNotes
fromISO 8601 timestamp24 hours agoStart of the window.
toISO 8601 timestampnowEnd of the window.
cursoropaque stringnoneThe previous page's x-axiorank-next-cursor value.
limitinteger, 1–50001000Rows per page.
sourcesdk | mcpallFilter by where the call entered.
decisionallow | deny | holdallFilter by gateway decision.

A bound that is present but unparseable, or a window where from is not before to, returns 400 { "error": "invalid from/to window" }. A malformed cursor returns 400 with invalid cursor; any other bad parameter (say, limit=0) returns 400 with invalid query.

Pagination

Pages are keyset-paginated on (created_at, id), so the cursor is stable under concurrent inserts (no skipped or doubled rows, unlike offset pagination). When a page comes back full, the response carries an x-axiorank-next-cursor header; pass it back as cursor for the next page. No header means you have everything.

BASE="https://app.axiorank.com/api/v1/audit/export"
QS="from=2026-06-01T00:00:00Z&to=2026-06-10T00:00:00Z&limit=1000"
CURSOR=""
while :; do
  HDRS=$(mktemp)
  curl -s -D "$HDRS" "$BASE?$QS${CURSOR:+&cursor=$CURSOR}" \
    -H "Authorization: Bearer $AXIORANK_API_KEY" >> audit.ndjson
  echo >> audit.ndjson   # pages have no trailing newline
  CURSOR=$(awk -F': ' 'tolower($1)=="x-axiorank-next-cursor"{gsub(/\r/,"",$2); print $2}' "$HDRS")
  [ -z "$CURSOR" ] && break
done

Persist your position

For a scheduled pull, store the last x-axiorank-next-cursor you saw (the final, partial page returns none, so also store the created_at of the last row you ingested). On the next run, resume from the cursor, or pass that timestamp as from, and dedupe on id downstream.

Formats

The API returns NDJSON (application/x-ndjson): one JSON object per line, each a full redacted audit row. NDJSON is what you want for SIEM pipelines; every field survives, including nested ones.

The dashboard's CSV stays flat so it opens cleanly in a spreadsheet, with these columns:

created_at, id, agent_id, tool_name, source, decision, risk_score,
reason, mcp_server_id, trace_id, step_index, taint_blocked, taint_tags

taint_tags is ;-joined. Cells are RFC 4180 quoted, and a leading =, +, -, or @ is prefixed with an apostrophe to defuse spreadsheet formula injection (tool names are agent-supplied, so treat them as untrusted).

SIEM ingestion

Splunk (HTTP Event Collector): wrap each NDJSON line in a HEC envelope.

curl -s "$BASE?$QS" -H "Authorization: Bearer $AXIORANK_API_KEY" |
while IFS= read -r line || [ -n "$line" ]; do   # `|| [ -n ... ]` keeps the last line (no trailing newline)
  curl -s "https://splunk.example.com:8088/services/collector/event" \
    -H "Authorization: Splunk $HEC_TOKEN" \
    -d "{\"sourcetype\":\"axiorank:audit\",\"event\":$line}"
done

Datadog (Logs API): batch a page per request.

curl -s "$BASE?$QS" -H "Authorization: Bearer $AXIORANK_API_KEY" \
  | jq -s 'map({ddsource: "axiorank", service: "audit"} + .)' \
  | curl -s -X POST "https://http-intake.logs.datadoghq.com/api/v2/logs" \
      -H "DD-API-KEY: $DD_API_KEY" -H "Content-Type: application/json" -d @-

Run either inside the cursor loop above on a schedule, persisting the cursor between runs.

Next steps

  • Webhooks: push instead of pull; react to events the moment they fire.
  • Audit integrity: the signed transparency log behind these rows.
  • Evidence bundle: an offline-verifiable export for auditors.

On this page