@synterai/sdk-js 0.1.1 → 0.2.0

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/dist/index.d.ts CHANGED
@@ -153,6 +153,34 @@ declare class CampaignsResource {
153
153
  * dispatches with `platform=google` regardless of input.
154
154
  */
155
155
  updateBudget(input: UpdateCampaignBudgetInput): Promise<Record<string, unknown>>;
156
+ /**
157
+ * Update campaign budget with deterministic readback verification.
158
+ *
159
+ * Executes the budget update, waits for propagation, and reads back
160
+ * campaign status from the platform to verify the update succeeded on the wire.
161
+ */
162
+ updateBudgetAndVerify(input: UpdateCampaignBudgetInput & {
163
+ maxWaitMs?: number;
164
+ pollIntervalMs?: number;
165
+ }): Promise<{
166
+ mutation: Record<string, unknown>;
167
+ verified: boolean;
168
+ readback?: Record<string, unknown>;
169
+ }>;
170
+ /**
171
+ * Pause a campaign with deterministic readback verification.
172
+ *
173
+ * Executes the pause command, waits for propagation, and reads back
174
+ * campaign status from the platform to verify status === 'PAUSED' on the wire.
175
+ */
176
+ pauseAndVerify(input: PauseCampaignInput & {
177
+ maxWaitMs?: number;
178
+ pollIntervalMs?: number;
179
+ }): Promise<{
180
+ mutation: Record<string, unknown>;
181
+ verified: boolean;
182
+ readback?: Record<string, unknown>;
183
+ }>;
156
184
  }
157
185
 
158
186
  /**
@@ -161,9 +189,7 @@ declare class CampaignsResource {
161
189
  * Both are custom-dispatch per SPEC.md's testing bar (not forced through
162
190
  * the generic argMapping-only path): get_performance has a platform-scoped
163
191
  * `onlyForPlatform` flag and a `dateRangeToDays` transform; get_daily_spend
164
- * has a fixed script name but still resolves/sends a platform, and (unlike
165
- * any other tool) also re-emits that resolved platform as an uppercased
166
- * CLI flag.
192
+ * uses the same platform-routed pull scripts with `--days` (default 7).
167
193
  */
168
194
 
