npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@nodatachat/sdk

v2.0.0

Published

NoData SDK for the Information Access Processor: one call decides whether an identity may access information and returns a signed proof.

Downloads

183

Readme

@nodatachat/sdk

The developer SDK for NoData, the Information Access Processor.

Give AI access without giving it the data. One API. One decision. One proof.

The primitive is a single call — compute(information, intent, clearance) → a decision with an authorized view and a signed proof. The data the AI isn't cleared for never reaches the model. You pay per decision, and every decision is the proof.

Everything else in this SDK — capsules, documents, scan, engines — is an adapter that resolves to that same decision.


Install

npm install @nodatachat/sdk

Zero dependencies. Works in Node.js, Bun, Deno, Cloudflare Workers, and any runtime with fetch. Get a key at nodatacapsule.com/capsule-api/register.


The primitive — compute()

import { NoData } from '@nodatachat/sdk';

const nd = new NoData({ apiKey: 'ndp_...' });

const { answer, sections, proof } = await nd.compute({
  question: 'What is the claim status?',
  clearance: 'internal',
  sections: [
    { title: 'Status', text: 'Claim status: approved. Region: Tel Aviv.' },
    { title: 'Client', text: 'Dana Cohen, ID 039821582, amount 42,500 NIS.' },
  ],
});

// "Client" auto-classifies as confidential and is WITHHELD at internal clearance —
// it never reaches the model. `answer` comes only from "Status".
// sections → [{ title: 'Status', sent: true }, { title: 'Client', sent: false }]

const v = await nd.verify(proof.id); // → { authentic: true, unaltered: true, ... }

Wire it to any model runtime — the pattern is always the same: NoData decides + proves; your model only ever sees the authorized slice.

// OpenAI / Anthropic / Gemini / LangChain / n8n — same shape:
const gate = await nd.compute({ question, clearance, sections });
if (gate.decision === 'deny') return 'Not authorized.';
const reply = gate.answer;            // already computed over the authorized slice
// attach gate.proof.id to your response as the tamper-evident receipt.

Adapter — a customer capsule in a few calls

The capsule is one adapter over the primitive: an isolated, content-blind workspace per customer; every read is a governed decision with a receipt.

import { NoData } from '@nodatachat/sdk';

const nd = new NoData({ apiKey: 'ndp_...' });

// Mint a customer capsule (isolated, content-blind)
const cap = await nd.capsules.create({ handle: 'case-4471', display_name: 'Yossi Levy' });

// Seal a document in — a key per recipient
await cap.documents.add({
  title: 'Policy',
  sections: [
    { label: 'Summary', classification: 'public',       text: 'Public summary.' },
    { label: 'Terms',   classification: 'confidential',  text: 'Confidential terms.' },
  ],
  recipients: [{ email: '[email protected]', classifications: ['public'], code: 'blue-harbor' }],
});

// Grant a member access across the docs
await cap.members.add({ email: '[email protected]', classifications: ['public'], code: 'blue-harbor' });

// Signed audit ledger — who opened, when, on which device
const ledger = await cap.audit.get();

// Kill-switch: blocks the key capsule-wide — every live link 410s at once.
// Reversible (a paused capsule can be restored); use burn to crypto-shred the bytes.
await cap.revoke({ reason: 'offboarded' });

The server stores ciphertext only — never your section plaintext or the key.


AI governance — let an agent read only what you allow

Grant a named agent scoped classifications; on read it gets back only those — denied sections never decrypt (deny-by-default), and every read is audited as an AI access.

const g = await cap.ai.grant({ agent_name: 'claims-bot', classifications: ['public'] });

const read = await cap.ai.read({ agent_id: g.agent_id });
// read.documents[].sections → 'public' only; 'confidential' is absent, never decrypted

await cap.ai.revoke(g.agent_id);

Embedded Capsule — the white-label widget

Mint an origin-bound token for one of the capsule's documents and frame the viewer on your own site. The raw bearer never leaves NoData's origin — the token encrypts it.

const { embed_url } = await cap.embed({
  bearer: '<document bearer from documents.add>',
  allowed_origin: 'https://portal.myfirm.com',
  ttl_seconds: 3600,
});
// <iframe src={embed_url} />

Tenants — provision a whole organization

const t = await nd.tenants.create({ company_name: 'Acme', slug: 'acme', capsule_install: true });
const state = await nd.tenants.get(t.tenant_id);

Requires a key with the partner.provision_tenants scope.


Fleet overview — you manage a fleet, not a capsule

const fleet = await nd.capsules.overview();
// { fleet: { active_vaults, total_documents, ... }, ai_governance: { agents, grants_active } }

Capsule API reference

