{"_id":"@cognizy/sdk","_rev":"3-a2db1810b5425b19a74a60a01a4e8dfe","name":"@cognizy/sdk","dist-tags":{"latest":"1.1.0"},"versions":{"0.1.0":{"name":"@cognizy/sdk","version":"0.1.0","license":"MIT","_id":"@cognizy/sdk@0.1.0","maintainers":[{"name":"wayter","email":"wayter.paulo.95@gmail.com"}],"dist":{"shasum":"3cccba3308f7dd73030b328866e4d0783abe13ac","tarball":"https://registry.npmjs.org/@cognizy/sdk/-/sdk-0.1.0.tgz","fileCount":18,"integrity":"sha512-iQtVPqdji+b8TH+NtRl8FqDtk6ZscJJij2RoQJro1wZ1suzPu30URzbRTGXHn3qV8L0+uMHdS26UpGVvqU4xwg==","signatures":[{"sig":"MEUCIDpsv5DbCWV2q5YgxoAIHLMxB9iwEtACBeHjy9n/2chSAiEAxoM6rAqXwRGX6uaxkPoZGZi2gBVgdhteg84iejbQSI4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":37030},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"8854fe34016ba1448b0bd13806c90c900e409dc3","scripts":{"test":"node --test --experimental-strip-types src/*.test.ts","build":"tsc -p tsconfig.json"},"_npmUser":{"name":"wayter","email":"wayter.paulo.95@gmail.com"},"_npmVersion":"11.12.1","description":"Official TypeScript SDK for the Cognizy Public API.","directories":{},"_nodeVersion":"24.15.0","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.4.0","@types/node":"^20.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.1.0_1778465962961_0.4317478388781224","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"@cognizy/sdk","version":"1.0.0","license":"MIT","_id":"@cognizy/sdk@1.0.0","maintainers":[{"name":"wayter","email":"wayter.paulo.95@gmail.com"}],"dist":{"shasum":"86327f31d968c9f8e30d327733732da7db12dc1f","tarball":"https://registry.npmjs.org/@cognizy/sdk/-/sdk-1.0.0.tgz","fileCount":18,"integrity":"sha512-D3hjB2c0wLyz6wgXLq/NAuoN/ebnBqCffqVjzOJYhr8o2mNugD3s6jq+0PFae61CHTgZtsdGiUxSNq2mz9j4ZQ==","signatures":[{"sig":"MEUCIQDlbeFil5Mo5HvinQzyT4Uo4I9/e5fMCIKml48RKux+MQIgK9uO0pbv7OWbs3qJ7O4cWjMrG+4CL5vBwSMwXC81U9A=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":39215},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"7ccd705c8e431500599296c07b5ca8cd82fcb73f","scripts":{"test":"node --test --experimental-strip-types src/*.test.ts","build":"tsc -p tsconfig.json"},"_npmUser":{"name":"wayter","email":"wayter.paulo.95@gmail.com"},"_npmVersion":"11.12.1","description":"Official TypeScript SDK for the Cognizy Public API.","directories":{},"_nodeVersion":"24.15.0","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.4.0","@types/node":"^20.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk_1.0.0_1778727609015_0.6451047580711373","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@cognizy/sdk","version":"1.1.0","description":"Official TypeScript SDK for the Cognizy Public API.","license":"MIT","type":"module","main":"./dist/index.js","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"build":"tsc -p tsconfig.json","test":"npm run build && node --test --experimental-strip-types src/*.test.ts"},"engines":{"node":">=18"},"devDependencies":{"typescript":"^5.4.0","@types/node":"^20.0.0"},"_id":"@cognizy/sdk@1.1.0","gitHead":"cf25f41c00dd385c81c4f2bf542b4ffc2ed14859","_nodeVersion":"22.23.1","_npmVersion":"10.9.8","dist":{"integrity":"sha512-ct2zOfpl4nlTGL+UCNlUsM12iei+WBgaRSv+3ByKCDn4cJwZiBHPxwuIZP+who7N8bD6VnCTegJHio5bJ/SbrQ==","shasum":"f0e24c4baffc628b201a256d74d6f7ab23936962","tarball":"https://registry.npmjs.org/@cognizy/sdk/-/sdk-1.1.0.tgz","fileCount":18,"unpackedSize":59278,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCJJ7CRfHhFphqGzvBhPjDSdXzQIZyNkF1Be6N6ROTslQIgK62hB3VddsJu+xKcSeQpehi+ixp9gKXhgKMTrYPnK8k="}]},"_npmUser":{"name":"wayter","email":"wayter.paulo.95@gmail.com"},"directories":{},"maintainers":[{"name":"wayter","email":"wayter.paulo.95@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/sdk_1.1.0_1786907370126_0.16245979941846467"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-11T02:19:22.901Z","modified":"2026-08-16T19:09:30.481Z","0.1.0":"2026-05-11T02:19:23.104Z","1.0.0":"2026-05-14T03:00:09.250Z","1.1.0":"2026-08-16T19:09:30.321Z"},"license":"MIT","description":"Official TypeScript SDK for the Cognizy Public API.","maintainers":[{"name":"wayter","email":"wayter.paulo.95@gmail.com"}],"readme":"# @cognizy/sdk\n\nOfficial TypeScript SDK for the [Cognizy](https://cognizy.ai) Public API.\n\nAvailable on Professional plans and above.\n\n## Install\n\n```bash\nnpm install @cognizy/sdk\n```\n\nRequires Node 18+ (for global `fetch`) or any modern browser.\n\n## Quick start\n\n```ts\nimport { Cognizy } from '@cognizy/sdk';\n\nconst cognizy = new Cognizy({ apiKey: process.env.COGNIZY_API_KEY! });\n\n// 1. Create a conversation tied to a contact in your system.\nconst conversation = await cognizy.conversations.create({\n  contact: { externalId: 'user-42', name: 'Alice', email: 'alice@example.com' },\n});\n\n// 2. Send a message and get the AI reply (synchronous).\nconst { reply } = await cognizy.messages.send({\n  conversationId: conversation.id,\n  message: 'How do I reset my password?',\n});\nconsole.log(reply?.body);\n```\n\n## Multi-tenant SaaS (B2B2C)\n\nIf your product embeds Cognizy and serves **multiple end customers**\n(e.g. a property platform whose realtors each have their own customers, a\nmulti-tenant CRM, a marketplace), pass the optional `account` field so\nCognizy groups conversations by your customer:\n\n```ts\nconst conversation = await cognizy.conversations.create({\n  contact: {\n    externalId: 'user-42',\n    name: 'Alice',\n    email: 'alice@acme.com',\n  },\n  account: {\n    externalId: 'acme-456',        // your customer / tenant id\n    name: 'Acme Inc.',             // shown as a badge in the inbox\n    source: 'my-saas',             // identifies your product (optional)\n    metadata: { plan: 'pro', mrr: 499 }, // free-form data\n  },\n});\n```\n\nEach unique `(source, externalId)` becomes an **ExternalAccount** in\nCognizy — created on the first call, reused on every subsequent call. All\ncontacts and conversations from the same customer are linked under that\naccount, with:\n\n- a badge on every conversation in the inbox\n- a filter to view conversations by account\n- a card on the contact detail showing the account's name, source and\n  metadata\n\nThe `account` field is fully optional and backward-compatible — calls\nwithout it keep working exactly as before.\n\n## Streaming\n\n```ts\nfor await (const event of cognizy.messages.stream({\n  conversationId: conversation.id,\n  message: 'Tell me a joke',\n})) {\n  if (event.type === 'token') process.stdout.write(event.token);\n  if (event.type === 'done') console.log('\\n— full text:', event.fullText);\n  if (event.type === 'error') console.error(event.code, event.message);\n}\n```\n\n## Webhook verification\n\nAlways verify the signature before trusting a webhook payload.\n\n```ts\nimport { verifyWebhookSignature } from '@cognizy/sdk';\n\napp.post('/webhooks/cognizy', express.raw({ type: 'application/json' }), (req, res) => {\n  const ok = verifyWebhookSignature({\n    secret: process.env.COGNIZY_WEBHOOK_SECRET!,\n    body: req.body, // raw Buffer — do not pre-parse\n    header: req.headers['x-cognizy-signature'] as string,\n  });\n  if (!ok) return res.status(400).send('invalid signature');\n\n  const event = JSON.parse(req.body.toString('utf8'));\n  // … handle event\n  res.status(200).send('ok');\n});\n```\n\n## Send APIs — transactional email & WhatsApp\n\nDirect sends that **don't create an inbox conversation**, so receipts, password\nresets and shipping notices never land in your agents' queue. Delivery is\nasynchronous: the call resolves once the message is accepted, and the outcome\narrives via the status endpoint or a webhook.\n\nRequires the `email:send` / `whatsapp:send` scope on the key.\n\n### Email from a template\n\nTemplates are built in the Cognizy dashboard and referenced by id. `{{variables}}`\nare resolved per recipient:\n\n```ts\nawait cognizy.email.send({\n  to: 'maria@example.com',\n  templateId: 'tpl_123',\n  variables: { 'contact.firstName': 'Maria', 'order.id': '#1001' },\n  idempotencyKey: 'order-1001-shipped', // safe to retry\n});\n```\n\nDon't know which variables a template expects? Ask:\n\n```ts\nconst { items } = await cognizy.email.templates();\n// [{ id: 'tpl_123', name: 'Order shipped', variables: ['contact.firstName', 'order.id'], … }]\n```\n\n### Email with your own body\n\nSkip `templateId` and pass the content directly:\n\n```ts\nawait cognizy.email.send({\n  to: 'maria@example.com',\n  subject: 'Your order {{order.id}} is on the way',\n  html: '<p>Hi {{contact.firstName}}, it just shipped.</p>',\n  variables: { 'contact.firstName': 'Maria', 'order.id': '#1001' },\n  replyTo: 'support@yourcompany.com',\n});\n```\n\n### Batches\n\nUp to 1000 recipients per call, each with its own variables. Per-recipient values\nwin over the shared ones:\n\n```ts\nconst res = await cognizy.email.send({\n  templateId: 'tpl_123',\n  variables: { 'company.name': 'Acme' },        // applies to everyone\n  recipients: [\n    { to: 'ana@example.com', variables: { 'contact.firstName': 'Ana' } },\n    { to: 'bruno@example.com', variables: { 'contact.firstName': 'Bruno' } },\n  ],\n});\n// { count: 2, items: [{ id: 'oe_1', … }, { id: 'oe_2', … }] }\n```\n\nA batch is **all-or-nothing against your quota**: if the monthly allowance plus\nwallet balance can't cover every recipient, nothing is sent and\n`EmailQuotaExhaustedError` tells you the shortfall. Partial delivery would leave\nyou unable to tell which recipients still need the message.\n\n```ts\nimport { EmailQuotaExhaustedError } from '@cognizy/sdk';\n\ntry {\n  await cognizy.email.send({ recipients, templateId });\n} catch (err) {\n  if (err instanceof EmailQuotaExhaustedError) {\n    // { requested: 500, includedRemaining: 120, payableFromWallet: 0, shortfall: 380, … }\n    await topUpWallet(err.details.shortfall! * (err.details.priceCents ?? 0));\n  }\n}\n```\n\n### Delivery status\n\n```ts\nconst email = await cognizy.email.get('oe_1');\n// status: QUEUED → SENT → DELIVERED → OPENED → CLICKED, or BOUNCED / FAILED\n```\n\nStatus only ever moves forward, so a late provider event can't undo a later one.\nRather than polling, subscribe to the `email.message.status` webhook.\n\n### WhatsApp\n\nSame shape. Free-form text and media need an open 24h session window with the\nrecipient; outside it WhatsApp only accepts a template approved in your WABA:\n\n```ts\nawait cognizy.whatsapp.send({\n  to: '+5511999999999',\n  type: 'TEMPLATE',\n  template: { name: 'order_update', language: 'pt_BR', variables: ['Maria', '#1001'] },\n});\n\nconst msg = await cognizy.whatsapp.get('om_1');\n// status: QUEUED → SENT → DELIVERED → READ, or FAILED\n```\n\nNote that Meta bills WhatsApp messages directly to the card on your WhatsApp\nBusiness account — Cognizy doesn't charge per message. Platform email is\ndifferent: it leaves through Cognizy's infrastructure, so it draws on your plan's\nmonthly allowance and then your wallet. Bringing your own SendGrid or Mailgun\naccount exempts you from both.\n\n## Errors\n\nThe SDK throws typed errors for the cases you'll want to handle:\n\n```ts\nimport {\n  AuthError,\n  RateLimitError,\n  QuotaExceededError,\n  EmailQuotaExhaustedError,\n  CognizyError,\n} from '@cognizy/sdk';\n\ntry {\n  await cognizy.messages.send({ conversationId, message: 'hi' });\n} catch (err) {\n  if (err instanceof RateLimitError) {\n    await sleep(err.retryAfterSeconds ?? 60);\n  } else if (err instanceof QuotaExceededError) {\n    notifyOps(`Hit ${err.used}/${err.limit} requests this month`);\n  } else if (err instanceof EmailQuotaExhaustedError) {\n    notifyOps(`Out of email credit — ${err.details.shortfall} couldn't be sent`);\n  } else if (err instanceof AuthError) {\n    rotateKey();\n  } else if (err instanceof CognizyError) {\n    console.error(err.status, err.code, err.message);\n  }\n}\n```\n\nThe two quota errors mean different things and take different fixes:\n\n| Error | Status | Meaning | Fix |\n|---|---|---|---|\n| `QuotaExceededError` | 429 | Too many **API requests** this month | Wait, or raise the plan's request limit |\n| `EmailQuotaExhaustedError` | 400 | Out of **emails** — allowance and wallet both spent | Add wallet credit, or upgrade the plan |\n\nWaiting never clears the second one; only money does.\n\n## API reference\n\nThe full Public API is documented in Swagger UI at:\n\n```\nhttps://<your-host>/api/v1/public/docs\n```\n\n(or `/api/v1/public/openapi.json` for the raw OpenAPI spec).\n\nThe 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:\n\n| Resource | Base path | Notes |\n|---|---|---|\n| Contacts | `/api/v1/public/contacts` | List + tag management |\n| Knowledge Base | `/api/v1/public/knowledge-base` | CRUD + semantic search (RAG) |\n| Tasks & Boards | `/api/v1/public/task-boards`, `/tasks/:id` | Full kanban surface |\n| Campaigns | `/api/v1/public/campaigns` | List + per-campaign analytics |\n| Scheduling | `/api/v1/public/scheduling` | Booking pages + appointments |\n| Analytics | `/api/v1/public/analytics` | Aggregated tenant metrics |\n| Webhooks (management) | `/api/v1/public/webhooks` | Register endpoints, replay deliveries |\n\nExample — direct fetch to a non-SDK endpoint:\n\n```ts\nconst res = await fetch('https://<your-host>/api/v1/public/tasks/' + taskId, {\n  method: 'PATCH',\n  headers: {\n    'Authorization': `Bearer ${process.env.COGNIZY_API_KEY}`,\n    'Content-Type': 'application/json',\n    'Idempotency-Key': crypto.randomUUID(),\n  },\n  body: JSON.stringify({ title: 'Updated title' }),\n});\n```\n\nSDK coverage will expand over time — open an issue if a specific resource is blocking you.\n\n## Custom base URL\n\nUseful for self-hosted deployments or staging environments.\n\n```ts\nconst cognizy = new Cognizy({\n  apiKey: '…',\n  baseUrl: 'https://staging.api.cognizy.ai',\n});\n```\n\n## License\n\nMIT\n","readmeFilename":"README.md"}