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

@signaliz/sdk

v1.0.103

Published

Signaliz SDK for Campaign OS, core products, Signal Awareness, Signaliz Flow, and reusable managed builds.

Readme

@signaliz/sdk

Typed JavaScript/TypeScript access to all five core products, Signal Awareness, Signaliz Flow, and delivered managed builds through one public contract.

npm install @signaliz/sdk

Production REST endpoints:

  • https://api.signaliz.com/functions/v1/api/v1/find-email
  • https://api.signaliz.com/functions/v1/api/v1/verify-email
  • https://api.signaliz.com/functions/v1/company-signal-enrichment-v2
  • https://api.signaliz.com/functions/v1/api/v1/signal-to-copy
  • https://api.signaliz.com/functions/v1/api/v1/signals-first (/signals remains a compatibility alias)
  • https://api.signaliz.com/functions/v1/api/v1/signal-awareness/signals
  • https://api.signaliz.com/functions/v1/api/v1/signal-awareness/companies/add
  • https://api.signaliz.com/functions/v1/api/v1/signal-awareness/companies/delete
  • https://api.signaliz.com/functions/v1/api/v1/signal-awareness/companies/schedule
  • https://api.signaliz.com/functions/v1/api/v1/flow
  • https://api.signaliz.com/functions/v1/api/v1/managed-builds

The same request and response schemas are available under /api/v2/.

import { Signaliz } from '@signaliz/sdk';

const signaliz = new Signaliz({
  apiKey: process.env.SIGNALIZ_API_KEY,
});

// Every product supports a strict no-spend preflight. Batch methods accept the
// same option and return one plan for the full input.
const plan = await signaliz.findEmail({
  companyDomain: 'example.com',
  fullName: 'Jane Doe',
  dryRun: true,
});
console.log(plan.estimatedCredits.max, plan.creditsCharged); // 2, 0
// Batch plans price only semantic unique work and expose duplicate suppression.
console.log(plan.inputCount, plan.uniqueFreshInputCount, plan.inputDuplicatesSuppressed);

const found = await signaliz.findEmail({
  companyDomain: 'example.com',
  fullName: 'Jane Doe',
});

// An HTTPS LinkedIn person profile URL (/in/<slug>) is also sufficient on its own.
const foundFromLinkedIn = await signaliz.findEmail({
  linkedinUrl: 'https://www.linkedin.com/in/jane-doe',
});

const verified = await signaliz.verifyEmail(found.email!, {
});

// Syntax failures are terminal local results, with no HTTP or provider call.
const malformed = await signaliz.verifyEmail('badformat@@gmail..com');
console.log(malformed.success, malformed.isMalformed, malformed.verificationVerdict);

// The SDK waits for long checks by default. For an agent handoff, return early
// and resume the exact provider run later without duplicate spend.
const queuedVerification = await signaliz.verifyEmail('[email protected]', {
  waitForResult: false,
});
const resumedVerification = await signaliz.verifyEmail('[email protected]', {
  verificationRunId: queuedVerification.verificationRunId,
});

// Recovery reuses the original request and its public credit receipt.
console.log(resumedVerification.creditsUsed, resumedVerification.billingReplayed);

const signals = await signaliz.enrichCompanySignals({
  domain: 'example.com',
  researchPrompt: 'Find recent signals that explain why this company would use Signaliz.',
});
// Signal rows expose only the customer-facing signal fields.
console.log(
  signals.signals[0].signal_type,
  signals.signals[0].source,
  signals.signals[0].date,
);

// Signals First emits cached progress and follows the durable live-search
// shortfall to completion by default, matching the signed-in UI.
const progress = [];
const completedDiscovery = await signaliz.discoverSignalsFirst({
  query: 'companies that just got funded',
  limit: 100,
  onProgress: (receipt) => progress.push(receipt),
});
console.log(completedDiscovery.signals[0]?.domain);

// Automation can request the first queued/cached receipt without waiting.
const signalDiscovery = await signaliz.discoverSignalsFirst({
  query: 'companies that just got funded',
  limit: 100,
  waitForResult: false,
});

