Skip to main content
This guide records one production-shaped event and verifies the receipt.

1. Create a project

In Lodger, create a project for the product area that owns the records. Most teams start with core, then add projects for separate products, environments, or regulated data boundaries. Use private receipt and policy access for internal projects, and public access when customers should be able to open links without a token. Activity links can be disabled per project.

2. Create an API key

Create an API key with:
  • events:write for event ingestion.
  • events:read if the integration needs retained-event queries.
  • A project restriction when the key should only write to one project.
  • Allowed actions when the key should only write known event names.
Keep the key server-side. Do not expose it in browser code.

3. Install the SDK

bun add @lodger/sdk

4. Record an event

import { Lodger } from "@lodger/sdk"

const lodger = new Lodger({
  apiKey: process.env.LODGER_API_KEY!,
  workspaceId: process.env.LODGER_WORKSPACE_ID!,
  projectId: "core",
  environment: process.env.NODE_ENV,
  server: process.env.HOSTNAME,
})

const receipt = await lodger.event("account.user.login", {
  actor: { id: user.id, type: "user", email: user.email },
  target: { id: user.id, type: "account" },
  metadata: {
    requestId,
    sessionId,
  },
  userVisible: true,
})

console.log(receipt.receipt)

5. Verify the receipt

const verified = await lodger.receipt(receipt.receipt)

console.log(verified.verified, verified.entry.hash)
Private project receipts can also be shared with scoped receipt tokens:
const link = await lodger.receiptToken(receipt.receipt)

return link.receiptUrl
The receipt response includes the event hash, previous hash, received time, lane, storage class, policy version, and verification URL.

6. Query records

const page = await lodger.query({
  query: user.id,
  lane: "security",
  limit: 25,
})

for (const event of page.events) {
  console.log(event.sequence, event.action, event.receipt)
}
If you request archived records, send includeArchive: true. Archive retrieval can be slower by design.