Overview
The embeddable viewer lets you display audit log events directly in your application without proxying through your backend. You generate a short-lived JWT token scoped to specific filters, then pass it to a frontend component or iframe.
Creating a Viewer Token
Generate a token server-side using the API:
curl -X POST https://getimmutable.dev/api/v1/viewer-token \
-H "Authorization: Bearer imk_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"tenant_id": "org_7rT2xBc",
"ttl": 3600
}'
Parameters
Restrict the viewer to events for a specific tenant. Use this to show customers only their own events.
Restrict the viewer to events by a specific actor.
Token lifetime in seconds. Minimum 60, maximum 86400 (24 hours). Default 3600 (1 hour).
Response
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires_at": "2026-03-26T11:15:00Z"
}
Embedding with an iframe
The simplest approach is an iframe:
<iframe
src="https://getimmutable.dev/viewer?token=eyJhbGciOiJIUzI1NiIs..."
width="100%"
height="600"
frameborder="0"
style="border-radius: 8px;"
></iframe>
React Component Example
A reusable React component that handles token generation and display:
"use client";
import { useEffect, useState } from "react";
interface AuditLogViewerProps {
token: string;
height?: number;
}
export function AuditLogViewer({ token, height = 600 }: AuditLogViewerProps) {
const [iframeSrc, setIframeSrc] = useState<string | null>(null);
useEffect(() => {
setIframeSrc(`https://getimmutable.dev/viewer?token=${token}`);
}, [token]);
if (!iframeSrc) return null;
return (
<iframe
src={iframeSrc}
width="100%"
height={height}
style={{ border: "none", borderRadius: "8px" }}
title="Audit Log"
/>
);
}
Generate the token server-side and pass it as a prop:
// Server component
import { immutable } from "@/lib/immutable";
import { AuditLogViewer } from "./audit-log-viewer";
export default async function CustomerDashboard({ tenantId }: { tenantId: string }) {
const { token } = await immutable.createViewerToken({
tenantId,
ttl: 3600,
});
return (
<div>
<h2>Activity Log</h2>
<AuditLogViewer token={token} />
</div>
);
}
TTL Management
Tokens are short-lived by design. For long-running pages, refresh the token before it expires:
// Refresh token 5 minutes before expiry
const ttl = 3600;
const refreshInterval = (ttl - 300) * 1000;
setInterval(async () => {
const { token } = await fetch("/api/viewer-token").then((r) => r.json());
setIframeSrc(`https://getimmutable.dev/viewer?token=${token}`);
}, refreshInterval);
Security
Viewer tokens are read-only. They cannot be used to ingest events, modify settings, or access any write endpoints. It is safe to expose them to end users in the browser.
The token’s JWT claims encode the filters you specified. The viewer backend validates these claims and only returns matching events. Users cannot modify the token to access events outside the specified scope.