const copy = await signaliz.signalToCopy({
  companyDomain: 'example.com',
  personName: 'Jane Doe',
  title: 'VP Sales',
  campaignOffer: 'pipeline intelligence',
  researchPrompt: 'expansion priorities',
  enableDeepSearch: false,
});

const offerLedCopy = await signaliz.signalToCopy({
  companyDomain: 'example.com',
  personName: 'Jane Doe',
  title: 'VP Sales',
  campaignOffer: 'pipeline intelligence',
  runWithoutSignal: true,
});

await signaliz.addSignalAwarenessCompany('acme.com', 'daily');
await signaliz.changeSignalAwarenessSchedule('acme.com', 'weekly');
const awareness = await signaliz.listAllSignalAwarenessSignals('acme.com');
console.log(
  awareness.signals?.[0].signal_type,
  awareness.signals?.[0].source,
  awareness.signals?.[0].date,
  awareness.signals?.[0].company_name,
  awareness.signals?.[0].domain,
);
await signaliz.deleteSignalAwarenessCompany('acme.com');

// Flow uses the same versioned REST gateway as every other SDK capability.
const flow = await signaliz.startFlow({
  signalQuery: 'companies with recent hiring',
  campaignOffer: 'pipeline intelligence',
});
const flowStatus = await signaliz.getFlow(flow.runId);
// Re-call getFlow with the same run ID until status is completed or failed.
// Flow leaves generated copy in review and never sends outreach.

// Delivered GTM Contractor builds are workspace-owned, reusable systems.
const delivered = await signaliz.listManagedBuilds();
const build = await signaliz.getManagedBuild(delivered.builds[0].build_id);
console.log(build.build.fixed_credits_per_run, build.build.clay_credits_budget_per_run);
const managedRun = await signaliz.runManagedBuild(build.build.build_id, {
  records: [{ domain: 'example.com' }],
});
const managedResult = await signaliz.getManagedBuildRun(managedRun.run.run_id);
// Supply the same idempotency key only to recover that exact intended run.

// Company Signals and Signal to Copy are hard synchronous contracts: these
// methods return complete data, an explicit success:false result, or throw a
// non-2xx terminal error in this same call.

The four row-oriented products support bounded batch execution over the same REST endpoints. Results stay in input order, failures are isolated per item, and concurrency is limited to 1-50 (default 10):

const verifiedBatch = await signaliz.verifyEmails(emails, { concurrency: 20 });
const foundBatch = await signaliz.findEmails(contacts, { concurrency: 20 });
const signalBatch = await signaliz.enrichCompanies(companies, { concurrency: 5 });
const copyBatch = await signaliz.createSignalCopyBatch(copyRequests, { concurrency: 5 });

// If a timeout or interrupted client returns a durable job ID, resume only
// that job. These methods never submit `requests` or repeat provider work.
const resumedFoundBatch = await signaliz.resumeFindEmailBatch('job_...');
const resumedVerifiedBatch = await signaliz.resumeVerifyEmailBatch('job_...');
const resumedSignalBatch = await signaliz.resumeCompanySignalBatch('job_...');
const resumedCopyBatch = await signaliz.resumeSignalCopyBatch('job_...');

// Long Company/Copy batches can return immediately with the actual durable
// job ID and idempotency key. Persist both before yielding the agent turn.
const signalJob = await signaliz.enrichCompanies(companies, {
  waitForResult: false,
});
// { jobId, idempotencyKey, status, total, ... }

// Keep one full result for exact repeats and return duplicateOf references for
// the rest. This is lossless and avoids multiplying evidence-rich payloads.
const compactSignals = await signaliz.enrichCompanies(companies, {
  concurrency: 5,
  compactDuplicates: true,
});

Failed rows preserve errorCode, retryEligible, and retryAfterSeconds when the REST API supplies them, including after automatic row retries are exhausted.

Every single-result method treats an error payload as success: false, even if an upstream HTTP 200 omits or contradicts the success flag. This includes ok: false, non-empty error fields or error arrays, and terminal provider statuses such as timed_out or crashed; an informational message alone is not an error. Find Email withholds the email and every send-safe indicator, Verify Email withholds deliverability and confidence, and Company Signals and Signal to Copy withhold contradictory signals, narratives, and copy. Normalized error and errorCode fields explain the failure while the original response remains available in raw for audit.

