@signaliz/sdk 1.0.57 → 1.0.58

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
@@ -87,7 +87,8 @@ const copy = await signaliz.signalToCopy({
87
87
  });
88
88
 
89
89
  // Company Signals and Signal to Copy are hard synchronous contracts: these
90
- // methods return complete data or throw a terminal error in this same call.
90
+ // methods return complete data, an explicit success:false result, or throw a
91
+ // non-2xx terminal error in this same call.
91
92
  ```
92
93
 
93
94
  The four row-oriented products support bounded batch execution over the same REST endpoints.
@@ -112,6 +113,12 @@ Failed rows preserve `errorCode`, `retryEligible`, and `retryAfterSeconds`
112
113
  when the REST API supplies them, including after automatic row retries are
113
114
  exhausted.
114
115
 
116
+ Every single-result method treats an error payload as `success: false`, even if
117
+ an upstream HTTP 200 omits or contradicts the success flag. Find Email also
118
+ withholds any email from a contradictory error response. Verify Email, Company
119
+ Signals, and Signal to Copy expose normalized `error` and `errorCode` fields;
120
+ the original response remains available in `raw`.
121
+
115
122
  For an ambiguous single request or batch submission failure, retry with the
116
123
  same `idempotencyKey` to recover the original request, durable job, or provider
117
124
  run without duplicate work or spend. The key is portable across REST API, MCP,
@@ -692,7 +692,7 @@ var Signaliz = class {
692
692
  }
693
693
  for (let index = 0; index < requests.length; index += 1) {
694
694
  const item = data.results[index];
695
- if (item.success === false) {
695
+ if (coreProductResponseFailed(item)) {
696
696
  if (rowRateLimitAttempt < MAX_ROW_RATE_LIMIT_RETRIES && isRetryableRowRateLimit({
697
697
  index,
698
698
  success: false,
@@ -701,7 +701,11 @@ var Signaliz = class {
701
701
  rateLimited.push({ index, params: requests[index], raw: item });
702
702
  continue;
703
703
  }
704
- results[index] = batchItemFailure(index, item.error || item.message || "Signal to Copy failed", item);
704
+ results[index] = batchItemFailure(
705
+ index,
706
+ coreProductErrorMessage(item) || "Signal to Copy failed",
707
+ item
708
+ );
705
709
  continue;
706
710
  }
707
711
  try {
@@ -802,9 +806,9 @@ var Signaliz = class {
802
806
  const raw = chunkResult.data[index];
803
807
  uniqueResults[chunk.offset + index] = {
804
808
  index: chunk.tasks[index].index,
805
- success: raw.success !== false,
809
+ success: !coreProductResponseFailed(raw),
806
810
  raw,
807
- error: raw.success === false ? raw.error || raw.message || raw.error_code || `${path} item failed` : void 0
811
+ error: coreProductResponseFailed(raw) ? coreProductErrorMessage(raw) || coreProductErrorCode(raw) || `${path} item failed` : void 0
808
812
  };
809
813
  }
810
814
  }
@@ -874,7 +878,7 @@ function batchItemFailure(index, error, raw) {
874
878
  };
875
879
  }
876
880
  function recoverableJobRowFailed(row) {
877
- return row.success === false || ["failed", "skipped"].includes(String(row._status || "").toLowerCase());
881
+ return coreProductResponseFailed(row) || ["failed", "skipped"].includes(String(row._status || "").toLowerCase());
878
882
  }
879
883
  function newBatchIdempotencyKey(label) {
880
884
  const nonce = globalThis.crypto?.randomUUID?.() || `${Date.now()}-${Math.random().toString(16).slice(2)}`;
@@ -924,7 +928,9 @@ function normalizeCoreProductDryRunResult(data) {
924
928
  };
925
929
  }
926
930
  function normalizeFindEmailResult(data) {
927
- const email = typeof data.email === "string" && data.email.trim() ? data.email.trim() : null;
931
+ const failed = coreProductResponseFailed(data);
932
+ const rawEmail = typeof data.email === "string" && data.email.trim() ? data.email.trim() : null;
933
+ const email = failed ? null : rawEmail;
928
934
  const found = Boolean(email) && data.found !== false;
929
935
  const verificationStatus = data.verification_status ?? (data.is_valid === true ? "valid" : data.status ?? "unknown");
930
936
  const rawFreshness = String(data.verification_freshness ?? "").toLowerCase();
@@ -934,7 +940,7 @@ function normalizeFindEmailResult(data) {
934
940
  const verified = !explicitlyNotSendSafe && (data.is_valid === true || data.isValid === true || data.email_verified === true || data.verified_for_sending === true || ["valid", "deliverable"].includes(String(verificationStatus).toLowerCase()));
935
941
  const verificationAgeDays = typeof data.verification_age_days === "number" && Number.isFinite(data.verification_age_days) ? data.verification_age_days : null;
936
942
  return {
937
- success: data.success !== false && found,
943
+ success: !failed && found,
938
944
  found,
939
945
  email,
940
946
  firstName: data.first_name,
@@ -961,26 +967,29 @@ function normalizeFindEmailResult(data) {
961
967
  liveProviderCalled: data.live_provider_called,
962
968
  openrouterCalled: data.openrouter_called,
963
969
  byoOpenrouterUsed: data.byo_openrouter_used,
964
- error: found ? void 0 : data.error ?? "No verified email found",
965
- errorCode: found ? void 0 : data.error_code ?? "EMAIL_NOT_FOUND",
970
+ error: found ? void 0 : coreProductErrorMessage(data) ?? "No verified email found",
971
+ errorCode: found ? void 0 : coreProductErrorCode(data) ?? "EMAIL_NOT_FOUND",
966
972
  raw: data
967
973
  };
968
974
  }
969
975
  function normalizeVerifyEmailResult(email, data) {
976
+ const failed = coreProductResponseFailed(data);
970
977
  const verificationStatus = String(data.verification_status ?? "").toLowerCase();
971
- const verified = data.email_verified === true || ["valid", "deliverable"].includes(verificationStatus);
978
+ const verified = !failed && (data.email_verified === true || ["valid", "deliverable"].includes(verificationStatus));
972
979
  return {
973
- success: data.success !== false,
980
+ success: !failed,
981
+ error: failed ? coreProductErrorMessage(data) : void 0,
982
+ errorCode: failed ? coreProductErrorCode(data) : void 0,
974
983
  email: data.email ?? email,
975
- status: String(data.status || "").toLowerCase() === "processing" ? "processing" : "completed",
984
+ status: !failed && String(data.status || "").toLowerCase() === "processing" ? "processing" : "completed",
976
985
  verificationRunId: data.verification_run_id ?? data.run_id,
977
986
  retryAfterMs: data.retry_after_ms,
978
987
  nextPollAfterSeconds: data.next_poll_after_seconds,
979
- isValid: data.is_valid ?? data.valid ?? verified,
980
- isDeliverable: data.is_deliverable ?? data.deliverable ?? verified,
988
+ isValid: failed ? false : data.is_valid ?? data.valid ?? verified,
989
+ isDeliverable: failed ? false : data.is_deliverable ?? data.deliverable ?? verified,
981
990
  isMalformed: data.is_malformed === true || data.verification_verdict === "malformed" || data.verification_status === "malformed" || data.deliverability_status === "malformed",
982
991
  isCatchAll: data.email_is_catch_all ?? data.is_catch_all ?? data.catch_all ?? data.diagnostics?.is_catch_all ?? false,
983
- verifiedForSending: data.verified_for_sending === true,
992
+ verifiedForSending: !failed && data.verified_for_sending === true,
984
993
  verificationVerdict: data.verification_verdict ?? data.verification_status ?? "unknown",
985
994
  confidenceScore: data.confidence_score ?? data.confidence ?? data.diagnostics?.confidence_score ?? (verified ? 1 : 0),
986
995
  provider: data.provider,
@@ -1025,9 +1034,12 @@ function companySignalRequestBody(params) {
1025
1034
  });
1026
1035
  }
1027
1036
  function normalizeCompanySignalResult(params, data) {
1028
- const rawSignals = data.signals ?? data.signal_feed ?? [];
1037
+ const failed = coreProductResponseFailed(data);
1038
+ const rawSignals = failed ? [] : data.signals ?? data.signal_feed ?? [];
1029
1039
  return {
1030
- success: data.success ?? true,
1040
+ success: !failed,
1041
+ error: failed ? coreProductErrorMessage(data) : void 0,
1042
+ errorCode: failed ? coreProductErrorCode(data) : void 0,
1031
1043
  status: data.status,
1032
1044
  signalRunId: data.signal_run_id ?? data.run_id ?? params.signalRunId,
1033
1045
  company: {
@@ -1324,11 +1336,15 @@ function finalizeCoreBatch(total, startedAt, round, normalize, options) {
1324
1336
  const results = new Array(total);
1325
1337
  for (const item of round) {
1326
1338
  if (!item.success || !item.raw) {
1327
- results[item.index] = batchItemFailure(
1339
+ const failure = batchItemFailure(
1328
1340
  item.index,
1329
1341
  item.error || "Signaliz batch item failed",
1330
1342
  item.raw ?? item
1331
1343
  );
1344
+ if (item.raw?.is_malformed === true) {
1345
+ failure.data = normalize(item);
1346
+ }
1347
+ results[item.index] = failure;
1332
1348
  continue;
1333
1349
  }
1334
1350
  try {
@@ -1401,17 +1417,21 @@ function validateCoreProductMaxWaitMs(value) {
1401
1417
  }
1402
1418
  }
1403
1419
  function normalizeSignalToCopyResult(data) {
1420
+ const failed = coreProductResponseFailed(data);
1404
1421
  return {
1405
- success: data.success ?? true,
1422
+ success: !failed,
1423
+ error: failed ? coreProductErrorMessage(data) : void 0,
1424
+ errorCode: failed ? coreProductErrorCode(data) : void 0,
1406
1425
  status: data.status,
1407
- runId: data.signal_run_id ?? data.run_id,
1426
+ runId: data.run_id ?? data.signal_run_id,
1427
+ companySignalRunId: data.company_signal_run_id,
1408
1428
  resumeContextPersisted: data.resume_context_persisted,
1409
- strongestSignal: data.strongest_signal ?? "",
1410
- whyNow: data.why_now ?? "",
1411
- subjectLine: data.subject_line ?? "",
1412
- openingLine: data.opening_line ?? "",
1413
- confidence: data.confidence ?? 0,
1414
- evidenceUrl: data.evidence_url ?? "",
1429
+ strongestSignal: failed ? "" : data.strongest_signal ?? "",
1430
+ whyNow: failed ? "" : data.why_now ?? "",
1431
+ subjectLine: failed ? "" : data.subject_line ?? "",
1432
+ openingLine: failed ? "" : data.opening_line ?? "",
1433
+ confidence: failed ? 0 : data.confidence ?? 0,
1434
+ evidenceUrl: failed ? "" : data.evidence_url ?? "",
1415
1435
  researchPrompt: data.research_prompt,
1416
1436
  empty: data.empty,
1417
1437
  emptyReason: data.empty_reason,
@@ -1424,7 +1444,7 @@ function normalizeSignalToCopyResult(data) {
1424
1444
  liveProviderCalled: data.live_provider_called,
1425
1445
  aiProviderCalled: data.ai_provider_called,
1426
1446
  byoAiUsed: data.byo_ai_used,
1427
- variations: (data.variations ?? []).map((variation) => ({
1447
+ variations: (failed ? [] : data.variations ?? []).map((variation) => ({
1428
1448
  style: variation.style,
1429
1449
  subjectLine: variation.subject_line ?? "",
1430
1450
  openingLine: variation.opening_line ?? "",
@@ -1436,8 +1456,32 @@ function normalizeSignalToCopyResult(data) {
1436
1456
  };
1437
1457
  }
1438
1458
  function isPendingSignalResponse(data) {
1459
+ if (coreProductResponseFailed(data)) return false;
1439
1460
  return ["triggered", "queued", "processing", "pending", "pending_version", "waiting_for_deploy"].includes(String(data.status || "").toLowerCase());
1440
1461
  }
1462
+ function coreProductResponseFailed(data) {
1463
+ if (data.success === false) return true;
1464
+ if (typeof data.error_code === "string" && data.error_code.trim()) return true;
1465
+ if (typeof data.error === "string" && data.error.trim()) return true;
1466
+ if (data.error && typeof data.error === "object" && Object.keys(data.error).length > 0) return true;
1467
+ return ["failed", "error", "cancelled", "canceled"].includes(String(data.status || "").toLowerCase());
1468
+ }
1469
+ function coreProductErrorMessage(data) {
1470
+ const nested = data.error && typeof data.error === "object" ? data.error : void 0;
1471
+ const candidates = [nested?.message, data.message, typeof data.error === "string" ? data.error : void 0];
1472
+ for (const candidate of candidates) {
1473
+ if (typeof candidate === "string" && candidate.trim()) return candidate.trim();
1474
+ }
1475
+ return void 0;
1476
+ }
1477
+ function coreProductErrorCode(data) {
1478
+ const nested = data.error && typeof data.error === "object" ? data.error : void 0;
1479
+ const candidates = [data.error_code, nested?.code, data.code];
1480
+ for (const candidate of candidates) {
1481
+ if (typeof candidate === "string" && candidate.trim()) return candidate.trim();
1482
+ }
1483
+ return void 0;
1484
+ }
1441
1485
  function assertTerminalSignalResponse(data, capability) {
1442
1486
  if (isPendingSignalResponse(data) || data.job_id) {
1443
1487
  throw new Error(`${capability} violated the synchronous response contract.`);
package/dist/index.d.mts CHANGED
@@ -116,6 +116,8 @@ interface FindEmailResult {
116
116
  }
117
117
  interface VerifyEmailResult {
118
118
  success: boolean;
119
+ error?: string;
120
+ errorCode?: string;
119
121
  email: string;
120
122
  /** Execution state. Processing results are never send-safe. */
121
123
  status: 'processing' | 'completed';
@@ -216,6 +218,8 @@ interface CompanySignal {
216
218
  }
217
219
  interface CompanySignalEnrichmentResult {
218
220
  success: boolean;
221
+ error?: string;
222
+ errorCode?: string;
219
223
  status?: string;
220
224
  signalRunId?: string;
221
225
  company: {
@@ -353,12 +357,15 @@ interface SignalToCopyVariation {
353
357
  openingLine: string;
354
358
  cta: string;
355
359
  prediction?: string;
356
- email?: string;
360
+ email: string;
357
361
  }
358
362
  interface SignalToCopyResult {
359
363
  success: boolean;
364
+ error?: string;
365
+ errorCode?: string;
360
366
  status?: string;
361
367
  runId?: string;
368
+ companySignalRunId?: string;
362
369
  resumeContextPersisted?: boolean;
363
370
  strongestSignal: string;
364
371
  whyNow: string;
package/dist/index.d.ts CHANGED
@@ -116,6 +116,8 @@ interface FindEmailResult {
116
116
  }
117
117
  interface VerifyEmailResult {
118
118
  success: boolean;
119
+ error?: string;
120
+ errorCode?: string;
119
121
  email: string;
120
122
  /** Execution state. Processing results are never send-safe. */
121
123
  status: 'processing' | 'completed';
@@ -216,6 +218,8 @@ interface CompanySignal {
216
218
  }
217
219
  interface CompanySignalEnrichmentResult {
218
220
  success: boolean;
221
+ error?: string;
222
+ errorCode?: string;
219
223
  status?: string;
220
224
  signalRunId?: string;
221
225
  company: {
@@ -353,12 +357,15 @@ interface SignalToCopyVariation {
353
357
  openingLine: string;
354
358
  cta: string;
355
359
  prediction?: string;
356
- email?: string;
360
+ email: string;
357
361
  }
358
362
  interface SignalToCopyResult {
359
363
  success: boolean;
364
+ error?: string;
365
+ errorCode?: string;
360
366
  status?: string;
361
367
  runId?: string;
368
+ companySignalRunId?: string;
362
369
  resumeContextPersisted?: boolean;
363
370
  strongestSignal: string;
364
371
  whyNow: string;
package/dist/index.js CHANGED
@@ -719,7 +719,7 @@ var Signaliz = class {
719
719
  }
720
720
  for (let index = 0; index < requests.length; index += 1) {
721
721
  const item = data.results[index];
722
- if (item.success === false) {
722
+ if (coreProductResponseFailed(item)) {
723
723
  if (rowRateLimitAttempt < MAX_ROW_RATE_LIMIT_RETRIES && isRetryableRowRateLimit({
724
724
  index,
725
725
  success: false,
@@ -728,7 +728,11 @@ var Signaliz = class {
728
728
  rateLimited.push({ index, params: requests[index], raw: item });
729
729
  continue;
730
730
  }
731
- results[index] = batchItemFailure(index, item.error || item.message || "Signal to Copy failed", item);
731
+ results[index] = batchItemFailure(
732
+ index,
733
+ coreProductErrorMessage(item) || "Signal to Copy failed",
734
+ item
735
+ );
732
736
  continue;
733
737
  }
734
738
  try {
@@ -829,9 +833,9 @@ var Signaliz = class {
829
833
  const raw = chunkResult.data[index];
830
834
  uniqueResults[chunk.offset + index] = {
831
835
  index: chunk.tasks[index].index,
832
- success: raw.success !== false,
836
+ success: !coreProductResponseFailed(raw),
833
837
  raw,
834
- error: raw.success === false ? raw.error || raw.message || raw.error_code || `${path} item failed` : void 0
838
+ error: coreProductResponseFailed(raw) ? coreProductErrorMessage(raw) || coreProductErrorCode(raw) || `${path} item failed` : void 0
835
839
  };
836
840
  }
837
841
  }
@@ -901,7 +905,7 @@ function batchItemFailure(index, error, raw) {
901
905
  };
902
906
  }
903
907
  function recoverableJobRowFailed(row) {
904
- return row.success === false || ["failed", "skipped"].includes(String(row._status || "").toLowerCase());
908
+ return coreProductResponseFailed(row) || ["failed", "skipped"].includes(String(row._status || "").toLowerCase());
905
909
  }
906
910
  function newBatchIdempotencyKey(label) {
907
911
  const nonce = globalThis.crypto?.randomUUID?.() || `${Date.now()}-${Math.random().toString(16).slice(2)}`;
@@ -951,7 +955,9 @@ function normalizeCoreProductDryRunResult(data) {
951
955
  };
952
956
  }
953
957
  function normalizeFindEmailResult(data) {
954
- const email = typeof data.email === "string" && data.email.trim() ? data.email.trim() : null;
958
+ const failed = coreProductResponseFailed(data);
959
+ const rawEmail = typeof data.email === "string" && data.email.trim() ? data.email.trim() : null;
960
+ const email = failed ? null : rawEmail;
955
961
  const found = Boolean(email) && data.found !== false;
956
962
  const verificationStatus = data.verification_status ?? (data.is_valid === true ? "valid" : data.status ?? "unknown");
957
963
  const rawFreshness = String(data.verification_freshness ?? "").toLowerCase();
@@ -961,7 +967,7 @@ function normalizeFindEmailResult(data) {
961
967
  const verified = !explicitlyNotSendSafe && (data.is_valid === true || data.isValid === true || data.email_verified === true || data.verified_for_sending === true || ["valid", "deliverable"].includes(String(verificationStatus).toLowerCase()));
962
968
  const verificationAgeDays = typeof data.verification_age_days === "number" && Number.isFinite(data.verification_age_days) ? data.verification_age_days : null;
963
969
  return {
964
- success: data.success !== false && found,
970
+ success: !failed && found,
965
971
  found,
966
972
  email,
967
973
  firstName: data.first_name,
@@ -988,26 +994,29 @@ function normalizeFindEmailResult(data) {
988
994
  liveProviderCalled: data.live_provider_called,
989
995
  openrouterCalled: data.openrouter_called,
990
996
  byoOpenrouterUsed: data.byo_openrouter_used,
991
- error: found ? void 0 : data.error ?? "No verified email found",
992
- errorCode: found ? void 0 : data.error_code ?? "EMAIL_NOT_FOUND",
997
+ error: found ? void 0 : coreProductErrorMessage(data) ?? "No verified email found",
998
+ errorCode: found ? void 0 : coreProductErrorCode(data) ?? "EMAIL_NOT_FOUND",
993
999
  raw: data
994
1000
  };
995
1001
  }
996
1002
  function normalizeVerifyEmailResult(email, data) {
1003
+ const failed = coreProductResponseFailed(data);
997
1004
  const verificationStatus = String(data.verification_status ?? "").toLowerCase();
998
- const verified = data.email_verified === true || ["valid", "deliverable"].includes(verificationStatus);
1005
+ const verified = !failed && (data.email_verified === true || ["valid", "deliverable"].includes(verificationStatus));
999
1006
  return {
1000
- success: data.success !== false,
1007
+ success: !failed,
1008
+ error: failed ? coreProductErrorMessage(data) : void 0,
1009
+ errorCode: failed ? coreProductErrorCode(data) : void 0,
1001
1010
  email: data.email ?? email,
1002
- status: String(data.status || "").toLowerCase() === "processing" ? "processing" : "completed",
1011
+ status: !failed && String(data.status || "").toLowerCase() === "processing" ? "processing" : "completed",
1003
1012
  verificationRunId: data.verification_run_id ?? data.run_id,
1004
1013
  retryAfterMs: data.retry_after_ms,
1005
1014
  nextPollAfterSeconds: data.next_poll_after_seconds,
1006
- isValid: data.is_valid ?? data.valid ?? verified,
1007
- isDeliverable: data.is_deliverable ?? data.deliverable ?? verified,
1015
+ isValid: failed ? false : data.is_valid ?? data.valid ?? verified,
1016
+ isDeliverable: failed ? false : data.is_deliverable ?? data.deliverable ?? verified,
1008
1017
  isMalformed: data.is_malformed === true || data.verification_verdict === "malformed" || data.verification_status === "malformed" || data.deliverability_status === "malformed",
1009
1018
  isCatchAll: data.email_is_catch_all ?? data.is_catch_all ?? data.catch_all ?? data.diagnostics?.is_catch_all ?? false,
1010
- verifiedForSending: data.verified_for_sending === true,
1019
+ verifiedForSending: !failed && data.verified_for_sending === true,
1011
1020
  verificationVerdict: data.verification_verdict ?? data.verification_status ?? "unknown",
1012
1021
  confidenceScore: data.confidence_score ?? data.confidence ?? data.diagnostics?.confidence_score ?? (verified ? 1 : 0),
1013
1022
  provider: data.provider,
@@ -1052,9 +1061,12 @@ function companySignalRequestBody(params) {
1052
1061
  });
1053
1062
  }
1054
1063
  function normalizeCompanySignalResult(params, data) {
1055
- const rawSignals = data.signals ?? data.signal_feed ?? [];
1064
+ const failed = coreProductResponseFailed(data);
1065
+ const rawSignals = failed ? [] : data.signals ?? data.signal_feed ?? [];
1056
1066
  return {
1057
- success: data.success ?? true,
1067
+ success: !failed,
1068
+ error: failed ? coreProductErrorMessage(data) : void 0,
1069
+ errorCode: failed ? coreProductErrorCode(data) : void 0,
1058
1070
  status: data.status,
1059
1071
  signalRunId: data.signal_run_id ?? data.run_id ?? params.signalRunId,
1060
1072
  company: {
@@ -1351,11 +1363,15 @@ function finalizeCoreBatch(total, startedAt, round, normalize, options) {
1351
1363
  const results = new Array(total);
1352
1364
  for (const item of round) {
1353
1365
  if (!item.success || !item.raw) {
1354
- results[item.index] = batchItemFailure(
1366
+ const failure = batchItemFailure(
1355
1367
  item.index,
1356
1368
  item.error || "Signaliz batch item failed",
1357
1369
  item.raw ?? item
1358
1370
  );
1371
+ if (item.raw?.is_malformed === true) {
1372
+ failure.data = normalize(item);
1373
+ }
1374
+ results[item.index] = failure;
1359
1375
  continue;
1360
1376
  }
1361
1377
  try {
@@ -1428,17 +1444,21 @@ function validateCoreProductMaxWaitMs(value) {
1428
1444
  }
1429
1445
  }
1430
1446
  function normalizeSignalToCopyResult(data) {
1447
+ const failed = coreProductResponseFailed(data);
1431
1448
  return {
1432
- success: data.success ?? true,
1449
+ success: !failed,
1450
+ error: failed ? coreProductErrorMessage(data) : void 0,
1451
+ errorCode: failed ? coreProductErrorCode(data) : void 0,
1433
1452
  status: data.status,
1434
- runId: data.signal_run_id ?? data.run_id,
1453
+ runId: data.run_id ?? data.signal_run_id,
1454
+ companySignalRunId: data.company_signal_run_id,
1435
1455
  resumeContextPersisted: data.resume_context_persisted,
1436
- strongestSignal: data.strongest_signal ?? "",
1437
- whyNow: data.why_now ?? "",
1438
- subjectLine: data.subject_line ?? "",
1439
- openingLine: data.opening_line ?? "",
1440
- confidence: data.confidence ?? 0,
1441
- evidenceUrl: data.evidence_url ?? "",
1456
+ strongestSignal: failed ? "" : data.strongest_signal ?? "",
1457
+ whyNow: failed ? "" : data.why_now ?? "",
1458
+ subjectLine: failed ? "" : data.subject_line ?? "",
1459
+ openingLine: failed ? "" : data.opening_line ?? "",
1460
+ confidence: failed ? 0 : data.confidence ?? 0,
1461
+ evidenceUrl: failed ? "" : data.evidence_url ?? "",
1442
1462
  researchPrompt: data.research_prompt,
1443
1463
  empty: data.empty,
1444
1464
  emptyReason: data.empty_reason,
@@ -1451,7 +1471,7 @@ function normalizeSignalToCopyResult(data) {
1451
1471
  liveProviderCalled: data.live_provider_called,
1452
1472
  aiProviderCalled: data.ai_provider_called,
1453
1473
  byoAiUsed: data.byo_ai_used,
1454
- variations: (data.variations ?? []).map((variation) => ({
1474
+ variations: (failed ? [] : data.variations ?? []).map((variation) => ({
1455
1475
  style: variation.style,
1456
1476
  subjectLine: variation.subject_line ?? "",
1457
1477
  openingLine: variation.opening_line ?? "",
@@ -1463,8 +1483,32 @@ function normalizeSignalToCopyResult(data) {
1463
1483
  };
1464
1484
  }
1465
1485
  function isPendingSignalResponse(data) {
1486
+ if (coreProductResponseFailed(data)) return false;
1466
1487
  return ["triggered", "queued", "processing", "pending", "pending_version", "waiting_for_deploy"].includes(String(data.status || "").toLowerCase());
1467
1488
  }
1489
+ function coreProductResponseFailed(data) {
1490
+ if (data.success === false) return true;
1491
+ if (typeof data.error_code === "string" && data.error_code.trim()) return true;
1492
+ if (typeof data.error === "string" && data.error.trim()) return true;
1493
+ if (data.error && typeof data.error === "object" && Object.keys(data.error).length > 0) return true;
1494
+ return ["failed", "error", "cancelled", "canceled"].includes(String(data.status || "").toLowerCase());
1495
+ }
1496
+ function coreProductErrorMessage(data) {
1497
+ const nested = data.error && typeof data.error === "object" ? data.error : void 0;
1498
+ const candidates = [nested?.message, data.message, typeof data.error === "string" ? data.error : void 0];
1499
+ for (const candidate of candidates) {
1500
+ if (typeof candidate === "string" && candidate.trim()) return candidate.trim();
1501
+ }
1502
+ return void 0;
1503
+ }
1504
+ function coreProductErrorCode(data) {
1505
+ const nested = data.error && typeof data.error === "object" ? data.error : void 0;
1506
+ const candidates = [data.error_code, nested?.code, data.code];
1507
+ for (const candidate of candidates) {
1508
+ if (typeof candidate === "string" && candidate.trim()) return candidate.trim();
1509
+ }
1510
+ return void 0;
1511
+ }
1468
1512
  function assertTerminalSignalResponse(data, capability) {
1469
1513
  if (isPendingSignalResponse(data) || data.job_id) {
1470
1514
  throw new Error(`${capability} violated the synchronous response contract.`);
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  Signaliz,
3
3
  SignalizError
4
- } from "./chunk-SZ3H5W5L.mjs";
4
+ } from "./chunk-EAKP4DSS.mjs";
5
5
  export {
6
6
  Signaliz,
7
7
  SignalizError
@@ -723,7 +723,7 @@ var Signaliz = class {
723
723
  }
724
724
  for (let index = 0; index < requests.length; index += 1) {
725
725
  const item = data.results[index];
726
- if (item.success === false) {
726
+ if (coreProductResponseFailed(item)) {
727
727
  if (rowRateLimitAttempt < MAX_ROW_RATE_LIMIT_RETRIES && isRetryableRowRateLimit({
728
728
  index,
729
729
  success: false,
@@ -732,7 +732,11 @@ var Signaliz = class {
732
732
  rateLimited.push({ index, params: requests[index], raw: item });
733
733
  continue;
734
734
  }
735
- results[index] = batchItemFailure(index, item.error || item.message || "Signal to Copy failed", item);
735
+ results[index] = batchItemFailure(
736
+ index,
737
+ coreProductErrorMessage(item) || "Signal to Copy failed",
738
+ item
739
+ );
736
740
  continue;
737
741
  }
738
742
  try {
@@ -833,9 +837,9 @@ var Signaliz = class {
833
837
  const raw = chunkResult.data[index];
834
838
  uniqueResults[chunk.offset + index] = {
835
839
  index: chunk.tasks[index].index,
836
- success: raw.success !== false,
840
+ success: !coreProductResponseFailed(raw),
837
841
  raw,
838
- error: raw.success === false ? raw.error || raw.message || raw.error_code || `${path2} item failed` : void 0
842
+ error: coreProductResponseFailed(raw) ? coreProductErrorMessage(raw) || coreProductErrorCode(raw) || `${path2} item failed` : void 0
839
843
  };
840
844
  }
841
845
  }
@@ -905,7 +909,7 @@ function batchItemFailure(index, error, raw) {
905
909
  };
906
910
  }
907
911
  function recoverableJobRowFailed(row) {
908
- return row.success === false || ["failed", "skipped"].includes(String(row._status || "").toLowerCase());
912
+ return coreProductResponseFailed(row) || ["failed", "skipped"].includes(String(row._status || "").toLowerCase());
909
913
  }
910
914
  function newBatchIdempotencyKey(label) {
911
915
  const nonce = globalThis.crypto?.randomUUID?.() || `${Date.now()}-${Math.random().toString(16).slice(2)}`;
@@ -955,7 +959,9 @@ function normalizeCoreProductDryRunResult(data) {
955
959
  };
956
960
  }
957
961
  function normalizeFindEmailResult(data) {
958
- const email = typeof data.email === "string" && data.email.trim() ? data.email.trim() : null;
962
+ const failed = coreProductResponseFailed(data);
963
+ const rawEmail = typeof data.email === "string" && data.email.trim() ? data.email.trim() : null;
964
+ const email = failed ? null : rawEmail;
959
965
  const found = Boolean(email) && data.found !== false;
960
966
  const verificationStatus = data.verification_status ?? (data.is_valid === true ? "valid" : data.status ?? "unknown");
961
967
  const rawFreshness = String(data.verification_freshness ?? "").toLowerCase();
@@ -965,7 +971,7 @@ function normalizeFindEmailResult(data) {
965
971
  const verified = !explicitlyNotSendSafe && (data.is_valid === true || data.isValid === true || data.email_verified === true || data.verified_for_sending === true || ["valid", "deliverable"].includes(String(verificationStatus).toLowerCase()));
966
972
  const verificationAgeDays = typeof data.verification_age_days === "number" && Number.isFinite(data.verification_age_days) ? data.verification_age_days : null;
967
973
  return {
968
- success: data.success !== false && found,
974
+ success: !failed && found,
969
975
  found,
970
976
  email,
971
977
  firstName: data.first_name,
@@ -992,26 +998,29 @@ function normalizeFindEmailResult(data) {
992
998
  liveProviderCalled: data.live_provider_called,
993
999
  openrouterCalled: data.openrouter_called,
994
1000
  byoOpenrouterUsed: data.byo_openrouter_used,
995
- error: found ? void 0 : data.error ?? "No verified email found",
996
- errorCode: found ? void 0 : data.error_code ?? "EMAIL_NOT_FOUND",
1001
+ error: found ? void 0 : coreProductErrorMessage(data) ?? "No verified email found",
1002
+ errorCode: found ? void 0 : coreProductErrorCode(data) ?? "EMAIL_NOT_FOUND",
997
1003
  raw: data
998
1004
  };
999
1005
  }
1000
1006
  function normalizeVerifyEmailResult(email, data) {
1007
+ const failed = coreProductResponseFailed(data);
1001
1008
  const verificationStatus = String(data.verification_status ?? "").toLowerCase();
1002
- const verified = data.email_verified === true || ["valid", "deliverable"].includes(verificationStatus);
1009
+ const verified = !failed && (data.email_verified === true || ["valid", "deliverable"].includes(verificationStatus));
1003
1010
  return {
1004
- success: data.success !== false,
1011
+ success: !failed,
1012
+ error: failed ? coreProductErrorMessage(data) : void 0,
1013
+ errorCode: failed ? coreProductErrorCode(data) : void 0,
1005
1014
  email: data.email ?? email,
1006
- status: String(data.status || "").toLowerCase() === "processing" ? "processing" : "completed",
1015
+ status: !failed && String(data.status || "").toLowerCase() === "processing" ? "processing" : "completed",
1007
1016
  verificationRunId: data.verification_run_id ?? data.run_id,
1008
1017
  retryAfterMs: data.retry_after_ms,
1009
1018
  nextPollAfterSeconds: data.next_poll_after_seconds,
1010
- isValid: data.is_valid ?? data.valid ?? verified,
1011
- isDeliverable: data.is_deliverable ?? data.deliverable ?? verified,
1019
+ isValid: failed ? false : data.is_valid ?? data.valid ?? verified,
1020
+ isDeliverable: failed ? false : data.is_deliverable ?? data.deliverable ?? verified,
1012
1021
  isMalformed: data.is_malformed === true || data.verification_verdict === "malformed" || data.verification_status === "malformed" || data.deliverability_status === "malformed",
1013
1022
  isCatchAll: data.email_is_catch_all ?? data.is_catch_all ?? data.catch_all ?? data.diagnostics?.is_catch_all ?? false,
1014
- verifiedForSending: data.verified_for_sending === true,
1023
+ verifiedForSending: !failed && data.verified_for_sending === true,
1015
1024
  verificationVerdict: data.verification_verdict ?? data.verification_status ?? "unknown",
1016
1025
  confidenceScore: data.confidence_score ?? data.confidence ?? data.diagnostics?.confidence_score ?? (verified ? 1 : 0),
1017
1026
  provider: data.provider,
@@ -1056,9 +1065,12 @@ function companySignalRequestBody(params) {
1056
1065
  });
1057
1066
  }
1058
1067
  function normalizeCompanySignalResult(params, data) {
1059
- const rawSignals = data.signals ?? data.signal_feed ?? [];
1068
+ const failed = coreProductResponseFailed(data);
1069
+ const rawSignals = failed ? [] : data.signals ?? data.signal_feed ?? [];
1060
1070
  return {
1061
- success: data.success ?? true,
1071
+ success: !failed,
1072
+ error: failed ? coreProductErrorMessage(data) : void 0,
1073
+ errorCode: failed ? coreProductErrorCode(data) : void 0,
1062
1074
  status: data.status,
1063
1075
  signalRunId: data.signal_run_id ?? data.run_id ?? params.signalRunId,
1064
1076
  company: {
@@ -1355,11 +1367,15 @@ function finalizeCoreBatch(total, startedAt, round, normalize, options) {
1355
1367
  const results = new Array(total);
1356
1368
  for (const item of round) {
1357
1369
  if (!item.success || !item.raw) {
1358
- results[item.index] = batchItemFailure(
1370
+ const failure = batchItemFailure(
1359
1371
  item.index,
1360
1372
  item.error || "Signaliz batch item failed",
1361
1373
  item.raw ?? item
1362
1374
  );
1375
+ if (item.raw?.is_malformed === true) {
1376
+ failure.data = normalize(item);
1377
+ }
1378
+ results[item.index] = failure;
1363
1379
  continue;
1364
1380
  }
1365
1381
  try {
@@ -1432,17 +1448,21 @@ function validateCoreProductMaxWaitMs(value) {
1432
1448
  }
1433
1449
  }
1434
1450
  function normalizeSignalToCopyResult(data) {
1451
+ const failed = coreProductResponseFailed(data);
1435
1452
  return {
1436
- success: data.success ?? true,
1453
+ success: !failed,
1454
+ error: failed ? coreProductErrorMessage(data) : void 0,
1455
+ errorCode: failed ? coreProductErrorCode(data) : void 0,
1437
1456
  status: data.status,
1438
- runId: data.signal_run_id ?? data.run_id,
1457
+ runId: data.run_id ?? data.signal_run_id,
1458
+ companySignalRunId: data.company_signal_run_id,
1439
1459
  resumeContextPersisted: data.resume_context_persisted,
1440
- strongestSignal: data.strongest_signal ?? "",
1441
- whyNow: data.why_now ?? "",
1442
- subjectLine: data.subject_line ?? "",
1443
- openingLine: data.opening_line ?? "",
1444
- confidence: data.confidence ?? 0,
1445
- evidenceUrl: data.evidence_url ?? "",
1460
+ strongestSignal: failed ? "" : data.strongest_signal ?? "",
1461
+ whyNow: failed ? "" : data.why_now ?? "",
1462
+ subjectLine: failed ? "" : data.subject_line ?? "",
1463
+ openingLine: failed ? "" : data.opening_line ?? "",
1464
+ confidence: failed ? 0 : data.confidence ?? 0,
1465
+ evidenceUrl: failed ? "" : data.evidence_url ?? "",
1446
1466
  researchPrompt: data.research_prompt,
1447
1467
  empty: data.empty,
1448
1468
  emptyReason: data.empty_reason,
@@ -1455,7 +1475,7 @@ function normalizeSignalToCopyResult(data) {
1455
1475
  liveProviderCalled: data.live_provider_called,
1456
1476
  aiProviderCalled: data.ai_provider_called,
1457
1477
  byoAiUsed: data.byo_ai_used,
1458
- variations: (data.variations ?? []).map((variation) => ({
1478
+ variations: (failed ? [] : data.variations ?? []).map((variation) => ({
1459
1479
  style: variation.style,
1460
1480
  subjectLine: variation.subject_line ?? "",
1461
1481
  openingLine: variation.opening_line ?? "",
@@ -1467,8 +1487,32 @@ function normalizeSignalToCopyResult(data) {
1467
1487
  };
1468
1488
  }
1469
1489
  function isPendingSignalResponse(data) {
1490
+ if (coreProductResponseFailed(data)) return false;
1470
1491
  return ["triggered", "queued", "processing", "pending", "pending_version", "waiting_for_deploy"].includes(String(data.status || "").toLowerCase());
1471
1492
  }
1493
+ function coreProductResponseFailed(data) {
1494
+ if (data.success === false) return true;
1495
+ if (typeof data.error_code === "string" && data.error_code.trim()) return true;
1496
+ if (typeof data.error === "string" && data.error.trim()) return true;
1497
+ if (data.error && typeof data.error === "object" && Object.keys(data.error).length > 0) return true;
1498
+ return ["failed", "error", "cancelled", "canceled"].includes(String(data.status || "").toLowerCase());
1499
+ }
1500
+ function coreProductErrorMessage(data) {
1501
+ const nested = data.error && typeof data.error === "object" ? data.error : void 0;
1502
+ const candidates = [nested?.message, data.message, typeof data.error === "string" ? data.error : void 0];
1503
+ for (const candidate of candidates) {
1504
+ if (typeof candidate === "string" && candidate.trim()) return candidate.trim();
1505
+ }
1506
+ return void 0;
1507
+ }
1508
+ function coreProductErrorCode(data) {
1509
+ const nested = data.error && typeof data.error === "object" ? data.error : void 0;
1510
+ const candidates = [data.error_code, nested?.code, data.code];
1511
+ for (const candidate of candidates) {
1512
+ if (typeof candidate === "string" && candidate.trim()) return candidate.trim();
1513
+ }
1514
+ return void 0;
1515
+ }
1472
1516
  function assertTerminalSignalResponse(data, capability) {
1473
1517
  if (isPendingSignalResponse(data) || data.job_id) {
1474
1518
  throw new Error(`${capability} violated the synchronous response contract.`);
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  Signaliz
4
- } from "./chunk-SZ3H5W5L.mjs";
4
+ } from "./chunk-EAKP4DSS.mjs";
5
5
 
6
6
  // src/mcp-config.ts
7
7
  import * as fs from "fs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@signaliz/sdk",
3
- "version": "1.0.57",
3
+ "version": "1.0.58",
4
4
  "description": "Signaliz SDK for Signals Everything, Find Email, Verify Email, Company Signal Enrichment, and Signal to Copy AI.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",