Docs/Core SDK/Sessions & Receipts

Sessions & Receipts

Create sessions to group related agent actions into hash-chained, cryptographically-signed receipt sequences.

import { Invariance, Session } from '@invariance/sdk';
Prerequisites: Initialization

Overview

A session is a container for a sequence of hash-chained receipts. Every receipt contains the SHA-256 hash of its action data plus the hash of the previous receipt, forming a tamper-evident chain. If any receipt is modified after creation, all subsequent hashes become invalid.

Sessions can be created lazily with `inv.session()` (backend registration happens in the background) or eagerly with `await inv.createSession()` (waits for backend confirmation).

When you close a session with `session.end()`, a close hash is computed over the entire chain and sent to the backend. This seals the session — no more receipts can be added.

Architecture

Sessions manage their own receipt chain state (hash cursor, sequence number). The Transport layer handles batching and network I/O. Sessions are independent — you can run multiple sessions concurrently without interference.

Important Notes

Sessions must be ended
Always call session.end() when done. Un-ended sessions remain "open" on the server and their receipts may not be fully flushed.
Lazy vs. eager creation
inv.session() returns immediately (fire-and-forget). Use inv.createSession() when you need to guarantee the session exists before recording.

Quick Example

Create a session and record actionstypescript
const inv = Invariance.init({ apiKey: 'dev_...', privateKey: '...' });

const session = inv.session({ agent: 'swap-bot', name: 'morning-run' });

await session.record({
  action: 'search', input: { query: 'ETH price' }
});
await session.record({
  action: 'swap', input: { from: 'ETH', to: 'USDC', amount: '1.0' },
  output: { txHash: '0xabc...' }
});

session.end();
await inv.shutdown();

Type Definitions

Receipt
interface Receipt {
  id: string;
  sessionId: string;
  agent: string;
  action: string;
  input: Record<string, unknown>;
  output?: Record<string, unknown>;
  error?: string;
  timestamp: number;
  hash: string;
  previousHash: string;
  signature: string | null;
  contractId?: string;
  counterAgentId?: string;
  counterSignature?: string;
}
A hash-chained, signed receipt of an agent action.
SessionInfo
interface SessionInfo {
  id: string;
  agent: string;
  name: string;
  status: 'open' | 'closed' | 'tampered';
  receiptCount: number;
}
Information about a session including its status and receipt count.

API Reference

session
Create a new session (lazy — backend registration happens asynchronously).
session(opts: { agent: string; name: string }): Session
Parameters
agentstringAgent identifier
namestringHuman-readable session name
ReturnsSession
createSession
Create a session and wait for backend confirmation.
async createSession(opts: { agent: string; name: string }): Promise<Session>
Parameters
agentstringAgent identifier
namestringSession name
ReturnsPromise<Session>
session.record
Record an action as a hash-chained receipt in this session.
async record(action: Action): Promise<Receipt>
Parameters
actionActionThe action to record
ReturnsPromise<Receipt>
session.end
Close the session. Computes a close hash and seals the chain.
end(status?: 'closed' | 'tampered'): SessionInfo
Parameters
status'closed' | 'tampered'Final session status
ReturnsSessionInfo
session.wrap
Policy check, execute, and record within a session context. Combines policy enforcement with execution and receipt creation in one call.
async wrap<T>(action: Omit<Action, "output" | "error">, fn: () => T | Promise<T>, checkPolicies?: (action: Action) => PolicyCheck): Promise<{ result: T; receipt: Receipt }>
Parameters
actionOmit<Action, "output" | "error">Action metadata (action name, input)
fn() => T | Promise<T>The function to execute
checkPolicies(action: Action) => PolicyCheckOptional policy check function evaluated before execution
ReturnsPromise<{ result: T; receipt: Receipt }>
session.getReceipts
Get all receipts recorded in this session (in-memory). Returns the session's local receipt chain without making API calls.
getReceipts(): readonly Receipt[]
Returnsreadonly Receipt[]
session.traces
Get a chainable TraceQuery over this session's receipts. Enables fluent filtering and analysis of session data.
traces(): TraceQuery
ReturnsTraceQuery
session.verify
Verify this session's receipt chain locally using verifyChain(). Checks hash-chain integrity and optional signature verification.
async verify(publicKeyHex?: string): Promise<VerifyResult>
Parameters
publicKeyHexstringOptional public key (hex) for signature verification. If omitted, only hash-chain integrity is checked.
ReturnsPromise<VerifyResult>

Walkthrough

Session lifecycle from creation to verification
1
Create a session
Initialize the SDK and create a session.
typescript
const inv = Invariance.init({
  apiKey: process.env.INVARIANCE_KEY!,
  privateKey: process.env.PRIVATE_KEY!,
});

const session = inv.session({
  agent: 'research-agent',
  name: 'daily-research',
});
2
Record a chain of actions
Each record call creates a receipt hash-chained to the previous one.
typescript
await session.record({
  action: 'web_search',
  input: { query: 'latest AI research papers' },
  output: { results: 15 },
});

await session.record({
  action: 'summarize',
  input: { paperCount: 5 },
  output: { summary: '...' },
});
3
End and verify
Close the session and verify chain integrity.
typescript
const info = session.end();
console.log(info.receiptCount); // 2

import { verifyChain } from '@invariance/sdk';
const receipts = await inv.query({ sessionId: session.id });
const result = verifyChain(receipts);
console.log(result.valid); // true

Error Handling

Error handling patterntypescript
import { InvarianceError } from '@invariance/sdk';

const session = inv.session({ agent: 'bot', name: 'run' });
session.end();

try {
  await session.record({ action: 'search', input: { q: 'test' } });
} catch (err) {
  if (err instanceof InvarianceError) {
    console.error(err.code); // 'SESSION_CLOSED'
  }
}

Use Cases

  • Group a multi-step agent workflow into a single auditable session
  • Create separate sessions for each user request or task
  • Use eager creation (createSession) when session ID is needed before first action
  • Run multiple concurrent sessions for parallel agent activities
On this page
OverviewArchitectureImportant NotesQuick ExampleType DefinitionsAPI ReferenceWalkthroughError HandlingUse CasesRelated Modules