For an ambiguous single request or batch submission failure, retry with the same idempotencyKey to recover the original request, durable job, or provider run without duplicate work or spend. The key is portable across REST API, MCP, SDK, and CLI calls for the same workspace and logical input. Chunked batches derive a stable key from each row's original input index, including after exact duplicate compaction and rate-limit retries.

Each batch accepts up to 5,000 items. For the four row-oriented core products, batches larger than 25 use one recoverable REST job. The SDK waits by default and retrieves every result page. Large Company Signals and Signal to Copy calls can instead set waitForResult: false to receive jobId plus the actual idempotencyKey, then resume with resumeCompanySignalBatch or resumeSignalCopyBatch. Company/Copy polling has no fixed SDK deadline unless maxWaitMs is explicitly supplied; timeout errors retain both recovery fields. Find Email and Verify Email polling defaults to 20 minutes; large email batches honor maxWaitMs and pollIntervalMs and retain the same recovery fields. Find Email, Verify Email, and Company Signals use bounded 25-row result pages; Signal to Copy uses 100-row durable pages. Retrieve completed Company/Copy pages within seven days. After cleanup, recovery fails with non-retryable BATCH_RESULTS_EXPIRED; do not automatically resubmit provider work, and require an explicit review before starting a new job. Company Signal signal_run_id recovery rows remain direct batches of at most 25, matching the recovery-read API contract instead of starting a new durable research job. Large Company Signal jobs persist bounded result pages and intentionally omit rejected candidate-evidence diagnostics. Requests with includeCandidateEvidence: true must be split into batches of at most 25. Exact duplicate tasks are single-flighted for synchronous batches. Durable Company/Copy submissions preserve every input row and its index so the server's idempotency identity remains stable across REST, MCP, SDK, and CLI recovery. Set compactDuplicates: true to return repeated successful rows as duplicateOf references; the default remains expanded for compatibility. Signal to Copy durable jobs complete missing company-signal research before generating copy. They accept uniform enableDeepSearch controls for the full job. Rows still return SIGNAL_DATA_REQUIRED when research completes without qualifying evidence. Signal to Copy also shares company research across copy recipients. Single calls and synchronous batches of at most 25 may instead pass signalSearchRunId, factId, or eventId to reuse canonical signal evidence. Durable batches of 26-5,000 reject these references rather than silently starting new research.

Signals First is query-first rather than a row batch. It defaults to 100 distinct companies and supports up to 100. Every returned signal row contains only a signal type, verified source URL, event date, company name, and domain. A request is a ceiling, not a promise: it can return fewer results when public evidence cannot verify both a date and company identity. It is included on Builder, Team, and Agency plans and can be resumed with signalSearchRunId. discoverSignalsFirst follows queued and cached-progress receipts by default; set waitForResult: false for a durable asynchronous handoff. The compatibility discoverSignals method remains single-request.

Company Signal Enrichment uses one fixed provider policy: cache first, one type-agnostic Parallel Advanced search, and at most one Extract of a first-party multi-event hub. Deterministic code enforces company identity, retrieved URLs, source quality, content-proven dates, copied evidence, lookback, and event deduplication before returning the newest ten events. It does not expose provider, model, prompt, lookback, signal-type, cache, or target-count controls. Signal to Copy AI returns three complete, evidence-backed email variations when supported signals are available. Signal to Copy defaults enableDeepSearch to false so it normally finishes within an agent turn; enable it only when deeper research is required. Every core request uses the authenticated workspace. Find Email costs 1 credit per returned result and Verify Email costs 0.02 credits per returned terminal result on every plan. Signaliz automatically reuses eligible evidence and prevents duplicate provider work. Builder, Team, Agency, and Pay-As-You-Go include Company Signals. Signal to Copy costs 1 credit per successful result on Free and Builder, and is unlimited on Team and Agency. lookbackDays remains a hard evidence-age bound. Unclassified evidence is returned by signal enrichment but is not used to generate outreach copy. Provider, billing provenance, routing, and validation internals are intentionally omitted from public signal rows.

