Node SDK · Minter
Use the minter when your application's frontend wants to display events directly — see Embed Tokens for the full model. Construct once at boot, mint per request:
import * as minter from "@everscribe/sdk-node/minter";
const m = new minter.Client(projectId, apiKey);
The token returned from mintToken is a JWT. Hand it to your frontend via your normal page-render path. Never expose your project API key to the browser.
Single-tenant
Use when your project has one customer per project, or when you're embedding the UI in your own internal tooling. The token has no tenant_id claim, so the embed shows every event in the project.
app.get("/api/embed-token", async (req, res) => {
const user = await authenticate(req);
if (!user) {
res.status(401).send("unauthorized");
return;
}
try {
const token = await m.mintToken({
// No tenantId — the project has one customer (or is
// internal), so the token doesn't need to filter by tenant.
expiresIn: 60 * 60 * 1000, // 1 hour, in ms
allowedColumns: ["occurred_at", "action", "actor", "target"],
});
res.json({ token });
} catch {
res.status(500).send("mint failed");
}
});
Multi-tenant
Use when your project partitions events by tenant_id and each customer should only see their own. Mint a token whose tenantId matches the signed-in user's tenant — the server enforces the scope on every read.
app.get("/api/embed-token", async (req, res) => {
const user = await authenticate(req);
if (!user) {
res.status(401).send("unauthorized");
return;
}
try {
const token = await m.mintToken({
// tenantId set to the signed-in user's tenant — reads
// filtered server-side. For an admin view (your internal
// support tool that should see every tenant), use the
// same minter but omit tenantId.
tenantId: user.tenantId,
expiresIn: 60 * 60 * 1000,
allowedColumns: ["occurred_at", "action", "actor", "target"],
allowedActions: ["user.*", "billing.invoice.created"],
});
res.json({ token });
} catch {
res.status(500).send("mint failed");
}
});
Multi-tenant products often expose two endpoints:
| Endpoint | Token | Used for |
|---|---|---|
/api/embed-token/customer |
tenantId = signed-in user's tenant |
the end-customer's view of their own audit trail |
/api/embed-token/admin |
tenantId omitted |
internal admin / support tool, shows every tenant |
Same minter, different scoping rules.
TokenOptions
| Field | Type | Notes |
|---|---|---|
tenantId |
string |
Optional. Scopes reads to events with matching tenant_id. Trimmed; ≤ 256 chars. Omit for unscoped (single-tenant or admin view). |
expiresIn |
number |
Token lifetime in milliseconds. Server clamps to [60_000, 86_400_000]. Omit or pass 0 for the server default (1h). |
allowedColumns |
string[] |
Optional whitelist of Event JSON field names (snake_case). Empty array rejected. |
allowedActions |
string[] |
Exact match or suffix wildcard (user.*). Empty array rejected. |
The SDK exports MIN_EXPIRES_IN_MS, MAX_EXPIRES_IN_MS, and ALLOWED_COLUMNS constants if you want to validate before calling.