@esrating/node
v0.1.0
Published
ESRating Node.js SDK — typed client for the Distribution Hub API + webhook signature verification.
Maintainers
Readme
@esrating/node
Typed Node.js SDK for the ESRating Distribution Hub API. Mints embed sessions, confirms external payments, and verifies inbound webhook signatures.
Install
npm install @esrating/nodeRequires Node 18+ (uses native fetch).
Quick start
import { ESRating } from '@esrating/node';
const esrating = new ESRating({ apiKey: process.env.ESRATING_SK_LIVE });
// Inside your /api/start-insurance-session handler:
const session = await esrating.embed.createSession({
user_id: req.user.id,
email: req.user.email,
metadata: { partnerOrderId: req.user.orderId },
});
res.json(session); // → { session_url, expires_at, embed_session_id }The browser then loads session_url in an iframe via @esrating/embed-js or @esrating/embed-react.
Webhook verification
import express from 'express';
import { ESRating, WebhookSignatureError } from '@esrating/node';
const esrating = new ESRating();
const app = express();
// IMPORTANT — raw body, not JSON-parsed. The signature is over exact bytes.
app.post('/webhooks/esrating', express.raw({ type: 'application/json' }), (req, res) => {
try {
const event = esrating.webhooks.constructEvent(
req.body,
req.headers['x-esrating-signature'],
process.env.ESRATING_WEBHOOK_SECRET!,
);
switch (event.event) {
case 'quote.bound':
await onQuoteBound(event.data);
break;
case 'policy.issued':
await onPolicyIssued(event.data);
break;
}
res.json({ received: true });
} catch (err) {
if (err instanceof WebhookSignatureError) {
res.status(400).json({ error: err.message });
} else {
res.status(500).end();
}
}
});Confirm an external payment
For partners who collect payment in their own checkout (their Stripe, their PSP):
await esrating.embed.confirmExternalPayment({
quote_id: 'quote_abc123',
external_payment_id: 'pi_partner_xyz',
amount_cents: 250_000,
method: 'card',
});Idempotent — retrying with the same external_payment_id is safe.
Errors
Every non-2xx HTTP response is mapped to a typed subclass of ESRatingError:
import { ESRating, AuthError, ForbiddenError, RateLimitError } from '@esrating/node';
try {
await esrating.embed.createSession({ ... });
} catch (err) {
if (err instanceof AuthError) { /* sk_ key bad */ }
else if (err instanceof ForbiddenError) { /* paused, KYC required, etc. */ }
else if (err instanceof RateLimitError) {
await sleep(err.retryAfterSeconds! * 1000);
// retry
}
else throw err;
}License
Apache-2.0.
