Invoance
Get a DemoLog InSign Up
Developers
Search docs…⌘K
Getting started
OverviewConceptsAuthenticationCreate an API key
API reference
EndpointsErrors
Audit Logs
Quick startIntegrationsEmbeddable viewerEvent schemaExporting eventsSDK reference
AI Attestations
Quick startAttestation schemaVerification & proofSDK reference
Events
OverviewSDK reference
Documents
OverviewSDK reference
Traces
OverviewSDK reference
SDKs
PythonNode.jsGoJavaRubyRust.NETPHPcURL
Verification
How it works
Support
API FAQ

Embeddable viewer

@invoance/audit-viewer puts the audit log inside your own product (say, admin.yourapp.com/audit): the same signed event table, filters, export, and in-browser Ed25519 tamper test as the hosted portal, rendered as a native React component in your DOM. No iframe, no styling conflicts, and the cryptographic verification runs in your customer's browser, so the proof never depends on trusting the page that renders it.

Signed event table

Actor, targets, action, and gap-free sequence numbers, with filters, keyset paging, CSV/JSON export, and 15-second live refresh.

In-browser tamper test

A detail drawer with the raw signed event: your customer edits any field and watches the Ed25519 verification flip from Authentic to Tampered.

Stream config screen

Mint the session with intent log_streams and the same component renders the SIEM webhook destination screen instead.

Before you begin

  • An API key with the audit scopes (create one) and at least one audit org receiving events.
  • React 18 or newer. The package has no other runtime dependencies.
  • No Tailwind required: the stylesheet ships compiled, prefixed, and themed by CSS variables.
1Install the package
npm install @invoance/audit-viewer
2Add a token endpoint to your backend

The component authenticates with a short-lived, org-scoped portal session that your backend mints for whichever of your customers is signed in. This is the one server-side piece.

The Invoance API key must never reach the browser. Mint server-side and return only the one-time token; it is useless for anything except opening this one organization's viewer.
// app/api/audit-portal-token/route.ts (Next.js example; any backend works)
import { InvoanceClient } from "invoance";

const client = new InvoanceClient({ apiKey: process.env.INVOANCE_API_KEY });

export async function POST() {
  const organizationId = await currentCustomerOrgId(); // however your app resolves it

  const session = await client.audit.portalSessions.create({
    organization_id: organizationId,
    intent: "audit_logs",
    session_duration_seconds: 3600,
  });

  return Response.json({ token: session.token });
}

Every SDK exposes the same call; in Python it is client.audit.portal_sessions.create(...). Keep session_duration_seconds short: the component re-mints through your endpoint automatically when it expires.

3Render the component
"use client";

import { AuditLogViewer } from "@invoance/audit-viewer";
import "@invoance/audit-viewer/styles.css";

export default function AuditPage() {
  return (
    <AuditLogViewer
      getPortalToken={async () => {
        const r = await fetch("/api/audit-portal-token", { method: "POST" });
        return (await r.json()).token;
      }}
    />
  );
}

getPortalToken is a callback, not a static prop, so expiry never strands the visitor. In the Next.js App Router the package already carries the "use client" banner, so you can import it from a server component tree. In Vite or CRA, mount it anywhere; only the fetch to your own token endpoint matters.

4Verify it works

Open the page as a signed-in customer. You should see their organization's events with your issuer branding in the header. Click any row and press Verify signature: the verdict should read Authentic. Now add a character to any field in the editor and verify again: it flips to Tampered, computed entirely in the browser. That is the demo worth showing your customers.

Props

PropDefaultWhat it does
getPortalToken-Async callback returning a fresh one-time portal token from your backend. Re-invoked automatically when the session expires.
tokenFromUrlfalseRead and strip a one-time ?token= from the page URL (hosted-page style).
persistSessionfalseCache the session JWT in sessionStorage so a refresh survives without a new token.
baseUrlhttps://api.invoance.comAPI origin; point it at a dev backend while developing.
pageSize25Initial rows per page (25, 50, or 100); the visitor can change it.
autoRefreshtrueQuietly re-pull page 1 every 15 seconds while idle.
theme-CSS-variable overrides, e.g. { variables: { background: "240 6% 12%" } }.
className-Extra class(es) on the root element.
onSessionExpired-Called when the session cannot be renewed.

Theming

Nine CSS variables (HSL triples, shadcn-style) drive every color. Override them on :root, on any ancestor of the viewer, or through the theme prop; bare names get the --inv- prefix automatically. A dark embed is three lines:

<AuditLogViewer
  getPortalToken={getPortalToken}
  theme={{ variables: { background: "240 6% 12%", foreground: "0 0% 98%", border: "240 6% 20%", muted: "240 5% 16%", popover: "240 6% 12%" } }}
/>
VariableDefault (light)
--inv-background0 0% 100%
--inv-foreground240 10% 8%
--inv-border240 6% 90%
--inv-muted240 4% 95%
--inv-popover0 0% 100%
--inv-popover-foreground240 10% 8%
--inv-success161 94% 30%
--inv-danger0 72% 51%
--inv-warning32 95% 44%

Sessions and failure modes

  • The exchanged JWT is org-scoped: it can only ever read the one organization the session was minted for. Portal traffic is rate-limited per visitor IP and never counts against your API budget.
  • On a 401 mid-session the component calls getPortalToken once and retries; if that fails it shows a clear expiry message and calls onSessionExpired.
  • A rate-limited exchange (many visitors behind one office NAT clicking at once) retries automatically honoring Retry-After; the one-time link is not consumed by a rate-limit rejection.
  • In browsers whose Web Crypto lacks Ed25519, the tamper test still checks the hash and reports the signature as not verifiable in this browser, distinct from a failed verification.
  • Events return context and metadata verbatim; whoever can render the embed can read them. Your tenant id is never exposed.

The mint endpoint is documented under Audit Logs endpoints, and the quick start covers sending the events the viewer displays. Source and issues: github.com/Invoance/invoance-audit-viewer.

01Audit logs02AI decisions03Documents04Business events05Whole workflows
Invoance

Neutral proof infrastructure for records that must survive scrutiny. Signed at creation. Verifiable outside your dashboard.

ALL SYSTEMS OPERATIONALEvidence infrastructure · Online

Build

  • Developer overview
  • API endpoints
  • Official SDKs
  • Authentication
  • Verification model

Use Invoance

  • Why Invoance
  • How it works
  • Compliance teams
  • Finance teams
  • Pricing

Verify

  • Audit log
  • AI attestation
  • Document
  • Ledger event
  • Sealed trace

Company

  • Help center
  • Resources
  • Security
  • Partners
  • Contact
  • System status
FIELD NOTES / 01Proof patterns for teams building trust.

Invoance provides cryptographic proof and verification infrastructure. It does not provide legal, financial, compliance, or regulatory advice.

Read proof disclaimer

Records anchored with Invoance are cryptographically signed and designed to reveal tampering. Invoance verifies that a specific record existed in a particular form at a particular time; it does not assess the record's accuracy, authenticity, legality, or underlying contents. Public verification links can be resolved without authentication. Invoance is not a custodian of funds, a legal authority, or a regulated financial institution. Using Invoance does not by itself satisfy any legal or regulatory requirement. Consult qualified legal or compliance professionals regarding your obligations.

© 2025 – 2026 Invoance, Inc. All rights reserved.
PrivacyLegalFAQ
PROOF, NOT PROMISES.