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

@cognizy/sdk

v1.1.0

Published

Official TypeScript SDK for the Cognizy Public API.

Readme

@cognizy/sdk

Official TypeScript SDK for the Cognizy Public API.

Available on Professional plans and above.

Install

npm install @cognizy/sdk

Requires Node 18+ (for global fetch) or any modern browser.

Quick start

import { Cognizy } from '@cognizy/sdk';

const cognizy = new Cognizy({ apiKey: process.env.COGNIZY_API_KEY! });

// 1. Create a conversation tied to a contact in your system.
const conversation = await cognizy.conversations.create({
  contact: { externalId: 'user-42', name: 'Alice', email: '[email protected]' },
});

// 2. Send a message and get the AI reply (synchronous).
const { reply } = await cognizy.messages.send({
  conversationId: conversation.id,
  message: 'How do I reset my password?',
});
console.log(reply?.body);

Multi-tenant SaaS (B2B2C)

If your product embeds Cognizy and serves multiple end customers (e.g. a property platform whose realtors each have their own customers, a multi-tenant CRM, a marketplace), pass the optional account field so Cognizy groups conversations by your customer:

const conversation = await cognizy.conversations.create({
  contact: {
    externalId: 'user-42',
    name: 'Alice',
    email: '[email protected]',
  },
  account: {
    externalId: 'acme-456',        // your customer / tenant id
    name: 'Acme Inc.',             // shown as a badge in the inbox
    source: 'my-saas',             // identifies your product (optional)
    metadata: { plan: 'pro', mrr: 499 }, // free-form data
  },
});

Each unique (source, externalId) becomes an ExternalAccount in Cognizy — created on the first call, reused on every subsequent call. All contacts and conversations from the same customer are linked under that account, with:

  • a badge on every conversation in the inbox
  • a filter to view conversations by account
  • a card on the contact detail showing the account's name, source and metadata

The account field is fully optional and backward-compatible — calls without it keep working exactly as before.

Streaming

for await (const event of cognizy.messages.stream({
  conversationId: conversation.id,
  message: 'Tell me a joke',
})) {
  if (event.type === 'token') process.stdout.write(event.token);
  if (event.type === 'done') console.log('\n— full text:', event.fullText);
  if (event.type === 'error') console.error(event.code, event.message);
}

Webhook verification

Always verify the signature before trusting a webhook payload.

import { verifyWebhookSignature } from '@cognizy/sdk';

app.post('/webhooks/cognizy', express.raw({ type: 'application/json' }), (req, res) => {
  const ok = verifyWebhookSignature({
    secret: process.env.COGNIZY_WEBHOOK_SECRET!,
    body: req.body, // raw Buffer — do not pre-parse
    header: req.headers['x-cognizy-signature'] as string,
  });
  if (!ok) return res.status(400).send('invalid signature');

  const event = JSON.parse(req.body.toString('utf8'));
  // … handle event
  res.status(200).send('ok');
});

Send APIs — transactional email & WhatsApp

Direct sends that don't create an inbox conversation, so receipts, password resets and shipping notices never land in your agents' queue. Delivery is asynchronous: the call resolves once the message is accepted, and the outcome arrives via the status endpoint or a webhook.

Requires the email:send / whatsapp:send scope on the key.

Email from a template

Templates are built in the Cognizy dashboard and referenced by id. {{variables}} are resolved per recipient:

await cognizy.email.send({
  to: '[email protected]',
  templateId: 'tpl_123',
  variables: { 'contact.firstName': 'Maria', 'order.id': '#1001' },
  idempotencyKey: 'order-1001-shipped', // safe to retry
});

Don't know which variables a template expects? Ask:

const { items } = await cognizy.email.templates();
// [{ id: 'tpl_123', name: 'Order shipped', variables: ['contact.firstName', 'order.id'], … }]

Email with your own body

Skip templateId and pass the content directly:

await cognizy.email.send({
  to: '[email protected]',
  subject: 'Your order {{order.id}} is on the way',
  html: '<p>Hi {{contact.firstName}}, it just shipped.</p>',
  variables: { 'contact.firstName': 'Maria', 'order.id': '#1001' },
  replyTo: '[email protected]',
});

Batches

Up to 1000 recipients per call, each with its own variables. Per-recipient values win over the shared ones:

const res = await cognizy.email.send({
  templateId: 'tpl_123',
  variables: { 'company.name': 'Acme' },        // applies to everyone
  recipients: [
    { to: '[email protected]', variables: { 'contact.firstName': 'Ana' } },
    { to: '[email protected]', variables: { 'contact.firstName': 'Bruno' } },
  ],
});
// { count: 2, items: [{ id: 'oe_1', … }, { id: 'oe_2', … }] }

