celestin-sdk
v0.1.0-alpha.1
Published
Official Node SDK for Celestín — zero-knowledge bank reconciliation API.
Maintainers
Readme
celestin-sdk
Official Node.js SDK for Celestín — the zero-knowledge bank reconciliation API for accounting teams and SaaS integrators.
Alpha release — this package is currently at
0.1.0-alpha.1and shipped alongside the internal Celestín Public API rollout. Breaking changes can happen between alpha versions. Pin exact versions in production.
Quickstart / Inicio rápido
npm install celestin-sdkimport { Celestin } from "celestin-sdk";
const celestin = new Celestin({
apiKey: process.env.CELESTIN_API_KEY!, // sk_test_... or sk_live_...
tenantId: "acme-sl", // optional, per-request override available
});
const job = await celestin.reconciliations.create({
bank: [
{
id: "b1",
date: "2026-03-15",
amount_cents: -12500,
currency: "EUR",
reference: "REF-A3K8M",
description: "Pago factura Acme",
},
],
ledger: [
{
id: "l1",
date: "2026-03-15",
debit_cents: 12500,
credit_cents: 0,
currency: "EUR",
account_code: "400",
reference: "REF-A3K8M",
description: "Factura Acme marzo",
},
],
});
console.log(`Matched ${job.summary.matches_total} of ${job.summary.bank_count} transactions`);
console.log(`By level: ${JSON.stringify(job.summary.matches_by_level)}`);Features
- Type-safe resource clients:
celestin.reconciliations,celestin.tenants. Full TypeScript strict-mode types for request bodies, response shapes and error classes. - Automatic retries: 429 and 5xx responses are retried with exponential backoff (respecting
Retry-Afterheaders), up to 3 attempts. POSTs are always idempotency-keyed so retries are safe end-to-end. - Typed error hierarchy:
CelestinErrorbase withCelestinAuthError,CelestinValidationError,CelestinRateLimitError,CelestinServerError,CelestinConnectionErrorandCelestinAbortErrorsubclasses — catch the specific one you care about. - Client-side anonymisation (Layer 1): the
Anonymizerclass redacts Spanish IBANs, NIF/NIE/CIF, emails,+34phones and Luhn-valid 16-digit cards into opaque<TYPE:HASH>tokens before the data leaves your server. Uses HKDF-SHA256 + HMAC-SHA256 — the plaintext never reaches Celestín. - Cancellable requests: every resource method accepts an
AbortSignalfor timeout and user-cancellation.
Zero-knowledge anonymisation / Anonimización zero-knowledge
By default, the SDK forwards your data to Celestín unchanged. For sensitive workloads, wire the built-in Anonymizer to tokenise Spanish PII client-side:
import { Anonymizer, Celestin } from "celestin-sdk";
const anon = new Anonymizer({
masterKey: Buffer.from(process.env.CELESTIN_MASTER_KEY!, "hex"), // 32 bytes
tenantId: "acme-sl",
});
const safeBank = bankTransactions.map((tx) => ({
...tx,
description: anon.redact(tx.description),
reference: anon.redact(tx.reference),
}));
const job = await celestin.reconciliations.create({
bank: safeBank,
ledger: safeLedger,
tokens: {
scheme: "hmac-sha256-base32-v2",
salt_fingerprint: anon.fingerprint(),
},
});
// The server's match explanations come back with your tokens —
// translate them back to your original strings locally:
const humanMatches = job.matches?.map((m) => ({
...m,
explanation: anon.deanonymize(m.explanation as string),
}));El servidor nunca ve tus datos reales. Los tokens son determinísticos (mismo input → mismo token) pero irreversibles sin tu masterKey — que nunca sale de tu servidor.
The SDK supports:
| Pattern | Token type | Example |
|---|---|---|
| NIF | NIF | 12345678Z → <NIF:A3KM8P7ZNQWR5> |
| NIE | NIF | X1234567L → <NIF:...> |
| CIF | CIF | B12345678 → <CIF:...> |
| IBAN ES | IBAN | ES91 2100 0418 4502 0005 1332 → <IBAN:...> |
| Email | EMAIL | [email protected] → <EMAIL:...> |
| Phone +34 | TEL | +34 612 345 678 → <TEL:...> |
| Card (Luhn-valid) | CARD | 4532 0151 1283 0366 → <CARD:...> |
A second NER-based layer (PER/ORG via DistilBERT ONNX) is available as an optional peer dependency (onnxruntime-node) in a later SDK release — Phase 9 ships the Layer 1 regex path only.
Error handling
import {
CelestinValidationError,
CelestinRateLimitError,
CelestinAuthError,
} from "celestin-sdk";
try {
await celestin.reconciliations.create(body);
} catch (err) {
if (err instanceof CelestinValidationError) {
for (const field of err.fieldErrors) {
console.error(`${field.field}: ${field.message}`);
}
} else if (err instanceof CelestinRateLimitError) {
console.warn(`Rate limited, retry after ${err.retryAfterSeconds}s`);
} else if (err instanceof CelestinAuthError) {
console.error("Bad API key — regenerate at https://celestin.es/app");
} else {
throw err;
}
}Every error exposes:
.code— machine-readable short code (validation_failed,rate_limited, ...).status— HTTP status code (when the error comes from a server response).problem— the full RFC 7807 problem+json body.requestId— theX-Celestin-Request-Idfor support triage
Configuration
new Celestin({
apiKey: "sk_test_...", // required
baseUrl: "https://sandbox-api.celestin.es", // optional, default https://api.celestin.es
tenantId: "acme-sl", // optional, per-request override available
timeoutMs: 30_000, // default 30 seconds
userAgent: "my-app/1.2.3", // appended to celestin-sdk-node/0.1.0-alpha.1
});Per-request overrides on every resource method:
await celestin.reconciliations.create(body, {
tenantId: "other-tenant", // X-Celestin-Tenant override
idempotencyKey: "my-key-123", // explicit key (default: auto UUIDv4 for POSTs)
timeoutMs: 60_000, // override default timeout
signal: controller.signal, // AbortSignal for cancellation
});Environments
| Environment | Base URL | Key prefix |
|---|---|---|
| Production | https://api.celestin.es | sk_live_... |
| Sandbox | https://sandbox-api.celestin.es | sk_test_... |
Test keys never touch production data. Responses from test keys include "livemode": false.
Requirements
- Node.js 18+ (uses native
fetchandAbortSignal.timeout) - ES module projects (
"type": "module"or.mjs) — CommonJS is not currently supported
License
MIT. Copyright © Team Banzai, S.L.U.
Support
- Documentation: https://docs.celestin.es
- Dashboard: https://celestin.es/app
- Issues: https://github.com/team-banzai/celestin/issues
- Email:
[email protected]
