@signaliz/sdk 1.0.52 → 1.0.54

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @signaliz/sdk
2
2
 
3
- Typed JavaScript/TypeScript access to the four Signaliz products.
3
+ Typed JavaScript/TypeScript access to all five core products in Signaliz.
4
4
 
5
5
  ```bash
6
6
  npm install @signaliz/sdk
@@ -12,6 +12,7 @@ Production REST endpoints:
12
12
  - `https://api.signaliz.com/functions/v1/api/v1/verify-email`
13
13
  - `https://api.signaliz.com/functions/v1/api/v1/company-signals`
14
14
  - `https://api.signaliz.com/functions/v1/api/v1/signal-to-copy`
15
+ - `https://api.signaliz.com/functions/v1/api/v1/signals`
15
16
 
16
17
  ```ts
17
18
  import { Signaliz } from '@signaliz/sdk';
@@ -59,6 +60,19 @@ const signals = await signaliz.enrichCompanySignals({
59
60
  console.log(signals.signals[0].evidencePublishedDate);
60
61
  console.log(signals.signals[0].signalFeedSource, signals.signals[0].derived);
61
62
 
63
+ // Query-first discovery returns distinct companies with dated source evidence.
64
+ // The first response is usually queued; resume only the returned run ID.
65
+ const signalDiscovery = await signaliz.discoverSignals({
66
+ query: 'companies that just got funded',
67
+ limit: 100,
68
+ sources: ['web', 'news'],
69
+ });
70
+ const completedDiscovery = signalDiscovery.signalSearchRunId
71
+ ? await signaliz.discoverSignals({ signalSearchRunId: signalDiscovery.signalSearchRunId })
72
+ : signalDiscovery;
73
+ console.log(completedDiscovery.signals[0]?.company.domain);
74
+ console.log(completedDiscovery.costGuardrail?.costPerQualifiedSignalUsd);
75
+
62
76
  const copy = await signaliz.signalToCopy({
63
77
  companyDomain: 'example.com',
64
78
  personName: 'Jane Doe',
@@ -74,7 +88,7 @@ const copy = await signaliz.signalToCopy({
74
88
  // methods return complete data or throw a terminal error in this same call.
75
89
  ```
76
90
 
77
- All four products support bounded batch execution over the same REST endpoints.
91
+ The four row-oriented products support bounded batch execution over the same REST endpoints.
78
92
  Results stay in input order, failures are isolated per item, and concurrency is
79
93
  limited to `1-50` (default `10`):
80
94
 
@@ -100,7 +114,7 @@ For an ambiguous single request or batch submission failure, retry with the
100
114
  same `idempotencyKey` to recover the original request or durable job without duplicate
101
115
  work.
102
116
 
103
- Each batch accepts up to 5,000 items. For all four core products, batches larger
117
+ Each batch accepts up to 5,000 items. For the four row-oriented core products, batches larger
104
118
  than 25 use one recoverable REST job; the SDK waits for completion and retrieves
105
119
  every result page before returning, so callers never receive queued work or
106
120
  polling instructions. Find Email, Verify Email, and Signal to Copy use 500-row
@@ -117,6 +131,16 @@ explicitly requests `skipCache` or `enableDeepSearch`, the SDK preserves that
117
131
  fresh-research behavior by using synchronous client-side chunks of at most 25.
118
132
  Signal to Copy also shares company research across copy recipients.
119
133
 
134
+ Signals Everything is query-first rather than a row batch. It defaults to 100
135
+ distinct companies and supports up to 1,000. Every returned signal contains a
136
+ company name, company domain, dated evidence, and a source URL. The typed
137
+ `costGuardrail` reports both projected and observed source acquisition cost;
138
+ Signaliz returns signals only when cost stays strictly below $0.01 per qualified
139
+ company. A request is a ceiling, not a promise: it can return fewer results
140
+ when public evidence cannot verify both a date and company identity. It is
141
+ included on Team and Agency plans and can be resumed with
142
+ `signalSearchRunId` without duplicate source acquisition.
143
+
120
144
  Company Signal Enrichment defaults `online` and `enableDeepSearch` to `true`
121
145
  unless the caller explicitly disables them. Its `searchMode` defaults to
