Home
Home/Developers/Audit logs/Organizations
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
API · Audit Logs

Audit organizations

One audit org per end customer: create it, list it, archive it, set its retention and check its sequence for gaps.

Audit Logs overview
sha-256 · 3a352297…2592
sha-256 · bae251a9…8ffa
On this page
POST/v1/audit/orgsCreate an audit orgGET/v1/audit/orgsList audit orgsPATCH/v1/audit/orgs/{id}Rename an audit orgDELETE/v1/audit/orgs/{id}Delete an audit orgPOST/v1/audit/orgs/{id}/archiveArchive an audit orgPOST/v1/audit/orgs/{id}/unarchiveUnarchive an audit orgGET/v1/audit/orgs/{id}/integrityCheck an org's sequence integrityPUT/v1/audit/orgs/{id}/retentionSet an org's retention
Endpoints
POST/v1/audit/orgs
API keyaudit:write

Create an audit org

Registers one end-customer org under your own organization_id and returns its aorg_ id and starting retention.

Headers
Content-Typestring · required

Must be application/json.

Request body
organization_idstring · required · 1 to 255 characters after trimming

Your own id for the end customer; unique per tenant and used in every later call. external_id is accepted as a legacy alias.

namestring · up to 255 characters

Display name for the org; trimmed before storage.

  • The org and its seq counter are created in one transaction; ingest for the org works as soon as the 201 returns.
  • Unknown body keys and wrong types are rejected by the framework before the handler runs, with a plain-text 4xx rather than a JSON error body.
  • The org count is read before the insert, so two concurrent creates at the cap can both succeed.
Node.js
import { InvoanceClient } from "invoance";

// Reads INVOANCE_API_KEY from the environment.
const client = new InvoanceClient();

const org = await client.audit.orgs.create({
  organizationId: "org_8472",
  name: "Acme Robotics",
});
console.log(org.id, org.retention_days);
Response · 201
{
  "id": "aorg_01J0XW9K3RQ5T7V8Y2C4E6G8HM",
  "organization_id": "org_8472",
  "external_id": "org_8472",
  "name": "Acme Robotics",
  "retention_days": 90,
  "archived_at": null
}
Response fields
idstring

Internal org id, aorg_ followed by a ULID; accepted wherever an org id is expected.

organization_idstring

Your own id for the end customer, as given at create time.

external_idstring

Same value as organization_id, kept for older clients.

namestring

Display name, or null when none is set.

retention_daysinteger

Starting retention: 90 days, or the plan's retention cap when that is lower.

archived_attimestamp (ISO 8601)

When the org was archived, or null while it is active.

Errors
invalid_organization_id400

organization_id is empty after trimming or longer than 255 characters.

invalid_name400

name is longer than 255 characters.

insufficient_scope403

The key does not have audit:write; audit:read alone is not enough.

too_many_orgs403

The tenant already has as many audit orgs as its plan allows.

org_exists409

An org with this organization_id already exists for the tenant.

rate_limited429

The tenant used up its per-second or per-minute request budget; the Retry-After header says when to retry.

db_error500

A database query failed.

missing_api_key401

Neither an Authorization header nor an X-API-Key header was sent.

invalid_authorization_scheme401

An Authorization header was sent without the Bearer scheme.

invalid_api_key_format401

The key does not start with invoance_live_.

invalid_api_key401

The key does not match any API key.

api_key_revoked401

The key has been revoked.

ip_not_allowed403

The key has an IP allowlist and the caller's address is not on it.

api_key_lookup_failed500

The key could not be looked up in the database.

GET/v1/audit/orgs
API keyaudit:read

List audit orgs

Returns up to 100 of the tenant's audit orgs, newest first, hiding archived orgs unless asked.

Query parameters
include_archivedboolean · default false

Set to true to include orgs whose archived_at is set.

  • There is no pagination; the list is capped at 100 rows.
  • The Python SDK sends include_archived=true only when the flag is set; the Go SDK omits the parameter entirely when false.