| Method | Endpoint | What it does | |--------|----------|--------------| | nd.capsules.create(req) | POST /v1/capsules | Mint a customer capsule | | nd.capsules.list(opts?) | GET /v1/capsules | List this org's capsules | | nd.capsules.get(idOrSlug) | GET /v1/capsules/{id} | Capsule summary | | cap.documents.add(req) | POST /v1/capsules/{id}/documents | Seal a document in | | cap.documents.list() | GET /v1/capsules/{id}/documents | List documents (metadata) | | cap.members.add(req) | POST /v1/capsules/{id}/members | Grant a member access | | cap.members.list() | GET /v1/capsules/{id}/members | The member roster | | cap.ai.grant(req) | POST /v1/capsules/{id}/ai-grants | Grant an AI agent scoped classifications | | cap.ai.list() | GET /v1/capsules/{id}/ai-grants | List grants (allowed vs denied) | | cap.ai.read(req) | POST /v1/capsules/{id}/ai-read | Agent reads only its allowed classifications | | cap.ai.revoke(id) | POST /v1/capsules/{id}/ai-grants | Revoke an agent | | cap.audit.get(opts?) | GET /v1/capsules/{id}/audit | Signed audit ledger | | cap.embed(req) | POST /v1/capsules/{id}/embed-token | Origin-bound embed token | | cap.revoke(opts?) | POST /v1/capsules/{id}/revoke | Kill-switch — every live link 410s at once (reversible) | | nd.tenants.create(req) | POST /v1/tenants | Provision a tenant | | nd.tenants.get(id) | GET /v1/tenants/{id} | Read tenant state | | nd.capsules.overview() | GET /v1/overview | Fleet totals |


Configuration

const nd = new NoData({
  apiKey: 'ndp_...',
  baseUrl: 'https://www.nodatacapsule.com',  // default
  timeout: 30000,                            // ms
  retries: 2,                                // on 5xx / network error
  headers: { 'X-Custom': 'value' },
  onRequest:  (url, init)        => console.log(`→ ${url}`),
  onResponse: (url, status, ms)  => console.log(`← ${status} ${ms}ms`),
  onError:    (url, err)         => console.error(`! ${url}: ${err.message}`),
});

Error handling

import { NoData, NoDataError } from '@nodatachat/sdk';

try {
  await nd.capsules.create({ handle: 'case-4471' });
} catch (err) {
  if (err instanceof NoDataError) {
    console.log(err.status, err.message, err.retryAfter);
  }
}

Rate limits are handled automatically — the SDK waits and retries on 429.


Platform Engines — nd.engines.*

The shared machinery beneath the capsule (and beneath File / Code / AI / Data Capsule). These are the engines, not the pitch — the way Stripe doesn't put its internal ledger in the hero. Reach for them directly only when you need the raw primitive.

// Blind Relay — field-level encrypt/decrypt (server stores nothing)
const { ciphertext } = await nd.engines.blindRelay.encrypt({ field: 'credit_card', value: '4111...' });

// Governance — register data + grant/revoke agents (runs on Excel/DB/CRM too)
await nd.engines.governance.grant(/* ... */);

// Channel — system-to-system encrypted transfer
const ch = await nd.engines.channel.create({ ttl: '1h' });

// Delivery — burn-after-read
await nd.engines.deliver.send({ content: 'API_KEY=...', burn: true });

// Evidence — audit trail + proofs
await nd.engines.evidence.query({ field: 'credit_card' });

// Vault — zero-knowledge blob storage · Webhooks — encrypted at rest
await nd.engines.vault.create({ /* ... */ });
await nd.engines.webhook.create({ label: 'stripe' });

| Engine | Namespace | Purpose | |--------|-----------|---------| | Governance | nd.engines.governance.* | Data permissions — register, grant, revoke (product-independent) | | Blind Relay | nd.engines.blindRelay.* | encrypt / decrypt / batch — field-level, server-blind | | Channel | nd.engines.channel.* | Encrypted system-to-system transfer | | Delivery | nd.engines.deliver.* | Burn-after-read secret delivery | | Evidence | nd.engines.evidence.* | Audit trail + cryptographic proofs | | Vault | nd.engines.vault.* | Zero-knowledge blob storage | | Webhooks | nd.engines.webhook.* | Receive webhooks, encrypted at rest |

The old top-level accessors (nd.encrypt, nd.channel, nd.governance, …) still work but are deprecated — use nd.engines.*.

Framework plugins are available: @nodatachat/sdk/express and @nodatachat/sdk/fastify.


Architecture

                     one capsule per customer
┌─────────────┐        ┌──────────────┐        ┌─────────────┐
│  Your App   │ ─────→ │  NoData API  │ ─────→ │  Your world │
│  plaintext  │        │  ciphertext  │        │  ciphertext │
│  lives here │        │  content-    │        │  + receipts │
│             │        │  blind · 0   │        │             │
└─────────────┘        └──────────────┘        └─────────────┘
     Capsule = the entity  ·  Engines = the machinery underneath

Content-blind by design — not by policy, by architecture. We store ciphertext; never your data, never the key. A zero-knowledge capsule is sealed to a key only your customer holds, so we can never unwrap it.


Get your API key

nodatacapsule.com/vault-api


NoData on npm

  • @nodatachat/nodata: the main package, with all protection, scanning and governance capabilities, from the terminal.
  • @nodatachat/sdk (this one): integration for developers.
  • @nodatachat/mcp: integration for AI agents and MCP clients.

License

FSL-1.1-ALv2 (Functional Source License 1.1, Apache 2.0 future license). Use it for any purpose except a competing product or service. Each release becomes available under the Apache License 2.0 two years after it is published. Version 1.0.0 was published under MIT and remains available under that license. Copyright 2026 Capsule Ltd.