A comprehensive TypeScript SDK for the Taboola Backstage API. Manage campaigns, ads, targeting, audiences, pixel tracking, and reporting programmatically.
- Full TypeScript Support — Complete type definitions for all API endpoints, requests, and responses
- Automatic Authentication — OAuth2 token management with automatic refresh
- Comprehensive API Coverage — Campaigns, Items, Targeting, Pixel, Reports, Audiences, and more
- Custom Error Classes — Typed errors for auth, validation, rate limiting, and not found scenarios
- Built-in Retry Logic — Exponential backoff for transient failures
- Dual Module Support — Works with both ESM and CommonJS
npm install taboola-backstage-sdkyarn add taboola-backstage-sdkpnpm add taboola-backstage-sdkimport { TaboolaClient } from 'taboola-backstage-sdk';
const client = new TaboolaClient({
clientId: process.env.TABOOLA_CLIENT_ID,
clientSecret: process.env.TABOOLA_CLIENT_SECRET,
});
// Get your account
const account = await client.accounts.getCurrent();
console.log('Account:', account.account_id);
// List campaigns
const { results: campaigns } = await client.campaigns.list(account.account_id);
console.log(`Found ${campaigns.length} campaigns`);
// Get campaign performance report
const report = await client.reports.campaignSummary(account.account_id, 'day', {
start_date: '2024-01-01',
end_date: '2024-01-31',
});const client = new TaboolaClient({
// Required
clientId: string,
clientSecret: string,
// Optional
baseUrl?: string, // API base URL (default: production)
timeout?: number, // Request timeout in ms (default: 30000)
retries?: number, // Retry attempts for failed requests (default: 3)
debug?: boolean, // Enable request/response logging
});// Get current account
const account = await client.accounts.getCurrent();
// Get all allowed accounts
const { results } = await client.accounts.getAllowed();
// Get advertisers in a network
const { results } = await client.accounts.getNetworkAdvertisers('network-id');// List campaigns
const { results } = await client.campaigns.list('account-id', {
page: 1,
pageSize: 50,
});
// Get single campaign
const campaign = await client.campaigns.get('account-id', 'campaign-id');
// Create campaign
const campaign = await client.campaigns.create('account-id', {
name: 'My Campaign',
branding_text: 'My Brand',
cpc: 0.50,
spending_limit: 1000,
spending_limit_model: 'MONTHLY',
marketing_objective: 'DRIVE_WEBSITE_TRAFFIC',
});
// Update campaign
await client.campaigns.update('account-id', 'campaign-id', {
cpc: 0.75,
daily_cap: 500,
});
// Pause / Unpause
await client.campaigns.pause('account-id', 'campaign-id');
await client.campaigns.unpause('account-id', 'campaign-id');
// Delete
await client.campaigns.delete('account-id', 'campaign-id');
// Duplicate
const copy = await client.campaigns.duplicate('account-id', 'campaign-id', 'Copy Name');
// Bulk update
await client.campaigns.bulkUpdate('account-id', {
campaigns: [
{ campaign_id: '123', update: { is_active: false } },
{ campaign_id: '456', update: { cpc: 0.60 } },
],
});// List items
const { results } = await client.items.list('account-id', 'campaign-id');
// Get single item
const item = await client.items.get('account-id', 'campaign-id', 'item-id');
// Create item
const item = await client.items.create('account-id', 'campaign-id', {
url: 'https://example.com/landing',
title: 'Amazing Product - Learn More',
thumbnail_url: 'https://example.com/image.jpg',
description: 'Discover our latest offering',
cta: { cta_type: 'LEARN_MORE' },
});
// Update item
await client.items.update('account-id', 'campaign-id', 'item-id', {
title: 'Updated Title',
});
// Pause / Unpause
await client.items.pause('account-id', 'campaign-id', 'item-id');
await client.items.unpause('account-id', 'campaign-id', 'item-id');
// Delete
await client.items.delete('account-id', 'campaign-id', 'item-id');
// Bulk create
const { results } = await client.items.bulkCreate('account-id', 'campaign-id', {
items: [
{ url: 'https://example.com/1', title: 'Title 1', thumbnail_url: '...' },
{ url: 'https://example.com/2', title: 'Title 2', thumbnail_url: '...' },
],
});// Postal code targeting
const postal = await client.targeting.getPostalCodes('account-id', 'campaign-id');
await client.targeting.updatePostalCodes('account-id', 'campaign-id', {
type: 'INCLUDE',
values: [
{ postal_code: '10001', country: 'US' },
{ postal_code: '10002', country: 'US' },
],
});
// Marketplace audience targeting
const audiences = await client.targeting.getMarketplaceAudiences('account-id', 'campaign-id');
await client.targeting.updateMarketplaceAudiences('account-id', 'campaign-id', {
type: 'INCLUDE',
collection: [{ id: 'segment-123' }],
});
// Custom audience targeting
const custom = await client.targeting.getCustomAudiences('account-id', 'campaign-id');
// Lookalike audience targeting
const lookalike = await client.targeting.getLookalikeAudiences('account-id', 'campaign-id');
// Contextual targeting
const contextual = await client.targeting.getContextual('account-id', 'campaign-id');
await client.targeting.updateContextual('account-id', 'campaign-id', {
type: 'INCLUDE',
collection: [{ id: 'context-456' }],
});
// First party audience targeting
const firstParty = await client.targeting.getFirstPartyAudiences('account-id', 'campaign-id');Manage conversion tracking and custom audience rules.
// List conversion rules
const rules = await client.pixel.listConversionRules('account-id');
// Get single conversion rule
const rule = await client.pixel.getConversionRule('account-id', 'rule-id');
// Create conversion rule
const rule = await client.pixel.createConversionRule('account-id', {
display_name: 'Purchase Completed',
type: 'EVENT_BASED',
category: 'PURCHASE',
event_name: 'purchase',
conditions: [],
effect: {
type: 'DYNAMIC_VALUE',
currency: 'USD',
value_parameter: 'order_total',
},
conversion_window_days: 30,
view_through_window_days: 1,
});
// Archive / Unarchive
await client.pixel.archiveConversionRule('account-id', 'rule-id');
await client.pixel.unarchiveConversionRule('account-id', 'rule-id');
// Custom audience rules
const audienceRules = await client.pixel.listCustomAudienceRules('account-id');
const audienceRule = await client.pixel.createCustomAudienceRule('account-id', {
display_name: 'Cart Abandoners',
conditions: [
{ type: 'EVENT_NAME', operator: 'EQUALS', value: 'add_to_cart' },
],
ttl_days: 7,
});
// Pause / Resume / Archive
await client.pixel.pauseCustomAudienceRule('account-id', 'rule-id');
await client.pixel.resumeCustomAudienceRule('account-id', 'rule-id');
await client.pixel.archiveCustomAudienceRule('account-id', 'rule-id');// Campaign summary report (by dimension)
const report = await client.reports.campaignSummary('account-id', 'day', {
start_date: '2024-01-01',
end_date: '2024-01-31',
});
// Available dimensions: 'day', 'week', 'month', 'campaign', 'site', 'country', 'platform'
const byPlatform = await client.reports.campaignSummary('account-id', 'platform', {
start_date: '2024-01-01',
end_date: '2024-01-31',
campaign: '12345', // Optional filter
});
// Report data
for (const row of report.results) {
console.log(`${row.date}: ${row.clicks} clicks, $${row.spent} spent, ${row.ctr}% CTR`);
}
// Top campaign content report
const topContent = await client.reports.topCampaignContent('account-id', {
start_date: '2024-01-01',
end_date: '2024-01-31',
limit: 100,
});
// Realtime reports
const realtime = await client.reports.realtimeCampaign('account-id');
const realtimeAds = await client.reports.realtimeAds('account-id');// List available publishers (requires admin network)
const publishers = await client.publishers.list('account-id');
// Get blocked publishers
const blocked = await client.publishers.getBlocked('account-id');
// Block / Unblock publishers
await client.publishers.blockPublisher('account-id', 'site.com');
await client.publishers.unblockPublisher('account-id', 'site.com');
// Bulk update blocked publishers
await client.publishers.updateBlocked('account-id', {
sites: ['site1.com', 'site2.com'],
});
// Clear all blocks
await client.publishers.clearBlocked('account-id');// Geographic data
const countries = await client.dictionary.getCountries();
const regions = await client.dictionary.getRegions('US');
const dmas = await client.dictionary.getDMAs('US');
// Platform/device data
const platforms = await client.dictionary.getPlatforms();
// Audience segments
const marketplace = await client.dictionary.getMarketplaceAudiences('account-id');
const contextual = await client.dictionary.getContextualSegments('account-id');// List available audiences for targeting
const available = await client.combinedAudiences.listAvailable('account-id');
// List combined audiences
const audiences = await client.combinedAudiences.list('account-id');
// Get single combined audience
const audience = await client.combinedAudiences.get('account-id', 'audience-id');
// Create combined audience
const audience = await client.combinedAudiences.create('account-id', {
name: 'High Value Users',
rules: [
{ type: 'INCLUDE', audience_id: 'audience-1' },
{ type: 'EXCLUDE', audience_id: 'audience-2' },
],
});// List first party audiences
const audiences = await client.firstPartyAudiences.list('account-id');
// Get single audience
const audience = await client.firstPartyAudiences.get('account-id', 'audience-id');
// Create first party audience
const audience = await client.firstPartyAudiences.create('account-id', {
name: 'My Audience',
ttl_in_days: 30,
});
// Add/remove users
await client.firstPartyAudiences.addUsers('account-id', 'audience-id', {
operation: 'ADD',
users: [
{ type: 'EMAIL_SHA256', id: 'hashed-email-1' },
{ type: 'EMAIL_SHA256', id: 'hashed-email-2' },
],
});The SDK provides typed error classes for different scenarios:
import {
TaboolaError,
TaboolaAuthError,
TaboolaValidationError,
TaboolaNotFoundError,
TaboolaRateLimitError,
TaboolaForbiddenError,
} from 'taboola-backstage-sdk';
try {
await client.campaigns.get('account-id', 'invalid-id');
} catch (error) {
if (error instanceof TaboolaNotFoundError) {
console.error('Campaign not found');
} else if (error instanceof TaboolaAuthError) {
console.error('Authentication failed');
} else if (error instanceof TaboolaValidationError) {
console.error('Validation error:', error.fieldErrors);
} else if (error instanceof TaboolaRateLimitError) {
console.error(`Rate limited. Retry after ${error.retryAfter}s`);
} else if (error instanceof TaboolaForbiddenError) {
console.error('Access denied');
} else if (error instanceof TaboolaError) {
console.error(`API error: ${error.message} (${error.statusCode})`);
}
}All types are exported for use in your application:
import type {
// Core types
Campaign,
CampaignItem,
Account,
// Request types
CreateCampaignRequest,
UpdateCampaignRequest,
CreateItemRequest,
// Report types
CampaignSummaryReport,
CampaignSummaryRow,
// Targeting types
PostalCodeTargeting,
AudienceTargeting,
// Pixel types
ConversionRule,
CustomAudienceRule,
// Enums
MarketingObjective,
BidStrategy,
CampaignStatus,
ItemStatus,
} from 'taboola-backstage-sdk';const { TaboolaClient } = require('taboola-backstage-sdk');
const client = new TaboolaClient({
clientId: process.env.TABOOLA_CLIENT_ID,
clientSecret: process.env.TABOOLA_CLIENT_SECRET,
});- Node.js 18.0.0 or higher
For detailed API documentation, see the Taboola Backstage API Reference.
MIT
Contributions are welcome! Please open an issue or submit a pull request.