A batch is all-or-nothing against your quota: if the monthly allowance plus wallet balance can't cover every recipient, nothing is sent and EmailQuotaExhaustedError tells you the shortfall. Partial delivery would leave you unable to tell which recipients still need the message.

import { EmailQuotaExhaustedError } from '@cognizy/sdk';

try {
  await cognizy.email.send({ recipients, templateId });
} catch (err) {
  if (err instanceof EmailQuotaExhaustedError) {
    // { requested: 500, includedRemaining: 120, payableFromWallet: 0, shortfall: 380, … }
    await topUpWallet(err.details.shortfall! * (err.details.priceCents ?? 0));
  }
}

Delivery status

const email = await cognizy.email.get('oe_1');
// status: QUEUED → SENT → DELIVERED → OPENED → CLICKED, or BOUNCED / FAILED

Status only ever moves forward, so a late provider event can't undo a later one. Rather than polling, subscribe to the email.message.status webhook.

WhatsApp

Same shape. Free-form text and media need an open 24h session window with the recipient; outside it WhatsApp only accepts a template approved in your WABA:

await cognizy.whatsapp.send({
  to: '+5511999999999',
  type: 'TEMPLATE',
  template: { name: 'order_update', language: 'pt_BR', variables: ['Maria', '#1001'] },
});

const msg = await cognizy.whatsapp.get('om_1');
// status: QUEUED → SENT → DELIVERED → READ, or FAILED

Note that Meta bills WhatsApp messages directly to the card on your WhatsApp Business account — Cognizy doesn't charge per message. Platform email is different: it leaves through Cognizy's infrastructure, so it draws on your plan's monthly allowance and then your wallet. Bringing your own SendGrid or Mailgun account exempts you from both.

Errors

The SDK throws typed errors for the cases you'll want to handle:

import {
  AuthError,
  RateLimitError,
  QuotaExceededError,
  EmailQuotaExhaustedError,
  CognizyError,
} from '@cognizy/sdk';

try {
  await cognizy.messages.send({ conversationId, message: 'hi' });
} catch (err) {
  if (err instanceof RateLimitError) {
    await sleep(err.retryAfterSeconds ?? 60);
  } else if (err instanceof QuotaExceededError) {
    notifyOps(`Hit ${err.used}/${err.limit} requests this month`);
  } else if (err instanceof EmailQuotaExhaustedError) {
    notifyOps(`Out of email credit — ${err.details.shortfall} couldn't be sent`);
  } else if (err instanceof AuthError) {
    rotateKey();
  } else if (err instanceof CognizyError) {
    console.error(err.status, err.code, err.message);
  }
}

The two quota errors mean different things and take different fixes:

| Error | Status | Meaning | Fix | |---|---|---|---| | QuotaExceededError | 429 | Too many API requests this month | Wait, or raise the plan's request limit | | EmailQuotaExhaustedError | 400 | Out of emails — allowance and wallet both spent | Add wallet credit, or upgrade the plan |

Waiting never clears the second one; only money does.

API reference

The full Public API is documented in Swagger UI at:

https://<your-host>/api/v1/public/docs

(or /api/v1/public/openapi.json for the raw OpenAPI spec).

The SDK currently wraps the most-used surface — agents, conversations, messages (incl. SSE streaming) and the Send APIs for email and WhatsApp — plus webhook signature verification. The following resources are also available in the Public API but are not yet covered by this SDK; call them via fetch (or any HTTP client) with the same Authorization: Bearer <api-key> header:

| Resource | Base path | Notes | |---|---|---| | Contacts | /api/v1/public/contacts | List + tag management | | Knowledge Base | /api/v1/public/knowledge-base | CRUD + semantic search (RAG) | | Tasks & Boards | /api/v1/public/task-boards, /tasks/:id | Full kanban surface | | Campaigns | /api/v1/public/campaigns | List + per-campaign analytics | | Scheduling | /api/v1/public/scheduling | Booking pages + appointments | | Analytics | /api/v1/public/analytics | Aggregated tenant metrics | | Webhooks (management) | /api/v1/public/webhooks | Register endpoints, replay deliveries |

Example — direct fetch to a non-SDK endpoint:

const res = await fetch('https://<your-host>/api/v1/public/tasks/' + taskId, {
  method: 'PATCH',
  headers: {
    'Authorization': `Bearer ${process.env.COGNIZY_API_KEY}`,
    'Content-Type': 'application/json',
    'Idempotency-Key': crypto.randomUUID(),
  },
  body: JSON.stringify({ title: 'Updated title' }),
});

SDK coverage will expand over time — open an issue if a specific resource is blocking you.

Custom base URL

Useful for self-hosted deployments or staging environments.

const cognizy = new Cognizy({
  apiKey: '…',
  baseUrl: 'https://staging.api.cognizy.ai',
});

License

MIT