Node.js
import { InvoanceClient } from "invoance";

// Reads INVOANCE_API_KEY from the environment.
const client = new InvoanceClient();

const result = await client.audit.orgs.list({ includeArchived: true });
for (const org of result.orgs as Array<Record<string, unknown>>) {
  console.log(org.id, org.organization_id, org.archived_at);
}
Response · 200
{
  "orgs": [
    {
      "id": "aorg_01J0XW9K3RQ5T7V8Y2C4E6G8HM",
      "organization_id": "org_8472",
      "external_id": "org_8472",
      "name": "Acme Robotics",
      "retention_days": 90,
      "created_at": "2026-09-22T08:10:00.418212+00:00",
      "archived_at": null
    }
  ]
}
Response fields
orgsobject[]

The orgs, ordered by created_at descending.

orgs[].idstring

Internal org id, aorg_ followed by a ULID; accepted wherever an org id is expected.

orgs[].organization_idstring

Your own id for the end customer, as given at create time.

orgs[].external_idstring

Same value as organization_id, kept for older clients.

orgs[].namestring

Display name, or null when none is set.

orgs[].retention_daysinteger

How many days the org's events are kept (hot plus cold) before they are purged.

orgs[].created_attimestamp (ISO 8601)

When the org was created, written with a +00:00 offset.

orgs[].archived_attimestamp (ISO 8601)

When the org was archived, or null while it is active.

Errors
insufficient_scope403

The key has neither audit:read nor audit:write; a ledger key with only read or write is rejected on audit routes.

rate_limited429

The tenant used up its per-second or per-minute request budget; the Retry-After header says when to retry.

db_error500

A database query failed.

missing_api_key401

Neither an Authorization header nor an X-API-Key header was sent.

invalid_authorization_scheme401

An Authorization header was sent without the Bearer scheme.

invalid_api_key_format401

The key does not start with invoance_live_.

invalid_api_key401

The key does not match any API key.

api_key_revoked401

The key has been revoked.

ip_not_allowed403

The key has an IP allowlist and the caller's address is not on it.

api_key_lookup_failed500

The key could not be looked up in the database.

PATCH/v1/audit/orgs/{id}
API keyaudit:write

Rename an audit org

Sets, changes or clears the org's display name and returns the updated org.

Headers
Content-Typestring · required

Must be application/json.

Path parameters
idstring · required

The aorg_ id or your organization_id; both resolve to the same org, scoped to your tenant.

Request body
namestring · required · up to 255 characters

The new display name; JSON null, an empty string or whitespace clears it. The key must be present.

  • The name is display only; events reference the org by id, so renaming never touches signed data.
  • Renaming works on archived orgs too.
  • The Java SDK's builder refuses to build unless name(...) or clearName() was called, and clearName() sends name null; the .NET SDK always sends the name key, so a null Name clears it.
  • The verb is PATCH; a PUT to this path is not routed.
Node.js
import { InvoanceClient } from "invoance";

// Reads INVOANCE_API_KEY from the environment.
const client = new InvoanceClient();

const org = await client.audit.orgs.update("org_8472", { name: "Acme Robotics Ltd" });
console.log(org.name);

// Pass null to clear the name.
await client.audit.orgs.update("org_8472", { name: null });
Response · 200
{
  "id": "aorg_01J0XW9K3RQ5T7V8Y2C4E6G8HM",
  "organization_id": "org_8472",
  "external_id": "org_8472",
  "name": "Acme Robotics Ltd",
  "retention_days": 90,
  "created_at": "2026-09-22T08:10:00.418212+00:00",
  "archived_at": null
}
Response fields
idstring

Internal org id, aorg_ followed by a ULID; accepted wherever an org id is expected.

organization_idstring

Your own id for the end customer, as given at create time.

external_idstring

Same value as organization_id, kept for older clients.

namestring

Display name, or null when none is set.

