@getnexorai/sdk
v0.1.7
Published
Official JavaScript SDK for Nexor — AI-led omni-channel contactability for your leads. REST client + embeddable chat widget.
Readme
@getnexorai/sdk
Official JavaScript SDK for Nexor — AI-led omni-channel contactability for your leads. One package, two things:
- REST client.
nexor.init({ apiKey })thennexor.createLead(...),nexor.getLead(...),nexor.sendMessage(...), etc. Works in Node 18+ and modern browsers. - Embeddable chat widget.
nexor.initChat({ workflowId })drops a chat bubble in the bottom-right of any web page. Visitors chat; you get a real Nexor lead + AI-driven conversation; cadence follow-ups happen on WhatsApp/email/voice as usual.
Full API reference: https://docs.getnexor.ai
Install
npm install @getnexorai/sdk
# or
pnpm add @getnexorai/sdk
# or
yarn add @getnexorai/sdkOr use it script-tag-style with no build:
<script src="https://unpkg.com/@getnexorai/sdk/dist/nexor.iife.js"></script>
<script>
Nexor.init({ apiKey: "nxr_live_…" });
</script>Quick start — push a lead from Node
import nexor from "@getnexorai/sdk";
nexor.init({ apiKey: process.env.NEXOR_API_KEY });
const { lead, workflow_run } = await nexor.createLead({
first_name: "Ada",
last_name: "Lovelace",
email: "[email protected]",
phone: "+1 555 0100",
workflow_id: "your-workflow-uuid",
metadata: { plan: "trial", utm_source: "google" },
});
console.log("Created lead:", lead.id);
console.log("Workflow run:", workflow_run?.id);That's it. Nexor's AI agent will now reach out on the channels configured in the workflow.
Quick start — embed a chat widget
<script src="https://unpkg.com/@getnexorai/sdk/dist/nexor.iife.js"></script>
<script>
Nexor.init({ apiKey: "nxr_live_…" });
Nexor.initChat({
workflowId: "your-workflow-uuid",
title: "Talk to our team",
accentColor: "#4f46e5",
systemPrompt: "You are a friendly sales assistant for Acme Corp.",
capture: { fields: ["first_name", "email"] },
});
</script>A chat bubble appears in the bottom-right. Visitors fill the (configurable) capture form, chat with your AI agent, and become real leads in your Nexor account — primed for follow-up on WhatsApp/email/voice.
API
Initialisation
nexor.init({
apiKey: string; // required
baseUrl?: string; // default "https://api.getnexor.ai"
timeoutMs?: number; // default 30_000
maxRetries?: number; // default 2 (retries on 429 + 5xx + network errors)
fetch?: typeof fetch; // override (e.g. for tests / Node <18)
userAgentSuffix?: string;
});For multi-tenant / server-side use where a singleton doesn't fit, instantiate the client directly:
import { NexorClient } from "@getnexorai/sdk";
const client = new NexorClient({ apiKey });
await client.createLead({ first_name: "Ada", … });Leads
nexor.createLead(input)
nexor.createLeadsBulk(inputs) // up to 1,000 per call
nexor.updateLead(leadId, updates) // metadata is shallow-merged server-side
nexor.getLead(leadId) // lead + collected variables + per-channel engagement
nexor.getLeadHistory(leadId, { channel, limit, offset })
nexor.syncLeadTags({ lead_id | email, tags }) // tags param is the full active set; [] clears
nexor.isLeadPaused(leadId, { workflow_id })
nexor.stopAutomation(leadId, { workflow_id }) // human takeover
nexor.resumeAutomation(leadId, { workflow_id, resume_cadence })
nexor.listLeadMeetings(leadId, { status })createLead accepts an optional force_first_message: { channel, content, subject?, sender_id? } that pushes the very first message synchronously (WhatsApp or email) rather than waiting for cadence.
Workflows / Campaigns / Templates
nexor.listWorkflows()
nexor.listCampaigns()
nexor.listTemplates({ status, category })Messages
nexor.sendMessage({
lead_id, workflow_id,
channel: "whatsapp" | "email" | "call",
content?: string, // free-form text (whatsapp/email)
html?: string, // email body
subject?: string, // email subject
template_id?: string, // whatsapp template (alternative to content)
components?: unknown, // whatsapp template parameters
begin_message?: string, // first utterance for outbound calls
});Meetings
nexor.createMeeting({ lead_email, title, starts_at, duration_minutes, … });
nexor.createMeetingNotes({ lead_email, notes, transcript_text, summary, action_items, … });Chat widget
nexor.initChat({
// Required
workflowId: string;
// Branding
title?: string; // header text
subtitle?: string; // small line below header
greeting?: string; // first bot message
accentColor?: string; // hex, default "#111827"
accentTextColor?: string; // hex, default "#ffffff"
showBranding?: boolean; // "Powered by Nexor" footer, default true
// Behaviour
position?: "bottom-right" | "bottom-left";
openOnLoad?: boolean;
container?: HTMLElement; // default document.body
// Speed-dial channels (optional) — hover (desktop) or tap (mobile) the
// launcher and it fans out round buttons instead of opening chat right away.
// Only the channels you supply are shown, in the order listed. On phones the
// chat panel opens full-screen with a clear close button in the header.
channels?: {
whatsapp?: string; // "+56912345678" → opens wa.me
whatsappText?: string; // pre-filled WhatsApp message
call?: string; // "+56912345678" → tel:
email?: string; // → mailto:
instagram?: string; // handle "nexor.ai" or full URL
chat?: boolean; // include an "open chat" button, default true
order?: ("whatsapp" | "call" | "email" | "instagram" | "chat")[];
labels?: Partial<Record<"whatsapp"|"call"|"email"|"instagram"|"chat", string>>;
};
// Per-widget prompt overrides — forwarded to the agent on every turn
systemPrompt?: string;
clientPrompt?: string;
// Lead linking
lead?: { first_name?, last_name?, email?, phone?, metadata? }; // pre-known visitor → skips capture
capture?: {
fields?: ("first_name" | "last_name" | "email" | "phone")[]; // default ["first_name", "email"]
mode?: "before" | "skip"; // default "before"
label?: string;
submitLabel?: string;
};
metadata?: Record<string, unknown>; // attached to every turn (page URL, UTM, …)
// Callbacks
onOpen?: () => void;
onClose?: () => void;
onMessage?: ({ role, text }) => void;
onLeadCaptured?: (leadId) => void;
onError?: (err) => void;
});Returns a handle:
const chat = nexor.initChat({ … });
chat.open();
chat.close();
chat.toggle();
await chat.send("Hello from JS"); // programmatic message
chat.destroy();
chat.getSessionId(); // stable per-browser id (persisted to localStorage)How it works under the hood
Each turn POSTs to /api/public/chat with:
{
"workflow_id": "…",
"session_id": "sess_…", // generated + persisted by the SDK
"message": "user text",
"system_prompt": "…", // optional override
"client_prompt": "…", // optional override
"lead": { "first_name": "Ada", "email": "[email protected]" },
"metadata": { "page_url": "…" }
}The server matches/creates a web-chat lead, runs the workflow's AI agent, and returns:
{ "success": true, "reply": "…", "session_id": "…", "lead_id": "…", "workflow_run_id": "…" }Subsequent turns reuse the same session and lead — including across page reloads.
Errors
All API failures throw a NexorAPIError (or one of its subclasses):
import { NexorAPIError, NexorAuthError, NexorValidationError, NexorNetworkError } from "@getnexorai/sdk";
try {
await nexor.createLead({ first_name: "" });
} catch (err) {
if (err instanceof NexorValidationError) {
console.error("Bad input:", err.message);
} else if (err instanceof NexorAuthError) {
console.error("API key rejected");
} else if (err instanceof NexorAPIError) {
console.error(`HTTP ${err.status}: ${err.message}`, err.requestId);
} else if (err instanceof NexorNetworkError) {
console.error("Network problem:", err.cause);
}
}429 and 5xx responses are automatically retried with exponential backoff (configurable via maxRetries). Honors Retry-After.
Examples
examples/node-create-lead.mjs— push leads from a Node script.examples/browser-chat.html— embed the chat widget via script tag.
Building from source
npm install
npm run typecheck
npm run build # outputs dist/{index.js,index.cjs,chat.js,chat.cjs,nexor.iife.js} + .d.tsLicense
MIT
