npm install @nodatachat/sdk
Machine-to-Machine SDK Five lines of code. Zero dependencies. Blind encryption for any system.
Your server should never see what it doesn't need to know.
INSTALL
npm bash
npm install @nodatachat/sdkcopy Zero dependencies. Works in Node.js, Bun, Deno, Cloudflare Workers — anything with fetch.
5 lines — and your server is blind
Encrypt a field, store it, decrypt it. Our server stores nothing.
TypeScript ts
import { NoData } from '@nodatachat/sdk';
const nd = new NoData({ apiKey: 'sk_live_...' });
// Encrypt — server-blind
const { ciphertext } = await nd.encrypt({
field: 'credit_card',
value: '4111111111111111',
});
// Store `ciphertext` in YOUR database. NoData stores nothing.
// Decrypt — audited
const { value } = await nd.decrypt({
field: 'credit_card',
ciphertext,
requester: 'billing-service',
});copy BATCH 100 fields. One call.
const result = await nd.batchNative([
{ op: 'encrypt', field: 'phone', value: '0501234567' },
{ op: 'encrypt', field: 'email', value: 'david@company.com' },
{ op: 'encrypt', field: 'id', value: '123456789' },
{ op: 'decrypt', field: 'ssn', ciphertext: 'aes256gcm:v1:...' },
]);
// result.ok === 4, result.failed === 0copy or — encrypt an entire object ts
const encrypted = await nd.encryptObject(
{ name: 'David', phone: '050...', email: 'd@x.com', age: 30 },
['phone', 'email']
);
// { name: 'David', phone: 'aes256gcm:v1:...', email: 'aes256gcm:v1:...', age: 30 }copy Modules 🔐 encrypt / decrypt
Field-level blind relay. Server encrypts, returns ciphertext. Content never stored.
nd.encrypt()nd.decrypt()nd.batchNative()nd.encryptObject()
🔗 channel
Secure tunnels between systems. E2E encrypted. Verification codes. Burn-after-read.
nd.channel.create()nd.channel.send()nd.channel.receive()nd.channel.proof()
🪝 webhook
Receive webhooks encrypted at rest. PBKDF2 + AES-256-GCM. You hold the key.
nd.webhook.create()nd.webhook.events()nd.webhook.list()
🔥 deliver
Burn-after-read delivery. One link. One view. Gone.
nd.deliver.send()nd.deliver.burn()nd.deliver.read()
📋 evidence
SOC-ready audit trail. Metadata only — never content. Proof certificates.
nd.evidence.query()nd.evidence.certificate()nd.evidence.verify()
🏦 vault
Zero-knowledge storage. You encrypt client-side. Server stores blindly.
nd.vault.create()nd.vault.read()nd.vault.delete()
M2M Secure Channel — system to system
Two systems need to exchange sensitive data. Neither trusts the other's infra. NoData sits in the middle — blind.
// System A — creates a channel
const ch = await nd.channel.create({
ttl: '1h',
requireVerification: true,
});
// System B — sends credit card data
await nd.channel.send({
token: ch.channel_token,
data: { card: '4111111111111111', cvv: '123', exp: '12/28' },
burnAfterRead: true,
});
// System A — receives
const result = await nd.channel.receive({
token: ch.channel_token,
verificationCode: '482901',
});
const card = JSON.parse(result.data);copy System A ──── channel.create() ────→ NoData ←──── channel.send() ──── System B Server relays encrypted bytes. Never sees content. Never stores content.
PLUGIN One line — Express / Fastify
Large system? No rewrite needed. One line of middleware — every response with sensitive fields auto-encrypted.
Express ts
import express from 'express';
import { nodataExpress } from '@nodatachat/sdk/express';
const app = express();
app.use('/api/customers', nodataExpress({
apiKey: 'sk_live_...',
encryptFields: ['phone', 'email', 'id_number'],
}));
// Every response with phone/email/id_number → auto-encrypted
// No code changes in your routescopy Fastify ts
import Fastify from 'fastify';
import { nodataFastify } from '@nodatachat/sdk/fastify';
const app = Fastify();
app.register(nodataFastify, {
apiKey: 'sk_live_...',
encryptFields: ['phone', 'email', 'id_number'],
});copy AUTH Service Accounts — scoped keys
Master key (sk_live_) creates restricted service accounts — scopes, rate limit, IP whitelist, expiry.
// Master key creates a scoped service account
const res = await fetch('/api/v1/service-account', {
method: 'POST',
headers: { Authorization: 'Bearer sk_live_MASTER_KEY' },
body: JSON.stringify({
name: 'payment-service',
scopes: ['encrypt', 'decrypt'],
rate_limit_per_minute: 500,
daily_quota: 100000,
expires_in_days: 90,
allowed_ips: ['10.0.0.0/8'],
}),
});
// → { key: "svc_live_abc123..." } — shown ONCEcopy sk_live_Master key
All scopes, creates child keys
svc_live_Service account
Restricted scopes, IP whitelist, expiry
Any language that speaks HTTP
Node.js Python cURL
import { NoData } from '@nodatachat/sdk';
const nd = new NoData({ apiKey: process.env.NODATA_API_KEY! });
const { ciphertext } = await nd.encrypt({
field: 'ssn',
value: '123-45-6789',
});
// Store in your DB. NoData stores nothing.
await db.query('UPDATE users SET ssn = $1 WHERE id = $2', [ciphertext, userId]);copy Architecture
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Your App │ ──────→ │ NoData API │ ──────→ │ Your DB │
│ │ │ │ │ │
│ plaintext │ │ ciphertext │ │ ciphertext │
│ lives here │ │ passes thru │ │ stored here│
│ │ │ stores: 0 │ │ │
└─────────────┘ └──────────────┘ └─────────────┘
NoData is a relay, not a vault. Data flows through, gets encrypted, and leaves. The server is blind by design — not by policy.
Why
🚫 Zero plaintext on our servers — ever
🔑 Zero key storage — you hold everything
📦 Zero data retention — we're a relay, not a warehouse
📋 Full audit trail — every operation logged (metadata only)
✅ SOC 2 ready — evidence endpoint = auditor-friendly
0️⃣ Zero dependencies — just fetch
100 calls/month free. No signup. No credit card.
@nodatachat/sdk v1.0.0 · 14.9 KB · MIT