retention_daysinteger

How many days the org's events are kept (hot plus cold) before they are purged.

created_attimestamp (ISO 8601)

When the org was created, written with a +00:00 offset.

archived_attimestamp (ISO 8601)

When the org was archived, or null while it is active.

Errors
nothing_to_update400

The body has no name key.

invalid_name400

name is longer than 255 characters.

insufficient_scope403

The key does not have audit:write; audit:read alone is not enough.

not_found404

No audit org with that id or organization_id belongs to the tenant.

rate_limited429

The tenant used up its per-second or per-minute request budget; the Retry-After header says when to retry.

db_error500

A database query failed.

missing_api_key401

Neither an Authorization header nor an X-API-Key header was sent.

invalid_authorization_scheme401

An Authorization header was sent without the Bearer scheme.

invalid_api_key_format401

The key does not start with invoance_live_.

invalid_api_key401

The key does not match any API key.

api_key_revoked401

The key has been revoked.

ip_not_allowed403

The key has an IP allowlist and the caller's address is not on it.

api_key_lookup_failed500

The key could not be looked up in the database.

DELETE/v1/audit/orgs/{id}
API keyaudit:write

Delete an audit org

Removes an org only when doing so destroys no signed history, and returns the deleted id.

Path parameters
idstring · required

The aorg_ id or your organization_id; both resolve to the same org, scoped to your tenant.

  • Deletion is allowed in two cases: the org never had an event signed (seq counter at 0 and no accepted event in the last 24 hours), or it is archived and retention has purged every row and cold segment.
  • For an org with history the path is archive, wait for retention_days to elapse, then delete; the three 409 messages say which condition blocks the call.
  • Streams, portal sessions and export rows of the org are removed with it, and the export files are deleted from storage afterwards on a best-effort basis.
Node.js
import { InvoanceClient } from "invoance";

// Reads INVOANCE_API_KEY from the environment.
const client = new InvoanceClient();

const result = await client.audit.orgs.delete("org_8472");
console.log(result.deleted, result.id);
Response · 200
{
  "deleted": true,
  "id": "aorg_01J0XW9K3RQ5T7V8Y2C4E6G8HM"
}
Response fields
deletedboolean

Always true on success.

idstring

The aorg_ id that was deleted.

Errors
insufficient_scope403

The key does not have audit:write; audit:read alone is not enough.

not_found404

No audit org with that id or organization_id belongs to the tenant.

org_not_deletable409

The org has signed history and is not archived; it is archived but live rows or cold segments remain; or an event was accepted for it within the last 24 hours and may still be queued for signing.

rate_limited429

The tenant used up its per-second or per-minute request budget; the Retry-After header says when to retry.

db_error500

A database query failed.

missing_api_key401

Neither an Authorization header nor an X-API-Key header was sent.

invalid_authorization_scheme401

An Authorization header was sent without the Bearer scheme.

invalid_api_key_format401

The key does not start with invoance_live_.

invalid_api_key401

The key does not match any API key.

api_key_revoked401

The key has been revoked.

ip_not_allowed403

The key has an IP allowlist and the caller's address is not on it.

api_key_lookup_failed500

The key could not be looked up in the database.

POST/v1/audit/orgs/{id}/archive
API keyaudit:write

Archive an audit org

Marks the org archived so it accepts no new events, streams, portal links or exports, while its history stays readable and verifiable.

Path parameters
idstring · required

The aorg_ id or your organization_id; both resolve to the same org, scoped to your tenant.

  • Archiving is idempotent; a second call keeps the original archived_at.
  • While archived: ingest returns 409 org_archived, stream create and test return 409, portal sessions and exports return 409; list, get, verify, integrity, rename and retention keep working.
  • A portal session minted just before archiving stays valid until it expires; the viewer sees archived_at on GET /v1/audit/portal/org.
Node.js
import { InvoanceClient } from "invoance";

// Reads INVOANCE_API_KEY from the environment.
const client = new InvoanceClient();

