taboola-backstage-sdk 0.1.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/LICENSE +21 -0
- package/README.md +478 -0
- package/dist/index.cjs +2337 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +3454 -0
- package/dist/index.d.ts +3454 -0
- package/dist/index.js +2309 -0
- package/dist/index.js.map +1 -0
- package/package.json +87 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Arya Alikhani
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,478 @@
|
|
|
1
|
+
# Taboola Backstage SDK
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/taboola-backstage-sdk)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://www.typescriptlang.org/)
|
|
6
|
+
[](https://nodejs.org/)
|
|
7
|
+
|
|
8
|
+
A comprehensive TypeScript SDK for the [Taboola Backstage API](https://developers.taboola.com/backstage-api/reference). Manage campaigns, ads, targeting, audiences, pixel tracking, and reporting programmatically.
|
|
9
|
+
|
|
10
|
+
## Features
|
|
11
|
+
|
|
12
|
+
- **Full TypeScript Support** — Complete type definitions for all API endpoints, requests, and responses
|
|
13
|
+
- **Automatic Authentication** — OAuth2 token management with automatic refresh
|
|
14
|
+
- **Comprehensive API Coverage** — Campaigns, Items, Targeting, Pixel, Reports, Audiences, and more
|
|
15
|
+
- **Custom Error Classes** — Typed errors for auth, validation, rate limiting, and not found scenarios
|
|
16
|
+
- **Built-in Retry Logic** — Exponential backoff for transient failures
|
|
17
|
+
- **Dual Module Support** — Works with both ESM and CommonJS
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install taboola-backstage-sdk
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
yarn add taboola-backstage-sdk
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pnpm add taboola-backstage-sdk
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
import { TaboolaClient } from 'taboola-backstage-sdk';
|
|
37
|
+
|
|
38
|
+
const client = new TaboolaClient({
|
|
39
|
+
clientId: process.env.TABOOLA_CLIENT_ID,
|
|
40
|
+
clientSecret: process.env.TABOOLA_CLIENT_SECRET,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// Get your account
|
|
44
|
+
const account = await client.accounts.getCurrent();
|
|
45
|
+
console.log('Account:', account.account_id);
|
|
46
|
+
|
|
47
|
+
// List campaigns
|
|
48
|
+
const { results: campaigns } = await client.campaigns.list(account.account_id);
|
|
49
|
+
console.log(`Found ${campaigns.length} campaigns`);
|
|
50
|
+
|
|
51
|
+
// Get campaign performance report
|
|
52
|
+
const report = await client.reports.campaignSummary(account.account_id, 'day', {
|
|
53
|
+
start_date: '2024-01-01',
|
|
54
|
+
end_date: '2024-01-31',
|
|
55
|
+
});
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Configuration
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
const client = new TaboolaClient({
|
|
62
|
+
// Required
|
|
63
|
+
clientId: string,
|
|
64
|
+
clientSecret: string,
|
|
65
|
+
|
|
66
|
+
// Optional
|
|
67
|
+
baseUrl?: string, // API base URL (default: production)
|
|
68
|
+
timeout?: number, // Request timeout in ms (default: 30000)
|
|
69
|
+
retries?: number, // Retry attempts for failed requests (default: 3)
|
|
70
|
+
debug?: boolean, // Enable request/response logging
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## API Reference
|
|
75
|
+
|
|
76
|
+
### Accounts
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
// Get current account
|
|
80
|
+
const account = await client.accounts.getCurrent();
|
|
81
|
+
|
|
82
|
+
// Get all allowed accounts
|
|
83
|
+
const { results } = await client.accounts.getAllowed();
|
|
84
|
+
|
|
85
|
+
// Get advertisers in a network
|
|
86
|
+
const { results } = await client.accounts.getNetworkAdvertisers('network-id');
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Campaigns
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
// List campaigns
|
|
93
|
+
const { results } = await client.campaigns.list('account-id', {
|
|
94
|
+
page: 1,
|
|
95
|
+
pageSize: 50,
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// Get single campaign
|
|
99
|
+
const campaign = await client.campaigns.get('account-id', 'campaign-id');
|
|
100
|
+
|
|
101
|
+
// Create campaign
|
|
102
|
+
const campaign = await client.campaigns.create('account-id', {
|
|
103
|
+
name: 'My Campaign',
|
|
104
|
+
branding_text: 'My Brand',
|
|
105
|
+
cpc: 0.50,
|
|
106
|
+
spending_limit: 1000,
|
|
107
|
+
spending_limit_model: 'MONTHLY',
|
|
108
|
+
marketing_objective: 'DRIVE_WEBSITE_TRAFFIC',
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// Update campaign
|
|
112
|
+
await client.campaigns.update('account-id', 'campaign-id', {
|
|
113
|
+
cpc: 0.75,
|
|
114
|
+
daily_cap: 500,
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
// Pause / Unpause
|
|
118
|
+
await client.campaigns.pause('account-id', 'campaign-id');
|
|
119
|
+
await client.campaigns.unpause('account-id', 'campaign-id');
|
|
120
|
+
|
|
121
|
+
// Delete
|
|
122
|
+
await client.campaigns.delete('account-id', 'campaign-id');
|
|
123
|
+
|
|
124
|
+
// Duplicate
|
|
125
|
+
const copy = await client.campaigns.duplicate('account-id', 'campaign-id', 'Copy Name');
|
|
126
|
+
|
|
127
|
+
// Bulk update
|
|
128
|
+
await client.campaigns.bulkUpdate('account-id', {
|
|
129
|
+
campaigns: [
|
|
130
|
+
{ campaign_id: '123', update: { is_active: false } },
|
|
131
|
+
{ campaign_id: '456', update: { cpc: 0.60 } },
|
|
132
|
+
],
|
|
133
|
+
});
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Items (Ads)
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
// List items
|
|
140
|
+
const { results } = await client.items.list('account-id', 'campaign-id');
|
|
141
|
+
|
|
142
|
+
// Get single item
|
|
143
|
+
const item = await client.items.get('account-id', 'campaign-id', 'item-id');
|
|
144
|
+
|
|
145
|
+
// Create item
|
|
146
|
+
const item = await client.items.create('account-id', 'campaign-id', {
|
|
147
|
+
url: 'https://example.com/landing',
|
|
148
|
+
title: 'Amazing Product - Learn More',
|
|
149
|
+
thumbnail_url: 'https://example.com/image.jpg',
|
|
150
|
+
description: 'Discover our latest offering',
|
|
151
|
+
cta: { cta_type: 'LEARN_MORE' },
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
// Update item
|
|
155
|
+
await client.items.update('account-id', 'campaign-id', 'item-id', {
|
|
156
|
+
title: 'Updated Title',
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
// Pause / Unpause
|
|
160
|
+
await client.items.pause('account-id', 'campaign-id', 'item-id');
|
|
161
|
+
await client.items.unpause('account-id', 'campaign-id', 'item-id');
|
|
162
|
+
|
|
163
|
+
// Delete
|
|
164
|
+
await client.items.delete('account-id', 'campaign-id', 'item-id');
|
|
165
|
+
|
|
166
|
+
// Bulk create
|
|
167
|
+
const { results } = await client.items.bulkCreate('account-id', 'campaign-id', {
|
|
168
|
+
items: [
|
|
169
|
+
{ url: 'https://example.com/1', title: 'Title 1', thumbnail_url: '...' },
|
|
170
|
+
{ url: 'https://example.com/2', title: 'Title 2', thumbnail_url: '...' },
|
|
171
|
+
],
|
|
172
|
+
});
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Targeting
|
|
176
|
+
|
|
177
|
+
```typescript
|
|
178
|
+
// Postal code targeting
|
|
179
|
+
const postal = await client.targeting.getPostalCodes('account-id', 'campaign-id');
|
|
180
|
+
await client.targeting.updatePostalCodes('account-id', 'campaign-id', {
|
|
181
|
+
type: 'INCLUDE',
|
|
182
|
+
values: [
|
|
183
|
+
{ postal_code: '10001', country: 'US' },
|
|
184
|
+
{ postal_code: '10002', country: 'US' },
|
|
185
|
+
],
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// Marketplace audience targeting
|
|
189
|
+
const audiences = await client.targeting.getMarketplaceAudiences('account-id', 'campaign-id');
|
|
190
|
+
await client.targeting.updateMarketplaceAudiences('account-id', 'campaign-id', {
|
|
191
|
+
type: 'INCLUDE',
|
|
192
|
+
collection: [{ id: 'segment-123' }],
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
// Custom audience targeting
|
|
196
|
+
const custom = await client.targeting.getCustomAudiences('account-id', 'campaign-id');
|
|
197
|
+
|
|
198
|
+
// Lookalike audience targeting
|
|
199
|
+
const lookalike = await client.targeting.getLookalikeAudiences('account-id', 'campaign-id');
|
|
200
|
+
|
|
201
|
+
// Contextual targeting
|
|
202
|
+
const contextual = await client.targeting.getContextual('account-id', 'campaign-id');
|
|
203
|
+
await client.targeting.updateContextual('account-id', 'campaign-id', {
|
|
204
|
+
type: 'INCLUDE',
|
|
205
|
+
collection: [{ id: 'context-456' }],
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
// First party audience targeting
|
|
209
|
+
const firstParty = await client.targeting.getFirstPartyAudiences('account-id', 'campaign-id');
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Pixel API
|
|
213
|
+
|
|
214
|
+
Manage conversion tracking and custom audience rules.
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
// List conversion rules
|
|
218
|
+
const rules = await client.pixel.listConversionRules('account-id');
|
|
219
|
+
|
|
220
|
+
// Get single conversion rule
|
|
221
|
+
const rule = await client.pixel.getConversionRule('account-id', 'rule-id');
|
|
222
|
+
|
|
223
|
+
// Create conversion rule
|
|
224
|
+
const rule = await client.pixel.createConversionRule('account-id', {
|
|
225
|
+
display_name: 'Purchase Completed',
|
|
226
|
+
type: 'EVENT_BASED',
|
|
227
|
+
category: 'PURCHASE',
|
|
228
|
+
event_name: 'purchase',
|
|
229
|
+
conditions: [],
|
|
230
|
+
effect: {
|
|
231
|
+
type: 'DYNAMIC_VALUE',
|
|
232
|
+
currency: 'USD',
|
|
233
|
+
value_parameter: 'order_total',
|
|
234
|
+
},
|
|
235
|
+
conversion_window_days: 30,
|
|
236
|
+
view_through_window_days: 1,
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
// Archive / Unarchive
|
|
240
|
+
await client.pixel.archiveConversionRule('account-id', 'rule-id');
|
|
241
|
+
await client.pixel.unarchiveConversionRule('account-id', 'rule-id');
|
|
242
|
+
|
|
243
|
+
// Custom audience rules
|
|
244
|
+
const audienceRules = await client.pixel.listCustomAudienceRules('account-id');
|
|
245
|
+
|
|
246
|
+
const audienceRule = await client.pixel.createCustomAudienceRule('account-id', {
|
|
247
|
+
display_name: 'Cart Abandoners',
|
|
248
|
+
conditions: [
|
|
249
|
+
{ type: 'EVENT_NAME', operator: 'EQUALS', value: 'add_to_cart' },
|
|
250
|
+
],
|
|
251
|
+
ttl_days: 7,
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
// Pause / Resume / Archive
|
|
255
|
+
await client.pixel.pauseCustomAudienceRule('account-id', 'rule-id');
|
|
256
|
+
await client.pixel.resumeCustomAudienceRule('account-id', 'rule-id');
|
|
257
|
+
await client.pixel.archiveCustomAudienceRule('account-id', 'rule-id');
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### Reports
|
|
261
|
+
|
|
262
|
+
```typescript
|
|
263
|
+
// Campaign summary report (by dimension)
|
|
264
|
+
const report = await client.reports.campaignSummary('account-id', 'day', {
|
|
265
|
+
start_date: '2024-01-01',
|
|
266
|
+
end_date: '2024-01-31',
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
// Available dimensions: 'day', 'week', 'month', 'campaign', 'site', 'country', 'platform'
|
|
270
|
+
const byPlatform = await client.reports.campaignSummary('account-id', 'platform', {
|
|
271
|
+
start_date: '2024-01-01',
|
|
272
|
+
end_date: '2024-01-31',
|
|
273
|
+
campaign: '12345', // Optional filter
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
// Report data
|
|
277
|
+
for (const row of report.results) {
|
|
278
|
+
console.log(`${row.date}: ${row.clicks} clicks, $${row.spent} spent, ${row.ctr}% CTR`);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// Top campaign content report
|
|
282
|
+
const topContent = await client.reports.topCampaignContent('account-id', {
|
|
283
|
+
start_date: '2024-01-01',
|
|
284
|
+
end_date: '2024-01-31',
|
|
285
|
+
limit: 100,
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
// Realtime reports
|
|
289
|
+
const realtime = await client.reports.realtimeCampaign('account-id');
|
|
290
|
+
const realtimeAds = await client.reports.realtimeAds('account-id');
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### Publishers
|
|
294
|
+
|
|
295
|
+
```typescript
|
|
296
|
+
// List available publishers (requires admin network)
|
|
297
|
+
const publishers = await client.publishers.list('account-id');
|
|
298
|
+
|
|
299
|
+
// Get blocked publishers
|
|
300
|
+
const blocked = await client.publishers.getBlocked('account-id');
|
|
301
|
+
|
|
302
|
+
// Block / Unblock publishers
|
|
303
|
+
await client.publishers.blockPublisher('account-id', 'site.com');
|
|
304
|
+
await client.publishers.unblockPublisher('account-id', 'site.com');
|
|
305
|
+
|
|
306
|
+
// Bulk update blocked publishers
|
|
307
|
+
await client.publishers.updateBlocked('account-id', {
|
|
308
|
+
sites: ['site1.com', 'site2.com'],
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
// Clear all blocks
|
|
312
|
+
await client.publishers.clearBlocked('account-id');
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
### Dictionary (Reference Data)
|
|
316
|
+
|
|
317
|
+
```typescript
|
|
318
|
+
// Geographic data
|
|
319
|
+
const countries = await client.dictionary.getCountries();
|
|
320
|
+
const regions = await client.dictionary.getRegions('US');
|
|
321
|
+
const dmas = await client.dictionary.getDMAs('US');
|
|
322
|
+
|
|
323
|
+
// Platform/device data
|
|
324
|
+
const platforms = await client.dictionary.getPlatforms();
|
|
325
|
+
|
|
326
|
+
// Audience segments
|
|
327
|
+
const marketplace = await client.dictionary.getMarketplaceAudiences('account-id');
|
|
328
|
+
const contextual = await client.dictionary.getContextualSegments('account-id');
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### Combined Audiences
|
|
332
|
+
|
|
333
|
+
```typescript
|
|
334
|
+
// List available audiences for targeting
|
|
335
|
+
const available = await client.combinedAudiences.listAvailable('account-id');
|
|
336
|
+
|
|
337
|
+
// List combined audiences
|
|
338
|
+
const audiences = await client.combinedAudiences.list('account-id');
|
|
339
|
+
|
|
340
|
+
// Get single combined audience
|
|
341
|
+
const audience = await client.combinedAudiences.get('account-id', 'audience-id');
|
|
342
|
+
|
|
343
|
+
// Create combined audience
|
|
344
|
+
const audience = await client.combinedAudiences.create('account-id', {
|
|
345
|
+
name: 'High Value Users',
|
|
346
|
+
rules: [
|
|
347
|
+
{ type: 'INCLUDE', audience_id: 'audience-1' },
|
|
348
|
+
{ type: 'EXCLUDE', audience_id: 'audience-2' },
|
|
349
|
+
],
|
|
350
|
+
});
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
### First Party Audiences
|
|
354
|
+
|
|
355
|
+
```typescript
|
|
356
|
+
// List first party audiences
|
|
357
|
+
const audiences = await client.firstPartyAudiences.list('account-id');
|
|
358
|
+
|
|
359
|
+
// Get single audience
|
|
360
|
+
const audience = await client.firstPartyAudiences.get('account-id', 'audience-id');
|
|
361
|
+
|
|
362
|
+
// Create first party audience
|
|
363
|
+
const audience = await client.firstPartyAudiences.create('account-id', {
|
|
364
|
+
name: 'My Audience',
|
|
365
|
+
ttl_in_days: 30,
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
// Add/remove users
|
|
369
|
+
await client.firstPartyAudiences.addUsers('account-id', 'audience-id', {
|
|
370
|
+
operation: 'ADD',
|
|
371
|
+
users: [
|
|
372
|
+
{ type: 'EMAIL_SHA256', id: 'hashed-email-1' },
|
|
373
|
+
{ type: 'EMAIL_SHA256', id: 'hashed-email-2' },
|
|
374
|
+
],
|
|
375
|
+
});
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
## Error Handling
|
|
379
|
+
|
|
380
|
+
The SDK provides typed error classes for different scenarios:
|
|
381
|
+
|
|
382
|
+
```typescript
|
|
383
|
+
import {
|
|
384
|
+
TaboolaError,
|
|
385
|
+
TaboolaAuthError,
|
|
386
|
+
TaboolaValidationError,
|
|
387
|
+
TaboolaNotFoundError,
|
|
388
|
+
TaboolaRateLimitError,
|
|
389
|
+
TaboolaForbiddenError,
|
|
390
|
+
} from 'taboola-backstage-sdk';
|
|
391
|
+
|
|
392
|
+
try {
|
|
393
|
+
await client.campaigns.get('account-id', 'invalid-id');
|
|
394
|
+
} catch (error) {
|
|
395
|
+
if (error instanceof TaboolaNotFoundError) {
|
|
396
|
+
console.error('Campaign not found');
|
|
397
|
+
} else if (error instanceof TaboolaAuthError) {
|
|
398
|
+
console.error('Authentication failed');
|
|
399
|
+
} else if (error instanceof TaboolaValidationError) {
|
|
400
|
+
console.error('Validation error:', error.fieldErrors);
|
|
401
|
+
} else if (error instanceof TaboolaRateLimitError) {
|
|
402
|
+
console.error(`Rate limited. Retry after ${error.retryAfter}s`);
|
|
403
|
+
} else if (error instanceof TaboolaForbiddenError) {
|
|
404
|
+
console.error('Access denied');
|
|
405
|
+
} else if (error instanceof TaboolaError) {
|
|
406
|
+
console.error(`API error: ${error.message} (${error.statusCode})`);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
## TypeScript
|
|
412
|
+
|
|
413
|
+
All types are exported for use in your application:
|
|
414
|
+
|
|
415
|
+
```typescript
|
|
416
|
+
import type {
|
|
417
|
+
// Core types
|
|
418
|
+
Campaign,
|
|
419
|
+
CampaignItem,
|
|
420
|
+
Account,
|
|
421
|
+
|
|
422
|
+
// Request types
|
|
423
|
+
CreateCampaignRequest,
|
|
424
|
+
UpdateCampaignRequest,
|
|
425
|
+
CreateItemRequest,
|
|
426
|
+
|
|
427
|
+
// Report types
|
|
428
|
+
CampaignSummaryReport,
|
|
429
|
+
CampaignSummaryRow,
|
|
430
|
+
|
|
431
|
+
// Targeting types
|
|
432
|
+
PostalCodeTargeting,
|
|
433
|
+
AudienceTargeting,
|
|
434
|
+
|
|
435
|
+
// Pixel types
|
|
436
|
+
ConversionRule,
|
|
437
|
+
CustomAudienceRule,
|
|
438
|
+
|
|
439
|
+
// Enums
|
|
440
|
+
MarketingObjective,
|
|
441
|
+
BidStrategy,
|
|
442
|
+
CampaignStatus,
|
|
443
|
+
ItemStatus,
|
|
444
|
+
} from 'taboola-backstage-sdk';
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
## CommonJS Usage
|
|
448
|
+
|
|
449
|
+
```javascript
|
|
450
|
+
const { TaboolaClient } = require('taboola-backstage-sdk');
|
|
451
|
+
|
|
452
|
+
const client = new TaboolaClient({
|
|
453
|
+
clientId: process.env.TABOOLA_CLIENT_ID,
|
|
454
|
+
clientSecret: process.env.TABOOLA_CLIENT_SECRET,
|
|
455
|
+
});
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
## Requirements
|
|
459
|
+
|
|
460
|
+
- Node.js 18.0.0 or higher
|
|
461
|
+
|
|
462
|
+
## API Documentation
|
|
463
|
+
|
|
464
|
+
For detailed API documentation, see the [Taboola Backstage API Reference](https://developers.taboola.com/backstage-api/reference).
|
|
465
|
+
|
|
466
|
+
## License
|
|
467
|
+
|
|
468
|
+
MIT
|
|
469
|
+
|
|
470
|
+
## Contributing
|
|
471
|
+
|
|
472
|
+
Contributions are welcome! Please open an issue or submit a pull request.
|
|
473
|
+
|
|
474
|
+
## Links
|
|
475
|
+
|
|
476
|
+
- [Taboola Backstage API Documentation](https://developers.taboola.com/backstage-api/reference)
|
|
477
|
+
- [npm Package](https://www.npmjs.com/package/taboola-backstage-sdk)
|
|
478
|
+
- [GitHub Repository](https://github.com/0xARYA/taboola-backstage-sdk)
|