Home
Home/Developers/Audit logs/orgs
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 schemaVerifying attestations
Traces
Sealing a trace
Audit logs
OrganizationsStreamsPortalPublic proofEvent schemaExporting eventsIntegrationsEmbeddable viewer
All endpoints
Reference
SDKs
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

  • Why Invoance
  • Pricing
  • Security
  • Compliance teams
  • Finance teams
  • Partners
  • Resources
  • Help center
  • Contact
© 2026 Invoance
PrivacyLegal noticeLegal FAQGitHubLinkedInX