const org = await client.audit.orgs.archive("org_8472");
console.log(org.archived_at);
Response · 200
{
  "id": "aorg_01J0XW9K3RQ5T7V8Y2C4E6G8HM",
  "organization_id": "org_8472",
  "external_id": "org_8472",
  "name": "Acme Robotics",
  "retention_days": 90,
  "created_at": "2026-09-22T08:10:00.418212+00:00",
  "archived_at": "2026-09-22T09:02:11.507314+00:00"
}
Response fields
idstring

Internal org id, aorg_ followed by a ULID; accepted wherever an org id is expected.

organization_idstring

Your own id for the end customer, as given at create time.

external_idstring

Same value as organization_id, kept for older clients.

namestring

Display name, or null when none is set.

retention_daysinteger

How many days the org's events are kept (hot plus cold) before they are purged.

created_attimestamp (ISO 8601)

When the org was created, written with a +00:00 offset.

archived_attimestamp (ISO 8601)

When the org was archived, or null while it is active.

Errors
insufficient_scope403

The key does not have audit:write; audit:read alone is not enough.

not_found404

No audit org with that id or organization_id belongs to the tenant.

rate_limited429

The tenant used up its per-second or per-minute request budget; the Retry-After header says when to retry.

db_error500

A database query failed.

missing_api_key401

Neither an Authorization header nor an X-API-Key header was sent.

invalid_authorization_scheme401

An Authorization header was sent without the Bearer scheme.

invalid_api_key_format401

The key does not start with invoance_live_.

invalid_api_key401

The key does not match any API key.

api_key_revoked401

The key has been revoked.

ip_not_allowed403

The key has an IP allowlist and the caller's address is not on it.

api_key_lookup_failed500

The key could not be looked up in the database.

POST/v1/audit/orgs/{id}/unarchive
API keyaudit:write

Unarchive an audit org

Clears archived_at so the org accepts writes again, and returns the org.

Path parameters
idstring · required

The aorg_ id or your organization_id; both resolve to the same org, scoped to your tenant.

  • Unarchiving is idempotent; calling it on an active org returns the org unchanged.
Node.js
import { InvoanceClient } from "invoance";

// Reads INVOANCE_API_KEY from the environment.
const client = new InvoanceClient();

const org = await client.audit.orgs.unarchive("org_8472");
console.log(org.archived_at);
Response · 200
{
  "id": "aorg_01J0XW9K3RQ5T7V8Y2C4E6G8HM",
  "organization_id": "org_8472",
  "external_id": "org_8472",
  "name": "Acme Robotics",
  "retention_days": 90,
  "created_at": "2026-09-22T08:10:00.418212+00:00",
  "archived_at": null
}
Response fields
idstring

Internal org id, aorg_ followed by a ULID; accepted wherever an org id is expected.

organization_idstring

Your own id for the end customer, as given at create time.

external_idstring

Same value as organization_id, kept for older clients.

namestring

Display name, or null when none is set.

retention_daysinteger

How many days the org's events are kept (hot plus cold) before they are purged.

created_attimestamp (ISO 8601)

When the org was created, written with a +00:00 offset.

archived_attimestamp (ISO 8601)

When the org was archived, or null while it is active.

Errors
insufficient_scope403

The key does not have audit:write; audit:read alone is not enough.

not_found404

No audit org with that id or organization_id belongs to the tenant.

rate_limited429

The tenant used up its per-second or per-minute request budget; the Retry-After header says when to retry.

db_error500

A database query failed.

missing_api_key401

Neither an Authorization header nor an X-API-Key header was sent.

invalid_authorization_scheme401

An Authorization header was sent without the Bearer scheme.

invalid_api_key_format401

The key does not start with invoance_live_.

invalid_api_key401

The key does not match any API key.

api_key_revoked401

The key has been revoked.

ip_not_allowed403

The key has an IP allowlist and the caller's address is not on it.