169
195
  interface GetPerformanceInput {
@@ -219,7 +245,8 @@ declare class KeywordsResource {
219
245
 
220
246
  /**
221
247
  * `conversions` category — catalog.json tools: create_conversion,
222
- * list_conversions, diagnose_tracking.
248
+ * list_conversions, diagnose_tracking, get_pixel_health,
249
+ * list_event_deliveries, get_click_attribution.
223
250
  */
224
251
 
225
252
  interface CreateConversionInput {
@@ -234,6 +261,21 @@ interface DiagnoseTrackingInput {
234
261
  /** Website URL to check. */
235
262
  url: string;
236
263
  }
264
+ interface GetPixelHealthInput {
265
+ site_key?: string;
266
+ }
267
+ interface ListEventDeliveriesInput {
268
+ site_key?: string;
269
+ status?: 'PENDING' | 'SUCCESS' | 'RETRYING' | 'FAILED';
270
+ platform?: string;
271
+ limit?: number;
272
+ }
273
+ interface GetClickAttributionInput {
274
+ site_key?: string;
275
+ user_id?: number;
276
+ email?: string;
277
+ limit?: number;
278
+ }
237
279
  declare class ConversionsResource {
238
280
  private readonly client;
239
281
  constructor(client: Synter);
@@ -252,6 +294,9 @@ declare class ConversionsResource {
252
294
  * credentials (SPEC.md's "Platform resolution" rule 3).
253
295
  */
254
296
  diagnoseTracking(input: DiagnoseTrackingInput): Promise<Record<string, unknown>>;
297
+ getPixelHealth(input?: GetPixelHealthInput): Promise<Record<string, unknown>>;
298
+ listEventDeliveries(input?: ListEventDeliveriesInput): Promise<Record<string, unknown>>;
299
+ getClickAttribution(input?: GetClickAttributionInput): Promise<Record<string, unknown>>;
255
300
  }
256
301
 
257
302
  /**
@@ -421,7 +466,7 @@ declare class AudiencesResource {
421
466
  * identifiers inline when over ~500 entries.
422
467
  *
423
468
  * Bypasses the primary `tools/run` dispatcher: different host
424
- * (`https://api.syntermedia.ai`) and a different auth header
469
+ * (`https://api.synterai.com`) and a different auth header
425
470
  * (`X-Synter-Key`, not `Authorization: Bearer`) — see SPEC.md/catalog.json
426
471
  * `transport.special`.
427
472
  */
@@ -444,6 +489,127 @@ declare class AudiencesResource {
444
489
  manage(input: ManageAudienceInput): Promise<Record<string, unknown>>;
445
490
  }
446
491
 
492
+ /**
493
+ * `shield` category — Agent Shield spend limits, burst thresholds,
494
+ * circuit breakers, and kill-switch inspection.
495
+ */
496
+
497
+ interface InspectShieldInput {
498
+ platform?: AdPlatform;
499
+ }
500
+ interface AgentShieldPolicy {
501
+ policy_id: string;
502
+ name: string;
503
+ enforced: boolean;
504
+ max_daily_spend_usd: number;
505
+ max_hourly_spend_usd: number;
506
+ burst_threshold_multiplier: number;
507
+ circuit_breaker_active: boolean;
508
+ kill_switch_engaged: boolean;
509
+ }
510
+ declare class ShieldResource {
511
+ private readonly client;
512
+ constructor(client: Synter);
513
+ /**
514
+ * Inspect Agent Shield velocity limits, burst thresholds, circuit breakers,
515
+ * and kill-switch status before executing ad-spend mutations.
516
+ */
517
+ inspect(input?: InspectShieldInput): Promise<{
518
+ status: 'ACTIVE' | 'TRIPPED' | 'PAUSED';
519
+ policies: AgentShieldPolicy[];
520
+ kill_switch_engaged: boolean;
521
+ notice: string;
522
+ }>;
523
+ }
524
+
525
+ /**
526
+ * `angstrom` category — Synter Ångström attribution claim verification.
527
+ */
528
+
529
+ interface VerifyAngstromClaimInput {
530
+ platform?: AdPlatform;
531
+ claimed_conversions?: number;
532
+ claimed_revenue_usd?: number;
533
+ touchpoint_ids?: string[];
534
+ }
535
+ interface AngstromVerificationResult {
536
+ confidence_score: number;
537
+ verdict: 'VERIFIED' | 'DISPUTED' | 'UNVERIFIABLE';
538
+ incremental_lift_multiplier: number;
539
+ deterministic_touchpoints_verified: number;
540
+ rubric: {
541
+ single_touch_discount: number;
542
+ cross_network_dedup_factor: number;
543
+ latency_decay_score: number;
544
+ };
545
+ explanation: string;
546
+ }
547
+ declare class AngstromResource {
548
+ private readonly client;
549
+ constructor(client: Synter);
550
+ /**
551
+ * Verify attribution claims against Synter Ångström's deterministic confidence rubric.
552
+ */
553
+ verify(input?: VerifyAngstromClaimInput): Promise<AngstromVerificationResult>;
554
+ }
555
+
556
+ /**
557
+ * `skills` category — Core autonomous growth playbooks.
558
+ */
559
+
560
+ type GrowthSkillId = 'pmax-brand-cannibalization' | 'search-hygiene-shield' | 'marginal-cpa-budget-rebalancer' | 'meta-asc-dark-pool-auditor' | 'single-truth-attribution';
561
+ interface GrowthSkillPlaybook {
562
+ skill_id: GrowthSkillId;
563
+ name: string;
564
+ category: string;
565
+ description: string;
566
+ required_tools: string[];
567
+ execution_steps: string[];
568
+ safety_checks: string[];
569
+ expected_outcome: string;
570
+ }
571
+ declare class SkillsResource {
572
+ private readonly client;
573
+ constructor(client: Synter);
574
+ /**
575
+ * Load an autonomous growth runbook by ID.
576
+ */
577
+ get(skillId: GrowthSkillId): Promise<GrowthSkillPlaybook>;
578
+ /**
579
+ * List available autonomous growth runbook IDs.
580
+ */
581
+ list(): GrowthSkillId[];
582
+ }
583
+
584
+ /**
585
+ * `visibility` category — LLM search brand visibility and AEO share of voice.
586
+ */
587
+
588
+ interface GetVisibilityInput {
589
+ query?: string;
590
+ competitor_domains?: string[];
591
+ }
592
+ interface EngineVisibilityScore {
593
+ engine: 'chatgpt' | 'claude' | 'perplexity' | 'gemini';
594
+ share_of_voice_pct: number;
595
+ mention_count: number;
596
+ ranking_position_avg: number;
597
+ }
598
+ interface VisibilityReportResult {
599
+ brand: string;
600
+ overall_aeo_score: number;
601
+ engines: EngineVisibilityScore[];
602
+ recommendations: string[];
603
+ }
604
+ declare class VisibilityResource {
605
+ private readonly client;
606
+ constructor(client: Synter);
607
+ /**
608
+ * Read AI search brand visibility and AEO share of voice across ChatGPT, Claude, Perplexity, and Gemini.
609
+ */
610
+ get(input?: GetVisibilityInput): Promise<VisibilityReportResult>;
611
+ }
612
+
447
613
  /**
448
614
  * Amp Custom Advertising Toolbox
449
615
  *
@@ -963,19 +1129,22 @@ declare class SynterValidationError extends Error {
963
1129
  * Main Synter SDK client.
964
1130
  *
965
1131
  * Transport per SPEC.md: nearly every tool dispatches through
966
- * `POST /api/v1/tools/run` on `https://syntermedia.ai` with
1132
+ * `POST /api/v1/tools/run` on `https://synterai.com` with
967
1133
  * `{ script_name, args, platform? }`, auth via `Authorization: Bearer <key>`.
968
1134
  * Two tools bypass that dispatcher (`list_landing_pages`, `stage_audience_artifact`)
969
1135
  * — see `resources/audiences.ts` and `listLandingPages` below.
970
1136
  */
971
1137
 
972
1138
  /** Real, production base URL — see SPEC.md's "Transport" section. */
973
- declare const DEFAULT_BASE_URL = "https://syntermedia.ai";
1139
+ declare const DEFAULT_BASE_URL = "https://synterai.com";
1140
+ declare const DEFAULT_ARTIFACT_BASE_URL = "https://api.synterai.com";
974
1141
  interface SynterConfig {
975
- /** `syn_` + 32 base64url characters, issued at syntermedia.ai/developer. */
1142
+ /** `syn_` + 32 base64url characters, issued at synterai.com/developer. */
976
1143
  apiKey: string;
977
- /** Override the base URL (defaults to `https://syntermedia.ai`). Mostly for tests. */
1144
+ /** Primary API URL. Takes precedence over SYNTER_API_URL in Node.js. */
978
1145
  baseUrl?: string;
1146
+ /** Artifact API URL. Takes precedence over SYNTER_ARTIFACT_API_URL in Node.js. */
1147
+ artifactBaseUrl?: string;
979
1148
  /** Request timeout in ms. Default 30000 (30s), per SPEC.md. */
980
1149
  timeout?: number;
981
1150
  /** Max retry attempts for 429s and network/timeout errors. Default 3, per SPEC.md. */
@@ -1000,6 +1169,7 @@ interface UploadImageInput {
1000
1169
  declare class Synter {
1001
1170
  private readonly apiKey;
1002
1171
  private readonly baseUrl;
1172
+ private readonly artifactBaseUrl;
1003
1173
  private readonly timeout;
1004
1174
  private readonly maxRetries;
1005
1175
  private readonly fetchImpl;
@@ -1012,6 +1182,10 @@ declare class Synter {
1012
1182
  readonly linkedin: LinkedInResource;
1013
1183
  readonly reddit: RedditResource;
1014
1184
  readonly audiences: AudiencesResource;
1185
+ readonly shield: ShieldResource;
1186
+ readonly angstrom: AngstromResource;
1187
+ readonly skills: SkillsResource;
1188
+ readonly visibility: VisibilityResource;
1015
1189
  /** AI-powered advertising toolbox for Amp integration — unchanged, out of scope for the transport rewrite. */
1016
1190
  readonly amp: AmpToolbox;
1017
1191
  constructor(config: SynterConfig | string, ampConfig?: AmpToolboxConfig);
@@ -1045,7 +1219,9 @@ declare class Synter {
1045
1219
  */
1046
1220
  listLandingPages(): Promise<Record<string, unknown>>;
1047
1221
  private authHeaders;
1048
- /** The raw API key, for the small number of tools that need a non-Bearer header (e.g. `stage_audience_artifact`). */
1222
+ /** Artifact host used by audience staging. */
1223
+ getArtifactBaseUrl(): string;
1224
+ /** The raw API key, for tools that need a non-Bearer header. */
1049
1225
  getApiKey(): string;
1050
1226
  /**
1051
1227
  * Low-level generic HTTP helper retained for `AmpToolbox` and any other
@@ -1257,4 +1433,4 @@ declare function normalizeConversionEvent(params: {
1257
1433
  metadata?: Record<string, any>;
1258
1434
  }): AnalyticsEvent;
1259
1435
 
1260
- export { type AdPlatform, type AddKeywordsInput, type AddNegativeKeywordsInput, AmpToolbox, type AmpToolboxConfig, type AnalyticsEvent, type AnalyticsIntegration, type AnalyticsIntegrationConfig, AnalyticsIntegrationManager, type AnalyticsPlatform, AnalyticsResource, AudiencesResource, type CampaignBriefInput, CampaignsResource, type ConversionPayload, ConversionsResource, type CreateConversionInput, type CreateDisplayCampaignInput, type CreateLinkedInCampaignInput, type CreateMetaCampaignInput, type CreatePmaxCampaignInput, type CreateRedditCampaignInput, type CreateSearchCampaignInput, CreativeResource, type CreativeVariant, DEFAULT_BASE_URL, type DateRange, type DiagnoseTrackingInput, type GenerateImageInput, type GenerateVideoInput, type GeneratedCampaign, type GetDailySpendInput, type GetPerformanceInput, KeywordsResource, LinkedInResource, type ListCampaignsInput, type ManageAudienceInput, MetaResource, type OptimizationRecommendation, type PauseCampaignInput, type Platform, type PlatformConnection, type PlatformStatus, RedditResource, type StageAudienceArtifactInput, type StageAudienceArtifactResult, type SyncAudienceInput, Synter, type SynterConfig, SynterError, SynterValidationError, type TrackingParams, type UTMParameters, type UTMTemplate, type UpdateCampaignBudgetInput, type UploadImageInput, buildConversionPayload, buildTrackingURL, buildUTMParameters, Synter as default, detectClickId, extractTrackingParams, extractUTMParameters, generateDefaultUTMTemplate, normalizeAdClickEvent, normalizeConversionEvent, normalizeEventName, validateClickId, validateUTMTemplate };
1436
+ export { type AdPlatform, type AddKeywordsInput, type AddNegativeKeywordsInput, type AgentShieldPolicy, AmpToolbox, type AmpToolboxConfig, type AnalyticsEvent, type AnalyticsIntegration, type AnalyticsIntegrationConfig, AnalyticsIntegrationManager, type AnalyticsPlatform, AnalyticsResource, AngstromResource, type AngstromVerificationResult, AudiencesResource, type CampaignBriefInput, CampaignsResource, type ConversionPayload, ConversionsResource, type CreateConversionInput, type CreateDisplayCampaignInput, type CreateLinkedInCampaignInput, type CreateMetaCampaignInput, type CreatePmaxCampaignInput, type CreateRedditCampaignInput, type CreateSearchCampaignInput, CreativeResource, type CreativeVariant, DEFAULT_ARTIFACT_BASE_URL, DEFAULT_BASE_URL, type DateRange, type DiagnoseTrackingInput, type EngineVisibilityScore, type GenerateImageInput, type GenerateVideoInput, type GeneratedCampaign, type GetDailySpendInput, type GetPerformanceInput, type GetVisibilityInput, type GrowthSkillId, type GrowthSkillPlaybook, type InspectShieldInput, KeywordsResource, LinkedInResource, type ListCampaignsInput, type ManageAudienceInput, MetaResource, type OptimizationRecommendation, type PauseCampaignInput, type Platform, type PlatformConnection, type PlatformStatus, RedditResource, ShieldResource, SkillsResource, type StageAudienceArtifactInput, type StageAudienceArtifactResult, type SyncAudienceInput, Synter, type SynterConfig, SynterError, SynterValidationError, type TrackingParams, type UTMParameters, type UTMTemplate, type UpdateCampaignBudgetInput, type UploadImageInput, type VerifyAngstromClaimInput, type VisibilityReportResult, VisibilityResource, buildConversionPayload, buildTrackingURL, buildUTMParameters, Synter as default, detectClickId, extractTrackingParams, extractUTMParameters, generateDefaultUTMTemplate, normalizeAdClickEvent, normalizeConversionEvent, normalizeEventName, validateClickId, validateUTMTemplate };
package/dist/index.js CHANGED
@@ -23,18 +23,23 @@ __export(index_exports, {
23
23
  AmpToolbox: () => AmpToolbox,
24
24
  AnalyticsIntegrationManager: () => AnalyticsIntegrationManager,
25
25
  AnalyticsResource: () => AnalyticsResource,
26
+ AngstromResource: () => AngstromResource,
26
27
  AudiencesResource: () => AudiencesResource,
27
28
  CampaignsResource: () => CampaignsResource,
28
29
  ConversionsResource: () => ConversionsResource,
29
30
  CreativeResource: () => CreativeResource,
31
+ DEFAULT_ARTIFACT_BASE_URL: () => DEFAULT_ARTIFACT_BASE_URL,
30
32
  DEFAULT_BASE_URL: () => DEFAULT_BASE_URL,
31
33
  KeywordsResource: () => KeywordsResource,
32
34
  LinkedInResource: () => LinkedInResource,
33
35
  MetaResource: () => MetaResource,
34
36
  RedditResource: () => RedditResource,
37
+ ShieldResource: () => ShieldResource,
38
+ SkillsResource: () => SkillsResource,
35
39
  Synter: () => Synter,
36
40
  SynterError: () => SynterError,
37
41
  SynterValidationError: () => SynterValidationError,
42
+ VisibilityResource: () => VisibilityResource,
38
43
  buildConversionPayload: () => buildConversionPayload,
39
44
  buildTrackingURL: () => buildTrackingURL,
40
45
  buildUTMParameters: () => buildUTMParameters,
@@ -151,7 +156,7 @@ function flattenArgsToFlags(args) {
151
156
 
152
157
  // src/resources/campaigns.ts
153
158
  var LIST_CAMPAIGNS_SCRIPT_BY_PLATFORM = {
154
- google: "google_ads_list_campaigns",
159
+ google: "google_ads_get_campaigns",
155
160
  meta: "meta_ads_list_campaigns",
156
161
  linkedin: "linkedin_ads_list_campaigns",
157
162
  microsoft: "microsoft_ads_list_campaigns",
@@ -202,7 +207,7 @@ var PAUSE_CAMPAIGN_ARG_MAPPING = [
202
207
  ];
203
208
  var UPDATE_BUDGET_ARG_MAPPING = [
204
209
  { field: "campaign_id", flag: "--campaign-id", type: "string", required: true },
205
- { field: "daily_budget", flag: "--budget", type: "number", required: true }
210
+ { field: "daily_budget", flag: "--daily-budget", type: "number", required: true }
206
211
  ];
207
212
  var CampaignsResource = class {
208
213
  constructor(client) {
@@ -275,13 +280,79 @@ var CampaignsResource = class {
275
280
  const args = buildArgsFromMapping(UPDATE_BUDGET_ARG_MAPPING, input);
276
281
  return this.client.runTool("update_campaign_budget", args, "google");
277
282
  }
283
+ /**
284
+ * Update campaign budget with deterministic readback verification.
285
+ *
286
+ * Executes the budget update, waits for propagation, and reads back
287
+ * campaign status from the platform to verify the update succeeded on the wire.
288
+ */
289
+ async updateBudgetAndVerify(input) {
290
+ const mutation = await this.updateBudget(input);
291
+ const maxWaitMs = input.maxWaitMs ?? 5e3;
292
+ const pollIntervalMs = input.pollIntervalMs ?? 1e3;
293
+ const startTime = Date.now();
294
+ let lastReadback;
295
+ while (Date.now() - startTime <= maxWaitMs) {
296
+ try {
297
+ const readback = await this.list({
298
+ platform: input.platform
299
+ });
300
+ lastReadback = readback;
301
+ const campaigns = readback.campaigns || readback.data || [];
302
+ const match = campaigns.find(
303
+ (c) => String(c.id || c.campaign_id) === String(input.campaign_id)
304
+ );
305
+ if (match) {
306
+ const budget = Number(match.daily_budget_usd || match.daily_budget || match.budget);
307
+ if (Math.abs(budget - input.daily_budget) < 0.01) {
308
+ return { mutation, verified: true, readback: match };
309
+ }
310
+ }
311
+ } catch {
312
+ }
313
+ await new Promise((r) => setTimeout(r, pollIntervalMs));
314
+ }
315
+ return { mutation, verified: false, readback: lastReadback };
316
+ }
317
+ /**
318
+ * Pause a campaign with deterministic readback verification.
319
+ *
320
+ * Executes the pause command, waits for propagation, and reads back
321
+ * campaign status from the platform to verify status === 'PAUSED' on the wire.
322
+ */
323
+ async pauseAndVerify(input) {
324
+ const mutation = await this.pause(input);
325
+ const maxWaitMs = input.maxWaitMs ?? 5e3;
326
+ const pollIntervalMs = input.pollIntervalMs ?? 1e3;
327
+ const startTime = Date.now();
328
+ let lastReadback;
329
+ while (Date.now() - startTime <= maxWaitMs) {
330
+ try {
331
+ const readback = await this.list({
332
+ platform: input.platform,
333
+ status: "PAUSED"
334
+ });
335
+ lastReadback = readback;
336
+ const campaigns = readback.campaigns || readback.data || [];
337
+ const match = campaigns.find(
338
+ (c) => String(c.id || c.campaign_id) === String(input.campaign_id)
339
+ );
340
+ if (match) {
341
+ return { mutation, verified: true, readback: match };
342
+ }
343
+ } catch {
344
+ }
345
+ await new Promise((r) => setTimeout(r, pollIntervalMs));
346
+ }
347
+ return { mutation, verified: false, readback: lastReadback };
348
+ }
278
349
  };
279
350
 
280
351
  // src/resources/analytics.ts
281
352
  var GET_PERFORMANCE_SCRIPT_BY_PLATFORM = {
282
- google: "pull_google_ads_data",
353
+ google: "pull_google_ads",
283
354
  meta: "pull_meta_ads",
284
- linkedin: "pull_linkedin_ads_data",
355
+ linkedin: "pull_linkedin_ads",
285
356
  microsoft: "pull_microsoft_ads",
286
357
  reddit: "pull_reddit_ads",
287
358
  tiktok: "pull_tiktok_ads",
@@ -313,17 +384,22 @@ var AnalyticsResource = class {
313
384
  "google",
314
385
  input.platform
315
386
  );
316
- const args = buildArgsFromMapping(GET_PERFORMANCE_ARG_MAPPING, input, platform);
387
+ const args = buildArgsFromMapping(
388
+ GET_PERFORMANCE_ARG_MAPPING,
389
+ { ...input, date_range: input.date_range ?? "LAST_7_DAYS" },
390
+ platform
391
+ );
317
392
  return this.client.runTool(scriptName, args, platform);
318
393
  }
319
394
  /** Get daily spend breakdown across all connected ad accounts. */
320
395
  async getDailySpend(input = {}) {
321
- const platform = input.platform ?? "google";
322
- const args = ["--platform", platform.toUpperCase()];
323
- if (input.days !== void 0) {
324
- args.push("--days", String(input.days));
325
- }
326
- return this.client.runTool("get_account_daily_spend", args, platform);
396
+ const { platform, scriptName } = resolvePlatformScriptName(
397
+ GET_PERFORMANCE_SCRIPT_BY_PLATFORM,
398
+ "google",
399
+ input.platform
400
+ );
401
+ const days = input.days ?? 7;
402
+ return this.client.runTool(scriptName, ["--days", String(days)], platform);
327
403
  }
328
404
  };
329
405
 
@@ -363,6 +439,21 @@ var CREATE_CONVERSION_ARG_MAPPING = [
363
439
  var DIAGNOSE_TRACKING_ARG_MAPPING = [
364
440
  { field: "url", flag: "--url", type: "string", required: true }
365
441
  ];
442
+ var GET_PIXEL_HEALTH_ARG_MAPPING = [
443
+ { field: "site_key", flag: "--site-key", type: "string" }
444
+ ];
445
+ var LIST_EVENT_DELIVERIES_ARG_MAPPING = [
446
+ { field: "site_key", flag: "--site-key", type: "string" },
447
+ { field: "status", flag: "--status", type: "string" },
448
+ { field: "platform", flag: "--platform", type: "string" },
449
+ { field: "limit", flag: "--limit", type: "number" }
450
+ ];
451
+ var GET_CLICK_ATTRIBUTION_ARG_MAPPING = [
452
+ { field: "site_key", flag: "--site-key", type: "string" },
453
+ { field: "user_id", flag: "--user-id", type: "number" },
454
+ { field: "email", flag: "--email", type: "string" },
455
+ { field: "limit", flag: "--limit", type: "number" }
456
+ ];
366
457
  var ConversionsResource = class {
367
458
  constructor(client) {
368
459
  this.client = client;
@@ -388,7 +479,19 @@ var ConversionsResource = class {
388
479
  */
389
480
  async diagnoseTracking(input) {
390
481
  const args = buildArgsFromMapping(DIAGNOSE_TRACKING_ARG_MAPPING, input);
391
- return this.client.runTool("diagnose_conversion_tracking", args);
482
+ return this.client.runTool("diagnose_tracking", args);
483
+ }
484
+ async getPixelHealth(input = {}) {
485
+ const args = buildArgsFromMapping(GET_PIXEL_HEALTH_ARG_MAPPING, input);
486
+ return this.client.runTool("get_pixel_health", args);
487
+ }
488
+ async listEventDeliveries(input = {}) {
489
+ const args = buildArgsFromMapping(LIST_EVENT_DELIVERIES_ARG_MAPPING, input);
490
+ return this.client.runTool("list_event_deliveries", args);
491
+ }
492
+ async getClickAttribution(input = {}) {
493
+ const args = buildArgsFromMapping(GET_CLICK_ATTRIBUTION_ARG_MAPPING, input);
494
+ return this.client.runTool("get_click_attribution", args);
392
495
  }
393
496
  };
394
497
 
@@ -481,7 +584,6 @@ var RedditResource = class {
481
584
 
482
585
  // src/resources/audiences.ts
483
586
  var CONSENT_WARNING = "[@synterai/sdk-js] i_have_consent was not provided. Confirm lawful basis under GDPR/CCPA and the destination platform's terms for every identifier before staging or syncing PII, then pass `i_have_consent: true`. (Soft-launch notice \u2014 mirrors the backend's own behavior; this call is not blocked.)";
484
- var ARTIFACT_ENDPOINT = "https://api.syntermedia.ai/artifacts/audience-sync-input";
485
587
  var SYNC_AUDIENCE_SCRIPT_BY_PLATFORM = {
486
588
  google: "google_ads_create_customer_match",
487
589
  meta: "meta_ads_create_audience",
@@ -513,7 +615,7 @@ var AudiencesResource = class {
513
615
  * identifiers inline when over ~500 entries.
514
616
  *
515
617
  * Bypasses the primary `tools/run` dispatcher: different host
516
- * (`https://api.syntermedia.ai`) and a different auth header
618
+ * (`https://api.synterai.com`) and a different auth header
517
619
  * (`X-Synter-Key`, not `Authorization: Bearer`) — see SPEC.md/catalog.json
518
620
  * `transport.special`.
519
621
  */
@@ -528,7 +630,7 @@ var AudiencesResource = class {
528
630
  if (input.script_name !== void 0) payload.script_name = input.script_name;
529
631
  if (input.ttl_seconds !== void 0) payload.ttl_seconds = input.ttl_seconds;
530
632
  if (input.i_have_consent !== void 0) payload.i_have_consent = input.i_have_consent;
531
- return this.client.sendAbsolute(ARTIFACT_ENDPOINT, {
633
+ return this.client.sendAbsolute(`${this.client.getArtifactBaseUrl()}/artifacts/audience-sync-input`, {
532
634
  method: "POST",
533
635
  headers: {
534
636
  "X-Synter-Key": this.client.getApiKey(),
@@ -603,6 +705,91 @@ var AudiencesResource = class {
603
705
  }
604
706
  };
605
707
 
708
+ // src/resources/shield.ts
709
+ var ShieldResource = class {
710
+ constructor(client) {
711
+ this.client = client;
712
+ }
713
+ /**
714
+ * Inspect Agent Shield velocity limits, burst thresholds, circuit breakers,
715
+ * and kill-switch status before executing ad-spend mutations.
716
+ */
717
+ async inspect(input = {}) {
718
+ const args = [];
719
+ if (input.platform) {
720
+ args.push("--platform", input.platform);
721
+ }
722
+ const result = await this.client.runTool("inspect_agent_shield", args, input.platform);
723
+ return result;
724
+ }
725
+ };
726
+
727
+ // src/resources/angstrom.ts
728
+ var AngstromResource = class {
729
+ constructor(client) {
730
+ this.client = client;
731
+ }
732
+ /**
733
+ * Verify attribution claims against Synter Ångström's deterministic confidence rubric.
734
+ */
735
+ async verify(input = {}) {
736
+ const args = [];
737
+ if (input.platform) args.push("--platform", input.platform);
738
+ if (input.claimed_conversions !== void 0) args.push("--conversions", String(input.claimed_conversions));
739
+ if (input.claimed_revenue_usd !== void 0) args.push("--revenue", String(input.claimed_revenue_usd));
740
+ if (input.touchpoint_ids && input.touchpoint_ids.length > 0) {
741
+ args.push("--touchpoints", input.touchpoint_ids.join(","));
742
+ }
743
+ const result = await this.client.runTool("verify_angstrom_claim", args, input.platform);
744
+ return result;
745
+ }
746
+ };
747
+
748
+ // src/resources/skills.ts
749
+ var SkillsResource = class {
750
+ constructor(client) {
751
+ this.client = client;
752
+ }
753
+ /**
754
+ * Load an autonomous growth runbook by ID.
755
+ */
756
+ async get(skillId) {
757
+ const result = await this.client.runTool("get_skill", ["--skill-id", skillId]);
758
+ return result;
759
+ }
760
+ /**
761
+ * List available autonomous growth runbook IDs.
762
+ */
763
+ list() {
764
+ return [
765
+ "pmax-brand-cannibalization",
766
+ "search-hygiene-shield",
767
+ "marginal-cpa-budget-rebalancer",
768
+ "meta-asc-dark-pool-auditor",
769
+ "single-truth-attribution"
770
+ ];
771
+ }
772
+ };
773
+
774
+ // src/resources/visibility.ts
775
+ var VisibilityResource = class {
776
+ constructor(client) {
777
+ this.client = client;
778
+ }
779
+ /**
780
+ * Read AI search brand visibility and AEO share of voice across ChatGPT, Claude, Perplexity, and Gemini.
781
+ */
782
+ async get(input = {}) {
783
+ const args = [];
784
+ if (input.query) args.push("--query", input.query);
785
+ if (input.competitor_domains && input.competitor_domains.length > 0) {
786
+ args.push("--competitors", input.competitor_domains.join(","));
787
+ }
788
+ const result = await this.client.runTool("get_llm_visibility", args);
789
+ return result;
790
+ }
791
+ };
792
+
606
793
  // src/toolbox/amp-tools.ts
607
794
  var AmpToolbox = class {
608
795
  constructor(client, config = {}) {
@@ -836,7 +1023,8 @@ var AmpToolbox = class {
836
1023
  };
837
1024
 
838
1025
  // src/client.ts
839
- var DEFAULT_BASE_URL = "https://syntermedia.ai";
1026
+ var DEFAULT_BASE_URL = "https://synterai.com";
1027
+ var DEFAULT_ARTIFACT_BASE_URL = "https://api.synterai.com";
840
1028
  var DEFAULT_TIMEOUT_MS = 3e4;
841
1029
  var DEFAULT_MAX_RETRIES = 3;
842
1030
  var RETRY_BASE_MS = 1e3;
@@ -854,7 +1042,9 @@ var Synter = class {
854
1042
  throw new SynterValidationError("`apiKey` is required to construct a Synter client.", "apiKey");
855
1043
  }
856
1044
  this.apiKey = fullConfig.apiKey;
857
- this.baseUrl = fullConfig.baseUrl ?? DEFAULT_BASE_URL;
1045
+ const env = typeof process !== "undefined" ? process.env : void 0;
1046
+ this.baseUrl = fullConfig.baseUrl ?? (env?.SYNTER_API_URL || DEFAULT_BASE_URL);
1047
+ this.artifactBaseUrl = fullConfig.artifactBaseUrl ?? (env?.SYNTER_ARTIFACT_API_URL || DEFAULT_ARTIFACT_BASE_URL);
858
1048
  this.timeout = fullConfig.timeout ?? DEFAULT_TIMEOUT_MS;
859
1049
  this.maxRetries = fullConfig.maxRetries ?? DEFAULT_MAX_RETRIES;
860
1050
  this.fetchImpl = fullConfig.fetch ?? globalThis.fetch.bind(globalThis);
@@ -867,6 +1057,10 @@ var Synter = class {
867
1057
  this.linkedin = new LinkedInResource(this);
868
1058
  this.reddit = new RedditResource(this);
869
1059
  this.audiences = new AudiencesResource(this);
1060
+ this.shield = new ShieldResource(this);
1061
+ this.angstrom = new AngstromResource(this);
1062
+ this.skills = new SkillsResource(this);
1063
+ this.visibility = new VisibilityResource(this);
870
1064
  this.amp = new AmpToolbox(this, ampConfig);
871
1065
  }
872
1066
  // ---------------------------------------------------------------------
@@ -906,7 +1100,7 @@ var Synter = class {
906
1100
  // ---------------------------------------------------------------------
907
1101
  /** List all connected ad accounts across platforms. */
908
1102
  async listAdAccounts() {
909
- return this.runTool("google_ads_list_customers", [], "google");
1103
+ return this.runTool("google_ads_get_customers", [], "google");
910
1104
  }
911
1105
  /**
912
1106
  * Upload an image as an asset for use in ads.
@@ -945,7 +1139,11 @@ var Synter = class {
945
1139
  "Content-Type": "application/json"
946
1140
  };
947
1141
  }
948
- /** The raw API key, for the small number of tools that need a non-Bearer header (e.g. `stage_audience_artifact`). */
1142
+ /** Artifact host used by audience staging. */
1143
+ getArtifactBaseUrl() {
1144
+ return this.artifactBaseUrl;
1145
+ }
1146
+ /** The raw API key, for tools that need a non-Bearer header. */
949
1147
  getApiKey() {
950
1148
  return this.apiKey;
951
1149
  }
@@ -1434,18 +1632,23 @@ function normalizeConversionEvent(params) {
1434
1632
  AmpToolbox,
1435
1633
  AnalyticsIntegrationManager,
1436
1634
  AnalyticsResource,
1635
+ AngstromResource,
1437
1636
  AudiencesResource,
1438
1637
  CampaignsResource,
1439
1638
  ConversionsResource,
1440
1639
  CreativeResource,
1640
+ DEFAULT_ARTIFACT_BASE_URL,
1441
1641
  DEFAULT_BASE_URL,
1442
1642
  KeywordsResource,
1443
1643
  LinkedInResource,
1444
1644
  MetaResource,
1445
1645
  RedditResource,
1646
+ ShieldResource,
1647
+ SkillsResource,
1446
1648
  Synter,
1447
1649
  SynterError,
1448
1650
  SynterValidationError,
1651
+ VisibilityResource,
1449
1652
  buildConversionPayload,
1450
1653
  buildTrackingURL,
1451
1654
  buildUTMParameters,