Home
Home/Developers/Audit logs/Exporting events
Ed25519 signaturesSHA-256 hashes8 SDKs
Status
Sign inStart free
Home
Start here
Overview
Authentication
Errors
FAQ
API
Events
Canonical JSON and hashes
Documents
Anchoring a file
AI attestations
Attestation schema
Verifying attestations
Traces
Sealing a trace
Audit logs
Organizations
Streams
Portal
Public proof
Event schema
Exporting events
Integrations
Clerk
Auth0
Embeddable viewer
All endpoints
Reference
SDKs
Node.js
Python
Go
Java
Ruby
Rust
.NET
PHP
REST
Verification
Docs · Audit logs

Exporting events

An export writes one org's events, cold storage included, to one CSV or NDJSON file in seq order. The download URL lasts 24 hours.

Create an exportStream instead
sha-256 · 3a352297…2592
sha-256 · e51db071…5f1f

List and get only read the hot log, which holds events for the plan's hot window. An export also reads cold storage, so an old range comes back whole.

Exports run in the background. You create a job, poll it, then fetch the file from a presigned URL. The filters are the ones list accepts.

Pick NDJSON when a program will read the file or verify it. Pick CSV for a spreadsheet; its rows carry the hash and signature but not every signed field.

Scopeaudit:read
Formatscsv or ndjson
Filtersactions, actor_id, target_id, occurred_after, occurred_before
Orderseq ascending: cold storage segments first, then the hot log
Workerpicks up pending jobs about every 10 seconds
Download URLpresigned for 24 hours from each GET
Content-Typetext/csv or application/x-ndjson
Flow
  1. Create

    POST /v1/audit/exports with organization_id, format and optional filters. The reply is 202 with the aexp_ id and status pending.

  2. Poll

    GET /v1/audit/exports/{id} until status is ready or failed. It goes pending, running, then ready or failed; error holds the failure message.

  3. Download

    GET download_url within 24 hours. Each poll presigns a fresh URL, so call again if the link expired.

EndpointsFields, errors and samples
POST/v1/audit/exportsCreate an exportGET/v1/audit/exports/{id}Get an export
File formats

NDJSON

One event per line, the same JSON that get returns, in seq order. The file ends in .ndjson and is served as application/x-ndjson.

export.ndjson · one line
{"id":"aevt_01J0Y1Z2A3B4C5D6E7F8G9H0JK","org_id":"aorg_01J0XW9K3RQ5T7V8Y2C4E6G8HM","seq":42,"schema_id":"invoance.audit/1","occurred_at":"2026-09-22T08:14:07.000Z","ingested_at":"2026-09-22T08:14:07.312Z","action":"user.signed_in","actor":{"type":"user","id":"u_4821","name":"Ada Lovelace"},"targets":[{"type":"workspace","id":"ws_17"}],"context":{"location":"203.0.113.10","user_agent":"Mozilla/5.0"},"metadata":{"method":"sso","mfa":true},"payload_hash":"df929158c7ce2107eff769fbcd58376c1d84dee0b5212b314f6f423dd20534d3","signature":"c6a2bf3bc3895915ead5f0b99eaf84534d4e8b9aa68bef8b0508cfd473f06e694d76d2bc330b83cfa613e49e7d2490d0413285017acfb78746bcc1524d05160d","signing_public_key":"bee215a9d2a0170176a88733056d8a0ae5372b0da8238796bef4a0b75d4c0974"}

CSV

A header row and one row per event. targets holds type:id pairs joined by a bar. A cell that starts with =, +, -, @, tab or carriage return gets a leading quote, so a spreadsheet shows it as text.

export.csv · header and one row
id,seq,occurred_at,ingested_at,action,actor_type,actor_id,actor_name,targets,context_location,payload_hash,signature
aevt_01J0Y1Z2A3B4C5D6E7F8G9H0JK,42,2026-09-22T08:14:07.000Z,2026-09-22T08:14:07.312Z,user.signed_in,user,u_4821,Ada Lovelace,workspace:ws_17,203.0.113.10,df929158c7ce2107eff769fbcd58376c1d84dee0b5212b314f6f423dd20534d3,c6a2bf3bc3895915ead5f0b99eaf84534d4e8b9aa68bef8b0508cfd473f06e694d76d2bc330b83cfa613e49e7d2490d0413285017acfb78746bcc1524d05160d

Not in the CSV: org_id, context.user_agent, metadata, target names and metadata, signing_public_key. A CSV row cannot be verified offline.

Verify an export offline

Each NDJSON line is a complete event. The SDK verifiers rebuild its canonical bytes and check payload_hash and the Ed25519 signature, with no network call.

By default they use the signing_public_key on the line. Pass your registered key from GET /keys/{domain} to pin it, which is what the server does.

Without an SDK, POST each line to /v1/proof/audit/{event_id}/verify; it needs no API key.

Node.jsimport { verifyAuditEvent } from "invoance"
Pythonfrom invoance import verify_audit_event
Goinvoance.VerifyAuditEvent
Javacom.invoance.AuditVerify.verifyAuditEvent
RubyInvoance::AuditVerify.verify_audit_event
Rustinvoance::verify_audit_event
.NETInvoance.Internal.AuditVerify.VerifyAuditEvent
PHPInvoance\AuditVerify::verifyAuditEvent
import { createReadStream } from "node:fs";
import { createInterface } from "node:readline";
import { verifyAuditEvent } from "invoance";

// Your registered key from GET /keys/{domain}, as hex. Leave it unset to
// check against the signing_public_key carried on each line.
const publicKey = process.env.INVOANCE_PUBLIC_KEY;

let valid = 0;
let invalid = 0;
const lines = createInterface({ input: createReadStream("export.ndjson") });
for await (const line of lines) {
  if (!line) continue;
  const event = JSON.parse(line);
  const result = verifyAuditEvent(event, { publicKey });
  if (result.valid) {
    valid += 1;
  } else {
    invalid += 1;
    console.log(event.id, result.reason);
  }
}
console.log("valid", valid, "invalid", invalid);
Questions
Export or stream?
A stream posts new events to your webhook as they are signed, in seq batches of up to 100. An export is a one-off file of a range or of everything.
How long does an export take?
A worker claims the job within about 10 seconds and writes the file in one pass. Poll until status is ready or failed.
Why did my export fail?
A malformed timestamp in filters is accepted at create time and fails the job later. The error field holds up to 500 characters of the cause.
Is a filtered export contiguous?
No, filters skip seq values by design. An unfiltered export lists every retained event in seq order, cold storage included.
Can I export an archived org?
No. Create returns 409 org_archived. Exports made before the org was archived stay available.

Proof infrastructure. Records are hashed, signed with your organization's Ed25519 key, and stored append-only, so anyone can check them later.

Products

  • Audit Logs
  • Event Ledger
  • AI Attestation
  • Document Anchoring
  • Traces

Developers

  • Documentation
  • API reference
  • SDKs
  • How it works
  • How traces seal
  • System status

Verify

  • Audit Log
  • Event
  • AI Attestation
  • Document
  • Trace

Company

  • Company overview
  • What is Invoance
  • Pricing
  • Security
  • Compliance teams
  • Finance teams
  • Partners
  • Resources
  • Help center
  • Contact
© 2025 – 2026 Invoance, Inc. All rights reserved.© 2026 Invoance, Inc. All rights reserved.
PrivacyLegal noticeLegal FAQ