api_key_lookup_failed500

The key could not be looked up in the database.

GET/v1/audit/orgs/{id}/integrity
API keyaudit:read

Check an org's sequence integrity

Scans the org's hot log for missing seq values between the retention floor and the high-water mark and reports every gap.

Path parameters
idstring · required

The aorg_ id or your organization_id; both resolve to the same org, scoped to your tenant.

Query parameters
frominteger · default evacuated_through_seq + 1

First seq to check; raised to 1 and to evacuated_through_seq + 1 when lower.

tointeger · default last_seq

Last seq to check; lowered to last_seq when higher.

  • seq is assigned in commit order with no gaps, so a missing value between the floor and last_seq means a row was removed from the hot log.
  • The scan cannot detect removal of the newest rows if the org's counter was also rolled back; the note field says so on every response.
  • When last_seq is 0 or the clamped range is empty, the response has count 0, expected 0, contiguous true, an empty gaps array and no gaps_truncated key.
  • The SDKs call this without from or to; pass them with a raw HTTP call when you need a sub-range.
Node.js
import { InvoanceClient } from "invoance";

// Reads INVOANCE_API_KEY from the environment.
const client = new InvoanceClient();

const report = await client.audit.orgs.integrity("org_8472");
console.log(report.contiguous, report.count, report.expected, report.gaps);
Response · 200
{
  "org_id": "aorg_01J0XW9K3RQ5T7V8Y2C4E6G8HM",
  "from": 1,
  "to": 42,
  "last_seq": 42,
  "evacuated_through_seq": 0,
  "count": 42,
  "expected": 42,
  "contiguous": true,
  "gaps": [],
  "gaps_truncated": false,
  "note": "A hole below the high-water mark proves deletion. An attacker who also resets the per-org seq counter can hide truncation of the newest events; only the Tier-3 signed checkpoint closes that. Integrity is 'Signed', not 'complete', until it ships."
}
Response fields
org_idstring

The aorg_ id that was scanned.

frominteger

First seq actually checked, after clamping.

tointeger

Last seq actually checked, after clamping.

last_seqinteger

The org's high-water mark: the last seq the signer assigned.

evacuated_through_seqinteger

The retention floor; seq values at or below it were moved to cold storage or purged and are not counted as gaps.

countinteger

Rows found in the checked range.

expectedinteger

to - from + 1, the number of rows a complete range would hold.

contiguousboolean

True when gaps is empty.

gapsobject[]

Missing ranges in ascending order.

gaps[].startinteger

First missing seq of the range.

gaps[].endinteger

Last missing seq of the range.

gaps[].lengthinteger

end - start + 1.

gaps_truncatedboolean

True when 1,000 gap ranges were found and the scan stopped; omitted when the range was empty.

notestring

Fixed text describing what the scan can and cannot detect.

Errors
insufficient_scope403

The key has neither audit:read nor audit:write; a ledger key with only read or write is rejected on audit routes.

not_found404

No audit org with that id or organization_id belongs to the tenant.

rate_limited429

The tenant used up its per-second or per-minute request budget; the Retry-After header says when to retry.

db_error500

A database query failed.

missing_api_key401

Neither an Authorization header nor an X-API-Key header was sent.

invalid_authorization_scheme401

An Authorization header was sent without the Bearer scheme.

invalid_api_key_format401

The key does not start with invoance_live_.

invalid_api_key401

The key does not match any API key.

api_key_revoked401

The key has been revoked.

ip_not_allowed403

The key has an IP allowlist and the caller's address is not on it.

api_key_lookup_failed500

The key could not be looked up in the database.

PUT/v1/audit/orgs/{id}/retention
API keyaudit:write

Set an org's retention

Sets how many days the org's events are kept before purge, clamped to the plan's cap, and reports the value applied.

Headers
Content-Typestring · required

Must be application/json.

Path parameters
idstring · required

The aorg_ id or your organization_id; both resolve to the same org, scoped to your tenant.

