TypeScript SDK

Typed methods for every operation. Works in Node.js and any TypeScript project.

Install

npm install nondual
# or
pnpm add nondual

Init

import { Nondual } from 'nondual';

const nd = new Nondual({ apiKey: process.env.NONDUAL_API_KEY });
// apiKey falls back to NONDUAL_API_KEY env var if omitted

nd.getContactInfo(input)

Get the full contact profile before any outreach. Returns profile, do_not_disturb flag, relationship summary, recent interactions, open followups, and recommended next action.

const res = await nd.getContactInfo({ contact: 'jane@acme.com' });

console.log(res.contact.name);               // "Jane Smith";
console.log(res.contact.do_not_disturb);     // false — safe to contact;
console.log(res.relationship_summary);       // "2 interactions. Follow-up is due.";
console.log(res.recent_interactions);        // [{ channel, occurred_at, summary }, ...];
console.log(res.open_followups);             // [{ id, action, due }, ...];
console.log(res.recommended_next_action);    // "Follow up with a proposal.";
console.log(res.enriched);                   // true if external enrichment ran

Set enrich: false for a fast workspace-only lookup:

const res = await nd.getContactInfo({ contact: 'jane@acme.com', enrich: false });

nd.recordContactInteraction(input)

Record an interaction. Optionally create a followup or complete existing ones in the same call.

const res = await nd.recordContactInteraction({
  contact: 'jane@acme.com',
  channel: 'email',
  direction: 'outbound',
  summary: 'Sent intro about partnership',
  followup_action: 'Send proposal deck',
  followup_due: '2026-08-01',
  complete_followups: 'all',   // or array of IDs
}, { agent: 'sales-bot' });

console.log(res.interaction.id);
console.log(res.followup_created);   // { id, action, due } | null;
console.log(res.followups_completed);// ["followup_..."];
console.log(res.contact_created);    // true if this was a new contact

nd.listOpenFollowups(params?)

All open followups with contact snippets. Includes do_not_disturb on each contact.

const res = await nd.listOpenFollowups({
  due_before: '2026-08-01',
  company: 'acme.com',
});

for (const f of res.followups) {
  if (f.contact.do_not_disturb) continue;
  console.log(f.action, f.due, f.contact.name);
}

nd.getCompanyActivity(input)

All contacts and recent interactions for a company domain.

const res = await nd.getCompanyActivity({ domain: 'acme.com' });

console.log(res.domain, res.total_contacts);
for (const c of res.contacts) {
  console.log(c.name, c.interactions.length);
}

Error handling

import { Nondual, NondualError } from 'nondual';

try {
  const res = await nd.getContactInfo({ contact: email });
} catch (err) {
  if (err instanceof NondualError) {
    console.error(err.status, err.code, err.message);
  }
}