CLIENT SDK·@passyn/node

Node.js SDK

@passyn/node is the official, typed, zero-dependency client for Node 18+ and edge runtimes (Cloudflare Workers, Vercel Edge Functions, AWS Lambda).

OpenAPI 3.0 SpecLaunch API Playground

Installation

pnpm add @passyn/node
# or npm i @passyn/node / yarn add @passyn/node

Quickstart usage

Import the default client, instantiate it with your API key, and call strongly-typed methods.

passyn-tour.ts
import Passyn, { PassynError } from "@passyn/node";
const passyn = new Passyn(process.env.PASSYN_API_KEY!, {
baseUrl: "https://sub.blansyn.com/api/v1", // or "http://localhost:3000/api/v1" for local dev
timeoutMs: 10_000,
});
// ── 1. Create a Pass Definition ──────────────────────────
const pass = await passyn.passes.create({
name: "Exam Cram 72h",
type: "EXAM",
durationHours: 72,
price: 19,
isActive: true,
});
const { passes, total } = await passyn.passes.list({ type: "EXAM", active: true });
await passyn.passes.update(pass.id, { price: 24 });
// ── 2. Users & Access Credential ─────────────────────────
const user = await passyn.users.create({ name: "Ada", email: "[email protected]" });
const access = await passyn.access.activate({ userId: user.id, passId: pass.id });
// ── 3. Edge Turnstile Verification ───────────────────────
const check = await passyn.access.verify({
accessId: access.id,
consume: true, // decrements one use atomically
});
console.log(check.valid); // => true
// ── 4. Error Handling ────────────────────────────────────
try {
await passyn.passes.get("pass_unknown");
} catch (err) {
if (err instanceof PassynError) {
console.error(err.code, err.status, err.message);
}
}

Webhook verification

The static helper Passyn.verifyWebhookSignature implements the timestamped HMAC-SHA256 verification with constant-time equality checks against replay attacks.

server.ts
import Passyn from "@passyn/node";
import express from "express";
const app = express();
// IMPORTANT: signature verification requires the raw unparsed request buffer
app.post("/webhooks/passyn", express.raw({ type: "application/json" }), (req, res) => {
const ok = Passyn.verifyWebhookSignature(
req.body.toString("utf8"),
req.headers["passyn-signature"] as string,
process.env.PASSYN_WEBHOOK_SECRET!
);
if (!ok) return res.status(400).send("Invalid signature");
const event = JSON.parse(req.body.toString("utf8"));
if (event.event === "pass.expired") {
// Revoke access or trigger customer notification
}
res.json({ received: true });
});