122
146
  `balanced`; use `fast` for the primary low-latency search lane only or
@@ -129,8 +153,8 @@ only when fresh or deeper research is required.
129
153
  Unclassified evidence is returned by signal enrichment but is not used to
130
154
  generate outreach copy.
131
155
  Each normalized signal keeps `date` separate from crawl-time `detectedAt` and
132
- also exposes `datePrecision`, `hasSpecificDate`, `sourceProvenance`,
133
- `entityConfidence`, `classification`, `derived`, `evidencePublishedDate`,
134
- `signalFeedSource`, and the provider `metadata` needed for integrity audits.
156
+ also exposes customer-facing classification fields such as `datePrecision`,
157
+ `signalFamily`, `eventType`, `eventLabel`, and `classification`. Provider,
158
+ billing, cache, routing, and validation internals are intentionally omitted.
135
159
 
136
160
  `listTools()` and `health()` are connection helpers, not additional products.
@@ -39,7 +39,11 @@ function publicRetryDetails(body) {
39
39
  const details = {
40
40
  ...body?.retry_eligible !== void 0 ? { retry_eligible: body.retry_eligible } : {},
41
41
  ...body?.retry_after !== void 0 ? { retry_after: body.retry_after } : {},
42
- ...body?.retry_after_seconds !== void 0 ? { retry_after_seconds: body.retry_after_seconds } : {}
42
+ ...body?.retry_after_seconds !== void 0 ? { retry_after_seconds: body.retry_after_seconds } : {},
43
+ ...body?.run_id !== void 0 ? { run_id: body.run_id } : {},
44
+ ...body?.signal_run_id !== void 0 ? { signal_run_id: body.signal_run_id } : {},
45
+ ...body?.company_signal_run_id !== void 0 ? { company_signal_run_id: body.company_signal_run_id } : {},
46
+ ...body?.resume_context_persisted !== void 0 ? { resume_context_persisted: body.resume_context_persisted } : {}
43
47
  };
44
48
  return Object.keys(details).length > 0 ? details : void 0;
45
49
  }
@@ -464,6 +468,14 @@ var Signaliz = class {
464
468
  assertTerminalSignalResponse(data, "Company Signals");
465
469
  return normalizeCompanySignalResult(params, data);
466
470
  }
471
+ async discoverSignals(params) {
472
+ validateSignalDiscoveryParams(params);
473
+ const data = await this.client.post(
474
+ "api/v1/signals",
475
+ signalDiscoveryRequestBody(params)
476
+ );
477
+ return normalizeSignalDiscoveryResult(params, data);
478
+ }
467
479
  async enrichCompanies(companies, options) {
468
480
  validateBatchSize(companies);
469
481
  companies.forEach((params) => validateCoreProductMaxWaitMs(params.maxWaitMs));
@@ -524,10 +536,7 @@ var Signaliz = class {
524
536
  request: signalToCopyRequestBody(params)
525
537
  }));
526
538
  const uniqueRequests = deduplicated.uniqueItems;