listTools() and health() are connection helpers, not additional products.

Campaign OS agent bridge

Campaign OS is an admin-only, agent-facing control plane. Codex, Claude Code, Cursor, Devin, Grok, Signaliz Agent, or another harness can use the same SDK methods to read a bounded client Brain, autonomously build a complete provider-locked CampaignSpec, draft an Audience, compile no-call provider previews, submit consequential action requests, and inspect receipts:

const clients = await signaliz.listCampaignOsClients({ status: 'active' });
const context = await signaliz.getCampaignOsClientContext(clients.clients[0].id);
const memory = await signaliz.searchCampaignOsKnowledge({
  query: 'cache first suppression and verification',
  recordKind: 'campaign_playbook',
});
const build = await signaliz.startCampaignOsBuild({
  clientId: clients.clients[0].id,
  name: 'Realtime product launch',
  objective: 'Build an evidence-grounded 500-person campaign',
  targetCount: 500,
  agentVendor: 'codex',
  idempotencyKey: 'launch-build-v1',
});
const draft = await signaliz.createCampaignOsDraft({
  clientId: clients.clients[0].id,
  name: 'Realtime product launch',
  lane: 'realtime',
  campaignSpec,
  agentVendor: 'codex',
  idempotencyKey: 'launch-draft-v1',
});
const materialization = await signaliz.materializeCampaignOsCacheAudience({
  clientId: clients.clients[0].id,
  audienceId: '<audience-uuid>',
  campaignId: draft.campaign.id,
  targetCount: 500,
  idempotencyKey: 'launch-cache-materialization-v1',
});
const alphaPreflight = await signaliz.preflightCampaignOsAlphaMaterialization({
  clientId: clients.clients[0].id,
  campaignId: draft.campaign.id,
  audienceRunId: materialization.run.id,
  validationRunId: '<passing-alpha-validation-run-uuid>',
  idempotencyKey: 'launch-alpha-materialization-v1',
});
const alphaRun = await signaliz.startCampaignOsAlphaMaterialization({
  materializationRunId: String(alphaPreflight.run.id),
  approvalHash: String(alphaPreflight.run.approval_hash),
  confirmSpend: true,
});
const alphaStatus = await signaliz.getCampaignOsAlphaMaterialization(
  String(alphaRun.run.id),
);
const request = await signaliz.submitCampaignOsActionRequest({
  clientId: clients.clients[0].id,
  campaignId: draft.campaign.id,
  actionType: 'provider_load',
  instructions: 'Prepare this exact provider load for human review.',
  preflightInputs: {
    provider: 'instantly',
    providerArtifactId: '<provider-artifact-uuid>',
    audienceRunId: '<audience-run-uuid>',
  },
  idempotencyKey: 'launch-provider-load-request-v1',
});
// After a Signaliz superadmin approves the proposal:
const continuation = await signaliz.prepareCampaignOsActionPreflight(
  clients.clients[0].id,
  request.request.id,
);

The Agent Bridge never calls Clay, Instantly, Smartlead, or Bison while building, drafting or cache-materializing an Audience, or compiling a preview. Cache-only materialization is capped at 500 members and returns exact zero-provider/Clay usage plus a terminal reconciliation receipt. Supplying campaignId links that run to the exact campaign lifecycle. Those safe operations do not need CMM-admin approval. Drafts keep paid sourcing, provider load, activation, real-time arming, queueing, and sending locked. submitCampaignOsActionRequest() requires a nonblank idempotency key and records intent for a fresh human decision at one of those consequential boundaries; even provider_send records a request and does not execute delivery. It stores only whitelisted non-secret preflight inputs. After human approval, prepareCampaignOsActionPreflight() appends or reads one immutable no-call continuation with explicit missing fields and adapter blockers; it still does not perform the downstream preflight or any provider mutation.

Alpha materialization is the one bounded exception to the no-spend build path: its preflight is free, while startCampaignOsAlphaMaterialization() authorizes only the exact research ceiling already pinned in its immutable approval hash. It never calls Clay, creates an Audience, loads or activates a provider, queues, or sends.