Request body
daysinteger · required · 1 or more; values above the plan cap are lowered to the cap

Requested retention in days, hot and cold storage combined.

  • Retention counts from ingested_at; rows older than the plan's hot window move to cold storage, and rows older than retention_days are purged by a nightly worker.
  • The hot window is set by the plan and cannot be changed here.
  • Lowering retention below the age of existing rows lets the next retention run purge them.
Node.js
import { InvoanceClient } from "invoance";

// Reads INVOANCE_API_KEY from the environment.
const client = new InvoanceClient();

const result = await client.audit.orgs.setRetention("org_8472", 365);
console.log(result.retention_days, result.clamped, result.plan_cap_days);
Response · 200
{
  "org_id": "aorg_01J0XW9K3RQ5T7V8Y2C4E6G8HM",
  "retention_days": 365,
  "requested_days": 365,
  "clamped": false,
  "plan_cap_days": 365
}
Response fields
org_idstring

The aorg_ id that was updated.

retention_daysinteger

The value stored: min(days, plan_cap_days).

requested_daysinteger

The days value you sent.

clampedboolean

True when retention_days is lower than requested_days.

plan_cap_daysinteger

The tenant's cap: a per-tenant override when set, otherwise the plan's retention_days; 30 when neither can be read.

Errors
invalid_days400

days is less than 1.

insufficient_scope403

The key does not have audit:write; audit:read alone is not enough.

not_found404

No audit org with that id or organization_id belongs to the tenant.

rate_limited429

The tenant used up its per-second or per-minute request budget; the Retry-After header says when to retry.

db_error500

A database query failed.

missing_api_key401

Neither an Authorization header nor an X-API-Key header was sent.

invalid_authorization_scheme401

An Authorization header was sent without the Bearer scheme.

invalid_api_key_format401

The key does not start with invoance_live_.

invalid_api_key401

The key does not match any API key.

api_key_revoked401

The key has been revoked.

ip_not_allowed403

The key has an IP allowlist and the caller's address is not on it.

api_key_lookup_failed500

The key could not be looked up in the database.

Other audit logs endpointsOverview
EventsPOST/v1/audit/eventsIngest an audit eventGET/v1/audit/eventsList audit eventsGET/v1/audit/events/{id}Get an audit eventGET/v1/audit/events/{id}/verifyVerify an audit event
StreamsPOST/v1/audit/orgs/{id}/streamsCreate a webhook streamGET/v1/audit/orgs/{id}/streamsList an org's streamsDELETE/v1/audit/orgs/{id}/streams/{stream_id}Delete a streamPOST/v1/audit/orgs/{id}/streams/{stream_id}/testSend a test delivery
Portal sessionsPOST/v1/audit/portal_sessionsCreate a portal session
ExportsPOST/v1/audit/exportsCreate an exportGET/v1/audit/exports/{id}Get an export
Portal, with a portal tokenPOST/v1/audit/portal/exchangeExchange a portal link tokenGET/v1/audit/portal/eventsList events through the portalGET/v1/audit/portal/events/{id}Get an event through the portalGET/v1/audit/portal/events/{id}/verifyVerify an event through the portalGET/v1/audit/portal/orgGet the portal's org and issuerGET/v1/audit/portal/streamsList streams through the portalPOST/v1/audit/portal/streamsCreate a stream through the portalDELETE/v1/audit/portal/streams/{id}Delete a stream through the portalPOST/v1/audit/portal/streams/{id}/testTest a stream through the portal
Public proofGET/v1/proof/audit/{event_id}Get the public proof of an audit eventPOST/v1/proof/audit/{event_id}/verifyVerify a copy of an audit event

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
  • Brand assets
  • Resources
  • Help center
  • Contact
© 2025 – 2026 Invoance, Inc. All rights reserved.© 2026 Invoance, Inc. All rights reserved.
PrivacyLegal noticeLegal FAQ