527
- const requiresFreshResearch = uniqueRequests.some(
528
- (request) => request.skipCache === true || request.enableDeepSearch === true
529
- );
530
- const uniqueResults = uniqueRequests.length > 25 && !requiresFreshResearch ? await this.runRecoverableSignalCopyBatch(uniqueRequests, options) : await this.runSignalCopyBatchChunks(uniqueRequests, options);
539
+ const uniqueResults = await this.runSignalCopyBatchChunks(uniqueRequests, options);
531
540
  const results = requests.map((_, index) => ({
532
541
  ...uniqueResults[deduplicated.sourceIndexByInput[index]],
533
542
  index
@@ -558,7 +567,7 @@ var Signaliz = class {
558
567
  for (let offset = 0; offset < uniqueRequests.length; offset += 25) {
559
568
  chunks.push({ offset, requests: uniqueRequests.slice(offset, offset + 25) });
560
569
  }
561
- const { serverConcurrency, chunkConcurrency } = batchConcurrencyPlan(options);
570
+ const { serverConcurrency, chunkConcurrency } = batchConcurrencyPlan(options, 25, 25);
562
571
  const chunkBatch = await runBatch(
563
572
  chunks,
564
573
  (chunk) => this.runSignalCopyBatchChunk(chunk.requests, serverConcurrency),
@@ -653,35 +662,6 @@ var Signaliz = class {
653
662
  if (seen.size !== requests.length) throw new Error(`${label} batch returned incomplete indexed results`);
654
663
  return rows;
655
664
  }
656
- async runRecoverableSignalCopyBatch(requests, options) {
657
- const rows = await this.runRecoverableCoreBatchJob(
658
- "api/v1/signal-to-copy",
659
- requests.map(signalToCopyRequestBody),
660
- "Signal to Copy",
661
- 100,
662
- 20 * 6e4,
663
- options?.idempotencyKey
664
- );
665
- const results = new Array(requests.length);
666
- for (const row of rows) {
667
- const index = Number(row.index);
668
- if (recoverableJobRowFailed(row)) {
669
- results[index] = batchItemFailure(
670
- index,
671
- row.error || row._error || row.message || row.failure_reason || "Signal to Copy item failed",
672
- row
673
- );
674
- continue;
675
- }
676
- try {
677
- assertTerminalSignalResponse(row, "Signal to Copy");
678
- results[index] = { index, success: true, data: normalizeSignalToCopyResult(row) };
679
- } catch (error) {
680
- results[index] = batchItemFailure(index, error instanceof Error ? error.message : String(error), row);
681
- }
682
- }
683
- return results;
684
- }
685
665
  async runSignalCopyBatchChunk(requests, concurrency, rowRateLimitAttempt = 0) {
686
666
  const results = new Array(requests.length);
687
667
  const rateLimited = [];
@@ -731,12 +711,11 @@ var Signaliz = class {
731
711
  return results;
732
712
  }
733
713
  async runCoreBatchRound(path, tasks, options, rowRateLimitAttempt = 0) {
734
- const { serverConcurrency, chunkConcurrency } = batchConcurrencyPlan(options);
714
+ const { serverConcurrency, chunkConcurrency } = path === "api/v1/company-signals" ? batchConcurrencyPlan(options, 25, 25) : batchConcurrencyPlan(options);
735
715
  const deduplicated = dedupeExactBatchItems(tasks, (task) => JSON.stringify(task.request));
736
716
  const uniqueTasks = deduplicated.uniqueItems;
737
- const recoverableBatch = path === "api/v1/find-email" ? { label: "Find Email", pageSize: 500, maxWaitMs: 20 * 6e4 } : path === "api/v1/verify-email" ? { label: "Verify Email", pageSize: 500, maxWaitMs: 20 * 6e4 } : path === "api/v1/company-signals" ? { label: "Company Signals", pageSize: 25, maxWaitMs: 20 * 6e4 } : void 0;
738
- const containsSignalRunRecovery = path === "api/v1/company-signals" && uniqueTasks.some((task) => Boolean(task.request.signal_run_id));
739
- if (recoverableBatch && uniqueTasks.length > 25 && !containsSignalRunRecovery) {
717
+ const recoverableBatch = path === "api/v1/find-email" ? { label: "Find Email", pageSize: 500, maxWaitMs: 20 * 6e4 } : path === "api/v1/verify-email" ? { label: "Verify Email", pageSize: 500, maxWaitMs: 20 * 6e4 } : void 0;
718
+ if (path !== "api/v1/company-signals" && recoverableBatch && uniqueTasks.length > 25) {
740
719
  const rows = await this.runRecoverableCoreBatchJob(
741
720
  path,
742
721
  uniqueTasks.map((task) => task.request),
@@ -1001,6 +980,7 @@ function companySignalRequestBody(params) {
1001
980
  enable_outreach_intelligence: params.enableOutreachIntelligence,
1002
981
  enable_predictive_intelligence: params.enablePredictiveIntelligence,
1003
982
  skip_cache: params.skipCache,
983
+ include_candidate_evidence: params.includeCandidateEvidence,
1004
984
  wait_for_result: true,
1005
985
  max_wait_ms: params.maxWaitMs,
1006
986
  dry_run: params.dryRun,
@@ -1018,7 +998,6 @@ function normalizeCompanySignalResult(params, data) {
1018
998
  domain: data.company?.domain ?? params.companyDomain ?? null
1019
999
  },
1020
1000
  signals: rawSignals.map((signal) => {
1021
- const metadata = signal.metadata && typeof signal.metadata === "object" && !Array.isArray(signal.metadata) ? signal.metadata : void 0;
1022
1001
  return {
1023
1002
  id: signal.id,
1024
1003
  title: signal.title ?? "",
@@ -1027,43 +1006,160 @@ function normalizeCompanySignalResult(params, data) {
1027
1006
  date: signal.date ?? null,
1028
1007
  detectedAt: signal.detected_at ?? null,
1029
1008
  datePrecision: signal.date_precision,
1030
- hasSpecificDate: signal.has_specific_date ?? metadata?.has_specific_date,
1031
1009
  sourceUrl: signal.source_url ?? signal.url ?? null,
1032
1010
  sourceType: signal.source_type,
1033
- sourceProvenance: signal.source_provenance,
1034
1011
  confidence: signal.confidence ?? signal.confidence_score ?? null,
1035
- entityConfidence: signal.entity_confidence ?? metadata?.entity_confidence ?? null,
1036
1012
  signalFamily: signal.signal_family,
1037
1013
  eventType: signal.signal_event_type,
1038
1014
  eventLabel: signal.signal_event_label,
1039
- classification: signal.signal_classification ?? null,
1040
- derived: signal.derived === true,
1041
- evidencePublishedDate: signal.evidence_published_date ?? metadata?.evidence_published_date ?? null,
1042
- signalFeedSource: signal.signal_feed_source ?? metadata?.signal_feed_source,
1043
- metadata
1015
+ classification: signal.signal_classification ?? null
1044
1016
  };
1045
1017
  }),
1046
1018
  signalCount: data.signal_count ?? data.total_signals ?? rawSignals.length,
1047
1019
  signalSummary: data.signal_summary ?? null,
1048
- signalSummarySource: data.signal_summary_source,
1049
1020
  intelligence: data.intelligence ?? null,
1050
1021
  copyFuel: data.copy_fuel ?? null,
1051
1022
  evidenceValidation: data.evidence_validation,
1052
- evidenceSources: data.evidence_sources,
1053
- credits: data.credits,
1054
- creditsUsed: data.credits_used,
1055
- costUsd: data.cost_usd,
1056
- billingMetadata: data.billing_metadata,
1057
- resultReturnedFrom: data.result_returned_from,
1058
- cacheHit: data.cache_hit,
1059
- freshEnrichmentUsed: data.fresh_enrichment_used,
1060
- liveProviderCalled: data.live_provider_called,
1061
- aiProviderCalled: data.ai_provider_called,
1062
- byoAiUsed: data.byo_ai_used,
1063
- metadata: data.metadata,
1023
+ evidenceSources: data.metadata?.evidence_sources ?? data.evidence_sources,
1024
+ evidenceCount: data.evidence_count,
1025
+ evidenceCountTotal: data.evidence_count_total,
1026
+ evidenceSourcesOmitted: data.evidence_sources_omitted,
1027
+ evidenceScope: data.evidence_scope,
1064
1028
  raw: data
1065
1029
  };
1066
1030
  }
1031
+ var SIGNAL_DISCOVERY_SOURCES = /* @__PURE__ */ new Set(["web", "news"]);
1032
+ var SIGNAL_DISCOVERY_STATUSES = /* @__PURE__ */ new Set([
1033
+ "planned",
1034
+ "queued",
1035
+ "processing",
1036
+ "completed",
1037
+ "completed_with_warnings",
1038
+ "failed"
1039
+ ]);
1040
+ function validateSignalDiscoveryParams(params) {
1041
+ const runId = typeof params.signalSearchRunId === "string" ? params.signalSearchRunId.trim() : "";
1042
+ const query = typeof params.query === "string" ? params.query.trim() : "";
1043
+ if (!runId && !query) {
1044
+ throw new TypeError("Signals Everything requires query or signalSearchRunId");
1045
+ }
1046
+ if (query && (query.length < 2 || query.length > 2e3)) {
1047
+ throw new RangeError("query must contain between 2 and 2000 characters");
1048
+ }
1049
+ if (params.limit !== void 0 && (!Number.isInteger(params.limit) || params.limit < 1 || params.limit > 1e3)) {
1050
+ throw new RangeError("limit must be an integer between 1 and 1000");
1051
+ }
1052
+ if (params.lookbackDays !== void 0 && (!Number.isInteger(params.lookbackDays) || params.lookbackDays < 1 || params.lookbackDays > 365)) {
1053
+ throw new RangeError("lookbackDays must be an integer between 1 and 365");
1054
+ }
1055
+ if (params.sources !== void 0 && (!Array.isArray(params.sources) || params.sources.length < 1 || params.sources.length > 2 || params.sources.some((source) => !SIGNAL_DISCOVERY_SOURCES.has(source)))) {
1056
+ throw new TypeError("sources must contain only web or news");
1057
+ }
1058
+ }
1059
+ function signalDiscoveryRequestBody(params) {
1060
+ const runId = typeof params.signalSearchRunId === "string" ? params.signalSearchRunId.trim() : "";
1061
+ if (runId) {
1062
+ return compact({
1063
+ signal_search_run_id: runId,
1064
+ dry_run: params.dryRun,
1065
+ idempotency_key: params.idempotencyKey
1066
+ });
1067
+ }
1068
+ return compact({
1069
+ query: params.query?.trim(),
1070
+ limit: params.limit ?? 100,
1071
+ sources: params.sources,
1072
+ lookback_days: params.lookbackDays,
1073
+ dry_run: params.dryRun,
1074
+ idempotency_key: params.idempotencyKey
1075
+ });
1076
+ }
1077
+ function normalizeSignalDiscoveryResult(params, data) {
1078
+ const rawSignals = Array.isArray(data.signals) ? data.signals : [];
1079
+ const rawStatus = String(data.status || "").toLowerCase();
1080
+ const status = SIGNAL_DISCOVERY_STATUSES.has(rawStatus) ? rawStatus : rawSignals.length > 0 ? "completed" : "failed";
1081
+ const signals = rawSignals.map(normalizeSignalDiscoverySignal);
1082
+ return {
1083
+ success: data.success !== false,
1084
+ status,
1085
+ capability: "signals_everything",
1086
+ signalSearchRunId: String(data.signal_search_run_id ?? params.signalSearchRunId ?? ""),
1087
+ query: String(data.query ?? params.query ?? ""),
1088
+ requestedCount: Number(data.requested_count ?? params.limit ?? 100),
1089
+ nextPollAfterSeconds: typeof data.next_poll_after_seconds === "number" ? data.next_poll_after_seconds : void 0,
1090
+ signals,
1091
+ signalCount: signals.length,
1092
+ sourceLanes: Array.isArray(data.source_lanes) ? data.source_lanes.filter((lane) => typeof lane === "string") : void 0,
1093
+ evidenceValidation: data.evidence_validation && typeof data.evidence_validation === "object" ? data.evidence_validation : void 0,
1094
+ costGuardrail: normalizeSignalDiscoveryCostGuardrail(data.cost_guardrail),
1095
+ warnings: Array.isArray(data.warnings) ? data.warnings.filter((warning) => typeof warning === "string") : void 0,
1096
+ raw: data
1097
+ };
1098
+ }
1099
+ function normalizeSignalDiscoveryCostGuardrail(value) {
1100
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
1101
+ const guardrail = value;
1102
+ const maxCost = Number(guardrail.max_cost_per_qualified_signal_usd);
1103
+ const withinLimit = guardrail.within_limit === true;
1104
+ if (!Number.isFinite(maxCost)) return void 0;
1105
+ const numberOrNullable = (candidate) => {
1106
+ if (candidate === null) return null;
1107
+ const numeric = Number(candidate);
1108
+ return Number.isFinite(numeric) ? numeric : void 0;
1109
+ };
1110
+ const numberOrUndefined = (candidate) => {
1111
+ const numeric = Number(candidate);
1112
+ return Number.isFinite(numeric) ? numeric : void 0;
1113
+ };
1114
+ return {
1115
+ maxCostPerQualifiedSignalUsd: maxCost,
1116
+ projectedSourceCostUsd: numberOrNullable(guardrail.projected_source_cost_usd),
1117
+ maxSourceCostUsd: numberOrNullable(guardrail.max_source_cost_usd),
1118
+ projectedCostPerRequestedCompanySignalUsd: numberOrNullable(
1119
+ guardrail.projected_cost_per_requested_company_signal_usd
1120
+ ),
1121
+ sourceCostUsd: numberOrNullable(guardrail.source_cost_usd),
1122
+ costSource: ["observed", "catalog_bounded", "mixed", "unavailable"].includes(String(guardrail.cost_source)) ? String(guardrail.cost_source) : void 0,
1123
+ qualifiedCompanySignalCount: numberOrUndefined(guardrail.qualified_company_signal_count),
1124
+ returnedCompanySignalCount: numberOrUndefined(guardrail.returned_company_signal_count),
1125
+ costPerQualifiedSignalUsd: numberOrNullable(guardrail.cost_per_qualified_signal_usd),
1126
+ withinLimit
1127
+ };
1128
+ }
1129
+ function normalizeSignalDiscoverySignal(value) {
1130
+ const signal = value && typeof value === "object" && !Array.isArray(value) ? value : {};
1131
+ const company = signal.company && typeof signal.company === "object" && !Array.isArray(signal.company) ? signal.company : {};
1132
+ const companyName = String(company.name ?? signal.company_name ?? "").trim();
1133
+ const companyDomain = String(company.domain ?? signal.company_domain ?? "").trim();
1134
+ if (!companyName || !companyDomain) {
1135
+ throw new Error("Signals Everything response violated the company attribution contract.");
1136
+ }
1137
+ return {
1138
+ id: signal.id,
1139
+ company: {
1140
+ name: companyName,
1141
+ domain: companyDomain,
1142
+ linkedinUrl: company.linkedin_url ?? signal.company_linkedin_url ?? void 0
1143
+ },
1144
+ title: signal.title ?? "",
1145
+ type: signal.type ?? signal.signal_type ?? "unknown",
1146
+ summary: signal.summary ?? signal.content ?? signal.description ?? "",
1147
+ eventDate: signal.event_date ?? signal.date ?? signal.signal_date ?? null,
1148
+ evidence: Array.isArray(signal.evidence) ? signal.evidence.map((item) => ({
1149
+ url: String(item?.url ?? ""),
1150
+ publishedAt: String(item?.published_at ?? item?.publishedAt ?? ""),
1151
+ source: String(item?.source ?? "")
1152
+ })).filter((item) => Boolean(item.url)) : [],
1153
+ content: signal.summary ?? signal.content ?? signal.description ?? "",
1154
+ date: signal.event_date ?? signal.date ?? signal.signal_date ?? null,
1155
+ detectedAt: signal.event_date ?? signal.detected_at ?? null,
1156
+ sourceUrl: signal.source_url ?? signal.url ?? null,
1157
+ sourceType: signal.source_type ?? null,
1158
+ confidence: signal.confidence ?? signal.confidence_score ?? null,
1159
+ classification: signal.signal_classification ?? signal.classification ?? null,
1160
+ raw: signal
1161
+ };
1162
+ }
1067
1163
  function validateBatchSize(items) {
1068
1164
  if (!Array.isArray(items) || items.length === 0) {
1069
1165
  throw new Error("Signaliz batch requests require at least one item");
@@ -1079,9 +1175,9 @@ function validatedBatchConcurrency(options) {
1079
1175
  }
1080
1176
  return concurrency;
1081
1177
  }
1082
- function batchConcurrencyPlan(options) {
1083
- const concurrency = validatedBatchConcurrency(options);
1084
- const serverConcurrency = Math.min(10, concurrency);
1178
+ function batchConcurrencyPlan(options, defaultConcurrency = 10, maximumServerConcurrency = 10) {
1179
+ const concurrency = options?.concurrency === void 0 ? defaultConcurrency : validatedBatchConcurrency(options);
1180
+ const serverConcurrency = Math.min(maximumServerConcurrency, concurrency);
1085
1181
  return {
1086
1182
  serverConcurrency,
1087
1183
  chunkConcurrency: Math.max(1, Math.floor(concurrency / serverConcurrency))
package/dist/index.d.mts CHANGED
@@ -169,6 +169,8 @@ interface CompanySignalEnrichmentParams {
169
169
  enableOutreachIntelligence?: boolean;
170
170
  enablePredictiveIntelligence?: boolean;
171
171
  skipCache?: boolean;
172
+ /** Include all evaluated evidence candidates, including rejected diagnostics. Defaults to selected-signal evidence only. */
173
+ includeCandidateEvidence?: boolean;
172
174
  /** @deprecated Company Signals is always synchronous; this option is ignored. */
173
175
  waitForResult?: boolean;
174
176
  /** Maximum server-side synchronous execution window. */
@@ -188,20 +190,13 @@ interface CompanySignal {
188
190
  date?: string | null;
189
191
  detectedAt?: string | null;
190
192
  datePrecision?: string;
191
- hasSpecificDate?: boolean;
192
193
  sourceUrl?: string | null;
193
194
  sourceType?: string;
194
- sourceProvenance?: string;
195
195
  confidence?: number | null;
196
- entityConfidence?: number | null;
197
196
  signalFamily?: string;
198
197
  eventType?: string;
199
198
  eventLabel?: string;
200
199
  classification?: Record<string, unknown> | string | null;
201
- derived?: boolean;
202
- evidencePublishedDate?: string | null;
203
- signalFeedSource?: string;
204
- metadata?: Record<string, unknown>;
205
200
  }
206
201
  interface CompanySignalEnrichmentResult {
207
202
  success: boolean;
@@ -214,22 +209,89 @@ interface CompanySignalEnrichmentResult {
214
209
  signals: CompanySignal[];
215
210
  signalCount: number;
216
211
  signalSummary: string | null;
217
- signalSummarySource?: string;
218
212
  intelligence?: Record<string, unknown> | null;
219
213
  copyFuel?: Record<string, unknown> | null;
220
214
  evidenceValidation?: Record<string, unknown>;
221
215
  evidenceSources?: Record<string, unknown>[];
222
- credits?: Record<string, unknown>;
223
- creditsUsed?: number;
224
- costUsd?: number;
225
- billingMetadata?: Record<string, unknown>;
226
- resultReturnedFrom?: string;
227
- cacheHit?: boolean;
228
- freshEnrichmentUsed?: boolean;
229
- liveProviderCalled?: boolean;
230
- aiProviderCalled?: boolean;
231
- byoAiUsed?: boolean;
232
- metadata?: Record<string, unknown>;
216
+ evidenceCount?: number;
217
+ evidenceCountTotal?: number;
218
+ evidenceSourcesOmitted?: number;
219
+ evidenceScope?: 'selected_signals' | 'all_candidates';
220
+ raw: Record<string, unknown>;
221
+ }
222
+ type SignalDiscoverySource = 'web' | 'news';
223
+ type SignalDiscoveryStatus = 'planned' | 'queued' | 'processing' | 'completed' | 'completed_with_warnings' | 'failed';
224
+ interface SignalDiscoveryParams {
225
+ /** Natural-language description of the signals to find. Required for a new search. */
226
+ query?: string;
227
+ /** Number of qualified company signals requested. Defaults to 100; allowed range is 1-1,000. */
228
+ limit?: number;
229
+ /** Restrict discovery to selected source families. */
230
+ sources?: SignalDiscoverySource[];
231
+ /** Maximum signal age in days. Allowed range is 1-365. */
232
+ lookbackDays?: number;
233
+ /** Resume an existing asynchronous discovery run without starting another search. */
234
+ signalSearchRunId?: string;
235
+ /** Stable retry key for recovering the same search after an ambiguous response. */
236
+ idempotencyKey?: string;
237
+ /** Return a no-dispatch plan without provider calls or jobs. */
238
+ dryRun?: boolean;
239
+ }
240
+ interface SignalDiscoverySignal {
241
+ id?: string;
242
+ company: {
243
+ /** Every returned discovery signal is attributed to a distinct company. */
244
+ name: string;
245
+ domain: string;
246
+ linkedinUrl?: string | null;
247
+ };
248
+ title: string;
249
+ type: string;
250
+ summary: string;
251
+ eventDate?: string | null;
252
+ evidence: Array<{
253
+ url: string;
254
+ publishedAt: string;
255
+ source: string;
256
+ }>;
257
+ /** Compatibility alias for summary. */
258
+ content: string;
259
+ /** Compatibility alias for eventDate. */
260
+ date?: string | null;
261
+ detectedAt?: string | null;
262
+ sourceUrl?: string | null;
263
+ sourceType?: string | null;
264
+ confidence?: number | null;
265
+ classification?: Record<string, unknown> | string | null;
266
+ raw: Record<string, unknown>;
267
+ }
268
+ interface SignalDiscoveryCostGuardrail {
269
+ /** Strict ceiling: a qualified company signal must cost less than this amount to return. */
270
+ maxCostPerQualifiedSignalUsd: number;
271
+ projectedSourceCostUsd?: number | null;
272
+ maxSourceCostUsd?: number | null;
273
+ projectedCostPerRequestedCompanySignalUsd?: number | null;
274
+ sourceCostUsd?: number | null;
275
+ costSource?: 'observed' | 'catalog_bounded' | 'mixed' | 'unavailable';
276
+ qualifiedCompanySignalCount?: number;
277
+ returnedCompanySignalCount?: number;
278
+ costPerQualifiedSignalUsd?: number | null;
279
+ withinLimit: boolean;
280
+ }
281
+ interface SignalDiscoveryResult {
282
+ success: boolean;
283
+ status: SignalDiscoveryStatus;
284
+ capability: 'signals_everything';
285
+ signalSearchRunId: string;
286
+ query: string;
287
+ requestedCount: number;
288
+ nextPollAfterSeconds?: number;
289
+ signals: SignalDiscoverySignal[];
290
+ signalCount: number;
291
+ sourceLanes?: string[];
292
+ evidenceValidation?: Record<string, unknown>;
293
+ costGuardrail?: SignalDiscoveryCostGuardrail;
294
+ warnings?: string[];
233
295
  raw: Record<string, unknown>;
234
296
  }
235
297
  interface SignalToCopyParams {
@@ -323,6 +385,7 @@ declare class Signaliz {
323
385
  dryRun: true;
324
386
  }): Promise<CoreProductDryRunResult>;
325
387
  enrichCompanySignals(params: CompanySignalEnrichmentParams): Promise<CompanySignalEnrichmentResult>;
388
+ discoverSignals(params: SignalDiscoveryParams): Promise<SignalDiscoveryResult>;
326
389
  enrichCompanies(companies: CompanySignalEnrichmentParams[], options: BatchOptions & {
327
390
  dryRun: true;
328
391
  }): Promise<CoreProductDryRunResult>;
@@ -338,11 +401,10 @@ declare class Signaliz {
338
401
  private runCoreProductDryRun;
339
402
  private runSignalCopyBatchChunks;
340
403
  private runRecoverableCoreBatchJob;
341
- private runRecoverableSignalCopyBatch;
342
404
  private runSignalCopyBatchChunk;
343
405
  private runCoreBatchRound;
344
406
  listTools(): Promise<MCPToolInfo[]>;
345
407
  health(): Promise<PlatformHealth>;
346
408
  }
347
409
 
348
- export { type BatchItemResult, type BatchOptions, type BatchResult, type CompanySignal, type CompanySignalEnrichmentParams, type CompanySignalEnrichmentResult, type ErrorType, type FindEmailParams, type FindEmailResult, type MCPToolInfo, type PlatformHealth, type SignalToCopyParams, type SignalToCopyResult, type SignalToCopyVariation, Signaliz, type SignalizConfig, SignalizError, type SignalizErrorData, type VerifyEmailBatchOptions, type VerifyEmailOptions, type VerifyEmailResult };
410
+ export { type BatchItemResult, type BatchOptions, type BatchResult, type CompanySignal, type CompanySignalEnrichmentParams, type CompanySignalEnrichmentResult, type ErrorType, type FindEmailParams, type FindEmailResult, type MCPToolInfo, type PlatformHealth, type SignalDiscoveryParams, type SignalDiscoveryResult, type SignalDiscoverySignal, type SignalDiscoverySource, type SignalDiscoveryStatus, type SignalToCopyParams, type SignalToCopyResult, type SignalToCopyVariation, Signaliz, type SignalizConfig, SignalizError, type SignalizErrorData, type VerifyEmailBatchOptions, type VerifyEmailOptions, type VerifyEmailResult };