
Company News
Jerod Santo Joins Socket as Head of Media
Allow myself to introduce... myself.
@synterai/sdk-js
Advanced tools
TypeScript SDK for the Synter advertising API — manage campaigns across Google Ads, Meta, LinkedIn, Reddit, Microsoft, TikTok, and X
TypeScript SDK for the Synter advertising API — manage campaigns across Google Ads, Meta, LinkedIn, Microsoft Ads, Reddit, TikTok, and X from your own code, with full types and IDE autocomplete.
0.1.0— early release. Live on npm and installable, but pre-1.0: the surface may change before a stable1.0. Pin a version in production.
Every method in this SDK calls the same live, production endpoint that powers Synter's MCP server (@synterai/mcp-server) and the synter CLI: POST https://syntermedia.ai/api/v1/tools/run. There is no separate "SDK backend" — if a method works here, it works because the exact same call already works for every MCP client (Claude, Cursor, Codex, ChatGPT) today.
See ../sdk-shared/SPEC.md and ../sdk-shared/catalog.json for the full transport contract this SDK — and every sibling-language SDK — implements.
npm install @synterai/sdk-js
Get an API key at syntermedia.ai/developer. Keys look like syn_ followed by 32 base64url characters.
⚠️ Server-side only. Your
SYNTER_API_KEYis a secret that can spend money and modify your ad accounts. Use this SDK from a backend — a Node service, a Next.js API route or Server Action, an edge/serverless function. Never instantiateSynterin client-side code (React components, browser bundles, mobile apps); the key would ship to every visitor. For a React/SPA frontend, call your own backend, and have the backend call Synter.
import { Synter } from '@synterai/sdk-js';
const synter = new Synter(process.env.SYNTER_API_KEY!);
// or, with options:
const synter = new Synter({
apiKey: process.env.SYNTER_API_KEY!,
timeout: 30_000, // ms, default 30s
maxRetries: 3, // default 3
});
import { Synter } from '@synterai/sdk-js';
const synter = new Synter(process.env.SYNTER_API_KEY!);
// List campaigns (defaults to Google if no platform is given)
const campaigns = await synter.campaigns.list({ status: 'ENABLED', limit: 10 });
// Create a Google Search campaign
await synter.campaigns.createSearch({
campaign_name: 'Q4 Launch',
daily_budget: 50,
keywords: ['running shoes'],
headlines: ['Fast. Light. Yours.', 'New Season, New PR', 'Free Shipping Today'],
descriptions: ['Premium running shoes built for speed.', 'Order today, ships free.'],
final_url: 'https://example.com/shoes',
});
// Pull performance metrics
const perf = await synter.analytics.getPerformance({ date_range: 'LAST_30_DAYS' });
// Generate an AI creative
const image = await synter.creative.generateImage({ prompt: 'a running shoe on a cloud, product photography' });
// Escape hatch: call any of the 140+ backend scripts by name
await synter.execute('google_ads_list_audiences', { status: 'ENABLED' }, 'google');
Methods are grouped by category, matching the tool catalog:
| Namespace | Methods |
|---|---|
synter.campaigns | list, createSearch, createDisplay, createPmax, pause, updateBudget |
synter.analytics | getPerformance, getDailySpend |
synter.keywords | add, addNegative |
synter.conversions | create, list, diagnoseTracking |
synter.creative | generateImage, generateVideo |
synter.meta | createCampaign |
synter.linkedin | createCampaign |
synter.reddit | createCampaign |
synter.audiences | stageArtifact, sync, manage |
synter (top level) | listAdAccounts, uploadImage, listLandingPages, execute |
Every method takes a fully-typed input object (required fields are non-optional in TypeScript) and returns Promise<Record<string, unknown>> — the backend scripts return script-specific JSON that isn't worth over-narrowing today.
synter.execute(scriptName, args, platform?) is the universal escape hatch: it can call any of the 140+ backend scripts beyond the typed methods above, converting an idiomatic {flagName: value} map into the CLI-flag wire format internally.
import { SynterError, SynterValidationError } from '@synterai/sdk-js';
try {
await synter.campaigns.createSearch({ /* missing required fields */ } as any);
} catch (err) {
if (err instanceof SynterValidationError) {
// Caught client-side, before any network call — e.g. a missing required field.
} else if (err instanceof SynterError) {
// The API rejected the call: err.status, err.message, err.code, err.details
}
}
The client automatically retries up to 3 times (exponential backoff, 1s base / 10s cap) on 429 responses (honoring Retry-After) and on network/timeout errors. Other 4xx/5xx responses are not retried.
These mirror real, current production behavior of the backend scripts. The SDK calls the backend exactly as it works today rather than silently diverging — see ../sdk-shared/SPEC.md's "Known issues" section and catalog.json's knownIssues:
campaigns.pause() and campaigns.updateBudget() accept a platform field (their schemas advertise all 7 platforms), but the live dispatch always uses platform=google regardless of what's passed.uploadImage() accepts an optional platform (google/meta/linkedin), but live dispatch always hardcodes platform=google.campaigns.createDisplay() and campaigns.createPmax() use different flag names for the same concept — --landscape-image/--square-image vs. --landscape-image-url/--square-image-url.These are flagged to Joel as product bugs to fix upstream (in catalog.json first, then every SDK), not something to patch ad hoc in one language.
synter.amp is a separate, AI-powered toolbox for Amp integration (campaign generation, creative variants, budget optimization, etc.) — see AMP_TOOLBOX_README.md. It predates and is independent of the catalog-driven transport rewrite above.
npm run build # tsup, dual ESM/CJS + .d.ts
npm run typecheck # tsc --noEmit
npx vitest run # test suite (mocked fetch, no real network/API key required)
MIT
FAQs
TypeScript SDK for the Synter advertising API — manage campaigns across Google Ads, Meta, LinkedIn, Reddit, Microsoft, TikTok, and X
The npm package @synterai/sdk-js receives a total of 8 weekly downloads. As such, @synterai/sdk-js popularity was classified as not popular.
We found that @synterai/sdk-js demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Company News
Allow myself to introduce... myself.

Research
/Security News
A Twitch browser extension on Chrome and Firefox forwards users’ live OAuth session tokens through proxies controlled by a Russian bot service.

Security News
Anthropic found biased reasoning and recklessness drove Claude Mythos 5 to publish malware on PyPI and compromise a security vendor.