@apostra/sdk 0.39.0 → 0.40.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/cli-login.d.ts +2 -2
- package/dist/cli-login.js +192 -12
- package/dist/generated/client.d.ts +20 -4
- package/dist/generated/client.js +13 -4
- package/dist/generated/metadata.d.ts +18 -3
- package/dist/generated/metadata.js +23 -3
- package/dist/generated/types.gen.d.ts +928 -122
- package/package.json +5 -2
package/dist/cli-login.d.ts
CHANGED
|
@@ -52,8 +52,8 @@ export declare function exchangeCliLoginCode(options: Options, discovery: CliLog
|
|
|
52
52
|
}): Promise<CliLoginTokens>;
|
|
53
53
|
/**
|
|
54
54
|
* Return a usable login for `baseUrl`, refreshing it if the access token is
|
|
55
|
-
* about to expire. After taking the lock the
|
|
56
|
-
* process refreshed first, its token is used and no request is made.
|
|
55
|
+
* about to expire. After taking the lock the credential store is read again:
|
|
56
|
+
* if another process refreshed first, its token is used and no request is made.
|
|
57
57
|
*/
|
|
58
58
|
export declare function refreshCliLogin(baseUrl: string, options?: Options): Promise<CliLoginEntry>;
|
|
59
59
|
/**
|
package/dist/cli-login.js
CHANGED
|
@@ -25,6 +25,7 @@ function node() {
|
|
|
25
25
|
fs: get('node:fs'),
|
|
26
26
|
os: get('node:os'),
|
|
27
27
|
path: get('node:path'),
|
|
28
|
+
module: get('node:module'),
|
|
28
29
|
};
|
|
29
30
|
}
|
|
30
31
|
const isRecord = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
@@ -73,7 +74,7 @@ function parseEntry(value) {
|
|
|
73
74
|
return undefined;
|
|
74
75
|
return value;
|
|
75
76
|
}
|
|
76
|
-
function
|
|
77
|
+
function readFileLogins() {
|
|
77
78
|
const { fs } = node();
|
|
78
79
|
try {
|
|
79
80
|
const file = JSON.parse(fs.readFileSync(credentialsPath(), 'utf8'));
|
|
@@ -84,7 +85,7 @@ function readAll() {
|
|
|
84
85
|
}
|
|
85
86
|
}
|
|
86
87
|
/** Atomic (temp file + rename), directory 0700, file 0600. */
|
|
87
|
-
function
|
|
88
|
+
function writeFileLogins(logins) {
|
|
88
89
|
const { fs, path } = node();
|
|
89
90
|
const file = credentialsPath();
|
|
90
91
|
const dir = path.dirname(file);
|
|
@@ -104,8 +105,141 @@ function writeAll(logins) {
|
|
|
104
105
|
}
|
|
105
106
|
fs.renameSync(temp, file);
|
|
106
107
|
}
|
|
108
|
+
const keyringService = 'Apostra CLI login';
|
|
109
|
+
/**
|
|
110
|
+
* Resolve the native binding only when this Node-only feature is used. A static
|
|
111
|
+
* import would make the browser SDK bundle a native module.
|
|
112
|
+
*/
|
|
113
|
+
function keyringEntry(resource) {
|
|
114
|
+
const { module } = node();
|
|
115
|
+
const required = module.createRequire(import.meta.url)('@napi-rs/keyring');
|
|
116
|
+
if (!isRecord(required) || typeof required.Entry !== 'function')
|
|
117
|
+
throw new Error('Apostra credential-store binding is unavailable');
|
|
118
|
+
const Entry = required.Entry;
|
|
119
|
+
// Do not accept keyutils on Linux. It is ephemeral and is not the requested
|
|
120
|
+
// Secret Service store, so an inaccessible service deliberately uses the
|
|
121
|
+
// documented 0600-file fallback instead.
|
|
122
|
+
return new Entry(keyringService, resource, proc().platform === 'linux'
|
|
123
|
+
? { linux: { store: 'secret-service' } }
|
|
124
|
+
: undefined);
|
|
125
|
+
}
|
|
126
|
+
function readSecureLogin(resource) {
|
|
127
|
+
try {
|
|
128
|
+
const password = keyringEntry(resource).getPassword();
|
|
129
|
+
if (!password)
|
|
130
|
+
return { available: true };
|
|
131
|
+
return { available: true, entry: parseEntry(JSON.parse(password)) };
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
return { available: false };
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
function writeSecureLogin(resource, entry) {
|
|
138
|
+
try {
|
|
139
|
+
keyringEntry(resource).setPassword(JSON.stringify(entry));
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
function deleteSecureLogin(resource) {
|
|
147
|
+
try {
|
|
148
|
+
return keyringEntry(resource).deletePassword();
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
return undefined;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
function warnFileFallback() {
|
|
155
|
+
const { fs, path } = node();
|
|
156
|
+
const dir = path.dirname(credentialsPath());
|
|
157
|
+
const marker = path.join(dir, '.file-store-warning');
|
|
158
|
+
try {
|
|
159
|
+
fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
160
|
+
fs.chmodSync(dir, 0o700);
|
|
161
|
+
const fd = fs.openSync(marker, 'wx', 0o600);
|
|
162
|
+
fs.closeSync(fd);
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
if (errorCode(error) === 'EEXIST')
|
|
166
|
+
return;
|
|
167
|
+
// If the marker cannot be written, warn for this process rather than
|
|
168
|
+
// silently accepting plaintext storage.
|
|
169
|
+
}
|
|
170
|
+
proc().emitWarning?.(`Apostra could not access your OS credential store. Login tokens are stored in ${credentialsPath()} with 0600 permissions. Use Keychain, Credential Manager, or Secret Service when available.`);
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Move every legacy entry while holding the normal refresh lock. Reads that
|
|
174
|
+
* arrive first use a short synchronous instance of the same lock; contenders
|
|
175
|
+
* keep reading the legacy file until the migration finishes.
|
|
176
|
+
*/
|
|
177
|
+
function migrateFileLogins(lockHeld = false) {
|
|
178
|
+
const { fs, path } = node();
|
|
179
|
+
const fileLogins = readFileLogins();
|
|
180
|
+
const entries = Object.entries(fileLogins).flatMap(([resource, value]) => {
|
|
181
|
+
const entry = parseEntry(value);
|
|
182
|
+
return entry ? [[resource, entry]] : [];
|
|
183
|
+
});
|
|
184
|
+
if (entries.length === 0)
|
|
185
|
+
return false;
|
|
186
|
+
const lock = `${credentialsPath()}.lock`;
|
|
187
|
+
let owner;
|
|
188
|
+
if (!lockHeld) {
|
|
189
|
+
fs.mkdirSync(path.dirname(lock), { recursive: true, mode: 0o700 });
|
|
190
|
+
owner = `migration:${proc().pid}:${globalThis.crypto.randomUUID()}`;
|
|
191
|
+
try {
|
|
192
|
+
const fd = fs.openSync(lock, 'wx', 0o600);
|
|
193
|
+
try {
|
|
194
|
+
fs.writeSync(fd, owner);
|
|
195
|
+
}
|
|
196
|
+
finally {
|
|
197
|
+
fs.closeSync(fd);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
try {
|
|
205
|
+
for (const [resource, entry] of entries) {
|
|
206
|
+
// A keyring value is authoritative: preserving it avoids overwriting a
|
|
207
|
+
// token another process has already refreshed during an interrupted
|
|
208
|
+
// earlier migration.
|
|
209
|
+
const stored = readSecureLogin(resource);
|
|
210
|
+
if (stored.entry)
|
|
211
|
+
continue;
|
|
212
|
+
if (!stored.available || !writeSecureLogin(resource, entry))
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
fs.rmSync(credentialsPath(), { force: true });
|
|
216
|
+
return true;
|
|
217
|
+
}
|
|
218
|
+
finally {
|
|
219
|
+
if (owner) {
|
|
220
|
+
try {
|
|
221
|
+
if (fs.readFileSync(lock, 'utf8') === owner)
|
|
222
|
+
fs.rmSync(lock, { force: true });
|
|
223
|
+
}
|
|
224
|
+
catch {
|
|
225
|
+
// The regular lock protocol protects against removing another owner.
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
107
230
|
export function readCliLogin(baseUrl) {
|
|
108
|
-
|
|
231
|
+
const resource = normalizeBaseUrl(baseUrl);
|
|
232
|
+
const secure = readSecureLogin(resource);
|
|
233
|
+
if (secure.entry)
|
|
234
|
+
return secure.entry;
|
|
235
|
+
const fileLogins = readFileLogins();
|
|
236
|
+
if (Object.keys(fileLogins).length === 0)
|
|
237
|
+
return undefined;
|
|
238
|
+
if (migrateFileLogins())
|
|
239
|
+
return readSecureLogin(resource).entry;
|
|
240
|
+
if (!secure.available)
|
|
241
|
+
warnFileFallback();
|
|
242
|
+
return parseEntry(fileLogins[resource]);
|
|
109
243
|
}
|
|
110
244
|
/** Like `readCliLogin`, but never throws: for the SDK's default credential chain. */
|
|
111
245
|
export function storedCliLogin(baseUrl) {
|
|
@@ -117,6 +251,43 @@ export function storedCliLogin(baseUrl) {
|
|
|
117
251
|
}
|
|
118
252
|
}
|
|
119
253
|
export const isFresh = (entry) => Date.parse(entry.expiresAt) - FRESH_MARGIN_MS > Date.now();
|
|
254
|
+
/**
|
|
255
|
+
* Remove a lock whose heartbeat stopped, without ever removing a live one.
|
|
256
|
+
* Only the holder of the takeover guard checks and removes. Checking again
|
|
257
|
+
* under the guard means a lock another process took after the first check is
|
|
258
|
+
* fresh and is left alone. A guard a crashed process left behind goes stale
|
|
259
|
+
* like a lock does. Returns whether this call held the guard, so the caller
|
|
260
|
+
* retries at once; otherwise it waits like any other contender.
|
|
261
|
+
*/
|
|
262
|
+
function breakStaleLock(fs, lock) {
|
|
263
|
+
const guard = `${lock}.takeover`;
|
|
264
|
+
try {
|
|
265
|
+
fs.closeSync(fs.openSync(guard, 'wx', 0o600));
|
|
266
|
+
}
|
|
267
|
+
catch (error) {
|
|
268
|
+
if (errorCode(error) !== 'EEXIST')
|
|
269
|
+
throw error;
|
|
270
|
+
try {
|
|
271
|
+
if (Date.now() - fs.statSync(guard).mtimeMs > LOCK_STALE_MS)
|
|
272
|
+
fs.rmSync(guard, { force: true });
|
|
273
|
+
}
|
|
274
|
+
catch {
|
|
275
|
+
// The guard went away between the two calls; the caller retries.
|
|
276
|
+
}
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
try {
|
|
280
|
+
if (Date.now() - fs.statSync(lock).mtimeMs > LOCK_STALE_MS)
|
|
281
|
+
fs.rmSync(lock, { force: true });
|
|
282
|
+
}
|
|
283
|
+
catch {
|
|
284
|
+
// The lock went away; the caller retries.
|
|
285
|
+
}
|
|
286
|
+
finally {
|
|
287
|
+
fs.rmSync(guard, { force: true });
|
|
288
|
+
}
|
|
289
|
+
return true;
|
|
290
|
+
}
|
|
120
291
|
/**
|
|
121
292
|
* Serialise every read-modify-write of the store, across processes. Refresh
|
|
122
293
|
* tokens rotate, so two processes must never present the same one outside the
|
|
@@ -154,11 +325,9 @@ export async function withCliLoginLock(fn) {
|
|
|
154
325
|
if (errorCode(error) !== 'EEXIST')
|
|
155
326
|
throw error;
|
|
156
327
|
try {
|
|
157
|
-
const stale = ownerOf();
|
|
158
328
|
if (Date.now() - fs.statSync(lock).mtimeMs > LOCK_STALE_MS) {
|
|
159
|
-
if (
|
|
160
|
-
|
|
161
|
-
continue;
|
|
329
|
+
if (breakStaleLock(fs, lock))
|
|
330
|
+
continue;
|
|
162
331
|
}
|
|
163
332
|
}
|
|
164
333
|
catch {
|
|
@@ -190,7 +359,14 @@ export async function withCliLoginLock(fn) {
|
|
|
190
359
|
}
|
|
191
360
|
/** Save a login. Call inside `withCliLoginLock`. */
|
|
192
361
|
export function writeCliLogin(baseUrl, entry) {
|
|
193
|
-
|
|
362
|
+
const resource = normalizeBaseUrl(baseUrl);
|
|
363
|
+
// Callers hold the cross-process lock, so the legacy file cannot overwrite
|
|
364
|
+
// a rotated credential while it is being migrated.
|
|
365
|
+
migrateFileLogins(true);
|
|
366
|
+
if (writeSecureLogin(resource, entry))
|
|
367
|
+
return;
|
|
368
|
+
warnFileFallback();
|
|
369
|
+
writeFileLogins({ ...readFileLogins(), [resource]: entry });
|
|
194
370
|
}
|
|
195
371
|
async function send(fetcher, url, init = {}) {
|
|
196
372
|
return fetcher(url, {
|
|
@@ -287,8 +463,8 @@ export function exchangeCliLoginCode(options, discovery, resource, grant) {
|
|
|
287
463
|
}
|
|
288
464
|
/**
|
|
289
465
|
* Return a usable login for `baseUrl`, refreshing it if the access token is
|
|
290
|
-
* about to expire. After taking the lock the
|
|
291
|
-
* process refreshed first, its token is used and no request is made.
|
|
466
|
+
* about to expire. After taking the lock the credential store is read again:
|
|
467
|
+
* if another process refreshed first, its token is used and no request is made.
|
|
292
468
|
*/
|
|
293
469
|
export async function refreshCliLogin(baseUrl, options = {}) {
|
|
294
470
|
const key = normalizeBaseUrl(baseUrl);
|
|
@@ -350,8 +526,12 @@ export async function logoutCliLogin(baseUrl, { fetch: f = globalThis.fetch } =
|
|
|
350
526
|
catch {
|
|
351
527
|
revoked = false;
|
|
352
528
|
}
|
|
353
|
-
|
|
354
|
-
|
|
529
|
+
deleteSecureLogin(key);
|
|
530
|
+
// A prior fallback login can still be present even when the credential
|
|
531
|
+
// store has no entry (or is available again). Remove it unconditionally:
|
|
532
|
+
// otherwise its refresh token could be migrated back after logout.
|
|
533
|
+
const { [key]: _removed, ...rest } = readFileLogins();
|
|
534
|
+
writeFileLogins(rest);
|
|
355
535
|
return { found: true, revoked };
|
|
356
536
|
});
|
|
357
537
|
}
|
|
@@ -43,6 +43,9 @@ export type GetSellerReportingReceiptsError = Wire.GetSellerReportingReceiptsErr
|
|
|
43
43
|
export type GetStatusInput = Wire.GetStatusData['body'];
|
|
44
44
|
export type GetStatusResult = Wire.GetStatusResponses[200]['data'];
|
|
45
45
|
export type GetStatusError = Wire.GetStatusErrors[keyof Wire.GetStatusErrors];
|
|
46
|
+
export type LogEventInput = OptionalWireField<Wire.LogEventData['body'], "idempotencyKey">;
|
|
47
|
+
export type LogEventResult = Wire.LogEventResponses[200]['data'];
|
|
48
|
+
export type LogEventError = Wire.LogEventErrors[keyof Wire.LogEventErrors];
|
|
46
49
|
export type OpenAdvertisersPageInput = Wire.OpenAdvertisersPageData['body'];
|
|
47
50
|
export type OpenAdvertisersPageResult = Wire.OpenAdvertisersPageResponses[200]['data'];
|
|
48
51
|
export type OpenAdvertisersPageError = Wire.OpenAdvertisersPageErrors[keyof Wire.OpenAdvertisersPageErrors];
|
|
@@ -276,6 +279,10 @@ export interface OperationTypes {
|
|
|
276
279
|
input: GetStatusInput;
|
|
277
280
|
result: GetStatusResult;
|
|
278
281
|
};
|
|
282
|
+
"log_event": {
|
|
283
|
+
input: LogEventInput;
|
|
284
|
+
result: LogEventResult;
|
|
285
|
+
};
|
|
279
286
|
"open_advertisers_page": {
|
|
280
287
|
input: OpenAdvertisersPageInput;
|
|
281
288
|
result: OpenAdvertisersPageResult;
|
|
@@ -624,6 +631,15 @@ export declare class Apostra extends Transport {
|
|
|
624
631
|
getStatus(input?: GetStatusInput, options?: RequestOptions): Promise<GetStatusResult>;
|
|
625
632
|
/** Current account, state, blockers, exact fixes, and reachable accounts. For seller demand, use it to tell whether readiness stops requests before source calls; read before diagnosing source health, empty responses, or demand. A Developer account adds each agent's stage, blocker, and next call. Returns the data together with response headers and request ID. */
|
|
626
633
|
getStatusWithResponse(input?: GetStatusInput, options?: RequestOptions): Promise<ResponseDetails<GetStatusResult>>;
|
|
634
|
+
/**
|
|
635
|
+
* Send up to 10,000 AdCP conversion events (log_event) to an event source the advertiser registered with save_event_source. Events must also pass the v2 rules: no raw email or phone in user_match, each event_type + event_id once per call. One invalid event refuses the whole call.
|
|
636
|
+
*
|
|
637
|
+
* @example
|
|
638
|
+
* await client.logEvent(input, { idempotencyKey: 'stable-key' })
|
|
639
|
+
*/
|
|
640
|
+
logEvent(input: LogEventInput, options: WriteRequestOptions): Promise<LogEventResult>;
|
|
641
|
+
/** Send up to 10,000 AdCP conversion events (log_event) to an event source the advertiser registered with save_event_source. Events must also pass the v2 rules: no raw email or phone in user_match, each event_type + event_id once per call. One invalid event refuses the whole call. Returns the data together with response headers and request ID. */
|
|
642
|
+
logEventWithResponse(input: LogEventInput, options: WriteRequestOptions): Promise<ResponseDetails<LogEventResult>>;
|
|
627
643
|
/**
|
|
628
644
|
* Open the Advertisers Page: every advertiser with its campaign and draft counts and one next action each. Use it for "show my advertisers" or "where do I start"; the Page self-fetches. To add or set up an advertiser, pass intent: "add". For a text answer use search(kind: "advertiser").
|
|
629
645
|
*
|
|
@@ -913,13 +929,13 @@ export declare class Apostra extends Transport {
|
|
|
913
929
|
/** Sync first-party CRM audiences for a buyer advertiser. Each audiences[] item may add, remove, or delete members. Returns an operationId; use get(kind: audience, advertiserId: "...") to read match status after it settles. Returns the data together with response headers and request ID. */
|
|
914
930
|
saveAudienceWithResponse(input: SaveAudienceInput, options: WriteRequestOptions): Promise<ResponseDetails<SaveAudienceResult>>;
|
|
915
931
|
/**
|
|
916
|
-
* Accept Terms, set the payment terms sellers are asked for, or accept a plan, answer its offer and change its renewal. Cards stay off MCP.
|
|
932
|
+
* Accept Terms, set the payment terms sellers are asked for, or accept a plan, answer its offer and change its renewal. Accepting a plan needs an administrator to approve it on our site. Cards stay off MCP.
|
|
917
933
|
*
|
|
918
934
|
* @example
|
|
919
935
|
* await client.saveBilling(input, { idempotencyKey: 'stable-key' })
|
|
920
936
|
*/
|
|
921
937
|
saveBilling(input: SaveBillingInput, options: WriteRequestOptions): Promise<SaveBillingResult>;
|
|
922
|
-
/** Accept Terms, set the payment terms sellers are asked for, or accept a plan, answer its offer and change its renewal. Cards stay off MCP. Returns the data together with response headers and request ID. */
|
|
938
|
+
/** Accept Terms, set the payment terms sellers are asked for, or accept a plan, answer its offer and change its renewal. Accepting a plan needs an administrator to approve it on our site. Cards stay off MCP. Returns the data together with response headers and request ID. */
|
|
923
939
|
saveBillingWithResponse(input: SaveBillingInput, options: WriteRequestOptions): Promise<ResponseDetails<SaveBillingResult>>;
|
|
924
940
|
/**
|
|
925
941
|
* Write seller AI Business Rules. Policy content needs an account admin and both policy fields. Approval auto needs acknowledgeNoHumanReview.
|
|
@@ -1048,13 +1064,13 @@ export declare class Apostra extends Transport {
|
|
|
1048
1064
|
/** Create or update where a seller's inventory comes from. Pass `id` to change a source or omit it to add one. Pass only `agentId` or `adServer` to open the form that connects an agent or an ad server. Credentials are never passed here; a source that needs one returns the page that collects it. Returns the data together with response headers and request ID. */
|
|
1049
1065
|
saveInventorySourceWithResponse(input: SaveInventorySourceInput, options: WriteRequestOptions): Promise<ResponseDetails<SaveInventorySourceResult>>;
|
|
1050
1066
|
/**
|
|
1051
|
-
* Manage seller lessons in a seller account
|
|
1067
|
+
* Manage seller lessons in a seller account; send the accountId of that account. propose requires lesson; approve and retire require lessonId; preview requires lessonId and brief. Preserve seller words from a private Session note and ask if kind or scope is unclear.
|
|
1052
1068
|
*
|
|
1053
1069
|
* @example
|
|
1054
1070
|
* await client.saveLesson(input, { idempotencyKey: 'stable-key' })
|
|
1055
1071
|
*/
|
|
1056
1072
|
saveLesson(input: SaveLessonInput, options: WriteRequestOptions): Promise<SaveLessonResult>;
|
|
1057
|
-
/** Manage seller lessons in a seller account
|
|
1073
|
+
/** Manage seller lessons in a seller account; send the accountId of that account. propose requires lesson; approve and retire require lessonId; preview requires lessonId and brief. Preserve seller words from a private Session note and ask if kind or scope is unclear. Returns the data together with response headers and request ID. */
|
|
1058
1074
|
saveLessonWithResponse(input: SaveLessonInput, options: WriteRequestOptions): Promise<ResponseDetails<SaveLessonResult>>;
|
|
1059
1075
|
/**
|
|
1060
1076
|
* Open a seller library request or close it with seller Material.
|
package/dist/generated/client.js
CHANGED
|
@@ -90,6 +90,15 @@ export class Apostra extends Transport {
|
|
|
90
90
|
getStatus(input = {}, options) { return this.request("get_status", input, options); }
|
|
91
91
|
/** Current account, state, blockers, exact fixes, and reachable accounts. For seller demand, use it to tell whether readiness stops requests before source calls; read before diagnosing source health, empty responses, or demand. A Developer account adds each agent's stage, blocker, and next call. Returns the data together with response headers and request ID. */
|
|
92
92
|
getStatusWithResponse(input = {}, options) { return this.requestDetailed("get_status", input, options); }
|
|
93
|
+
/**
|
|
94
|
+
* Send up to 10,000 AdCP conversion events (log_event) to an event source the advertiser registered with save_event_source. Events must also pass the v2 rules: no raw email or phone in user_match, each event_type + event_id once per call. One invalid event refuses the whole call.
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* await client.logEvent(input, { idempotencyKey: 'stable-key' })
|
|
98
|
+
*/
|
|
99
|
+
logEvent(input, options) { return this.request("log_event", input, options); }
|
|
100
|
+
/** Send up to 10,000 AdCP conversion events (log_event) to an event source the advertiser registered with save_event_source. Events must also pass the v2 rules: no raw email or phone in user_match, each event_type + event_id once per call. One invalid event refuses the whole call. Returns the data together with response headers and request ID. */
|
|
101
|
+
logEventWithResponse(input, options) { return this.requestDetailed("log_event", input, options); }
|
|
93
102
|
/**
|
|
94
103
|
* Open the Advertisers Page: every advertiser with its campaign and draft counts and one next action each. Use it for "show my advertisers" or "where do I start"; the Page self-fetches. To add or set up an advertiser, pass intent: "add". For a text answer use search(kind: "advertiser").
|
|
95
104
|
*
|
|
@@ -379,13 +388,13 @@ export class Apostra extends Transport {
|
|
|
379
388
|
/** Sync first-party CRM audiences for a buyer advertiser. Each audiences[] item may add, remove, or delete members. Returns an operationId; use get(kind: audience, advertiserId: "...") to read match status after it settles. Returns the data together with response headers and request ID. */
|
|
380
389
|
saveAudienceWithResponse(input, options) { return this.requestDetailed("save_audience", input, options); }
|
|
381
390
|
/**
|
|
382
|
-
* Accept Terms, set the payment terms sellers are asked for, or accept a plan, answer its offer and change its renewal. Cards stay off MCP.
|
|
391
|
+
* Accept Terms, set the payment terms sellers are asked for, or accept a plan, answer its offer and change its renewal. Accepting a plan needs an administrator to approve it on our site. Cards stay off MCP.
|
|
383
392
|
*
|
|
384
393
|
* @example
|
|
385
394
|
* await client.saveBilling(input, { idempotencyKey: 'stable-key' })
|
|
386
395
|
*/
|
|
387
396
|
saveBilling(input, options) { return this.request("save_billing", input, options); }
|
|
388
|
-
/** Accept Terms, set the payment terms sellers are asked for, or accept a plan, answer its offer and change its renewal. Cards stay off MCP. Returns the data together with response headers and request ID. */
|
|
397
|
+
/** Accept Terms, set the payment terms sellers are asked for, or accept a plan, answer its offer and change its renewal. Accepting a plan needs an administrator to approve it on our site. Cards stay off MCP. Returns the data together with response headers and request ID. */
|
|
389
398
|
saveBillingWithResponse(input, options) { return this.requestDetailed("save_billing", input, options); }
|
|
390
399
|
/**
|
|
391
400
|
* Write seller AI Business Rules. Policy content needs an account admin and both policy fields. Approval auto needs acknowledgeNoHumanReview.
|
|
@@ -514,13 +523,13 @@ export class Apostra extends Transport {
|
|
|
514
523
|
/** Create or update where a seller's inventory comes from. Pass `id` to change a source or omit it to add one. Pass only `agentId` or `adServer` to open the form that connects an agent or an ad server. Credentials are never passed here; a source that needs one returns the page that collects it. Returns the data together with response headers and request ID. */
|
|
515
524
|
saveInventorySourceWithResponse(input, options) { return this.requestDetailed("save_inventory_source", input, options); }
|
|
516
525
|
/**
|
|
517
|
-
* Manage seller lessons in a seller account
|
|
526
|
+
* Manage seller lessons in a seller account; send the accountId of that account. propose requires lesson; approve and retire require lessonId; preview requires lessonId and brief. Preserve seller words from a private Session note and ask if kind or scope is unclear.
|
|
518
527
|
*
|
|
519
528
|
* @example
|
|
520
529
|
* await client.saveLesson(input, { idempotencyKey: 'stable-key' })
|
|
521
530
|
*/
|
|
522
531
|
saveLesson(input, options) { return this.request("save_lesson", input, options); }
|
|
523
|
-
/** Manage seller lessons in a seller account
|
|
532
|
+
/** Manage seller lessons in a seller account; send the accountId of that account. propose requires lesson; approve and retire require lessonId; preview requires lessonId and brief. Preserve seller words from a private Session note and ask if kind or scope is unclear. Returns the data together with response headers and request ID. */
|
|
524
533
|
saveLessonWithResponse(input, options) { return this.requestDetailed("save_lesson", input, options); }
|
|
525
534
|
/**
|
|
526
535
|
* Open a seller library request or close it with seller Material.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const version = "0.
|
|
1
|
+
export declare const version = "0.40.0";
|
|
2
2
|
export declare const baseUrl = "https://api.apostra.com/api/v3";
|
|
3
3
|
export declare const m2mTokenUrl = "https://identity.scope3.com/oauth2/token";
|
|
4
4
|
export declare const operations: {
|
|
@@ -180,6 +180,21 @@ export declare const operations: {
|
|
|
180
180
|
}];
|
|
181
181
|
readonly summary: "Current account, state, blockers, exact fixes, and reachable accounts. For seller demand, use it to tell whether readiness stops requests before source calls; read before diagnosing source health, empty responses, or demand. A Developer account adds each agent's stage, blocker, and next call.";
|
|
182
182
|
};
|
|
183
|
+
readonly log_event: {
|
|
184
|
+
readonly path: "/tools/log_event";
|
|
185
|
+
readonly method: "POST";
|
|
186
|
+
readonly body: true;
|
|
187
|
+
readonly binary: false;
|
|
188
|
+
readonly idempotencyKey: true;
|
|
189
|
+
readonly bodyKeyField: "idempotencyKey";
|
|
190
|
+
readonly parameters: readonly [];
|
|
191
|
+
readonly security: readonly [{
|
|
192
|
+
readonly apiKeyAuth: readonly [];
|
|
193
|
+
}, {
|
|
194
|
+
readonly m2mOAuth: readonly ["interchange:write"];
|
|
195
|
+
}];
|
|
196
|
+
readonly summary: "Send up to 10,000 AdCP conversion events (log_event) to an event source the advertiser registered with save_event_source. Events must also pass the v2 rules: no raw email or phone in user_match, each event_type + event_id once per call. One invalid event refuses the whole call.";
|
|
197
|
+
};
|
|
183
198
|
readonly open_advertisers_page: {
|
|
184
199
|
readonly path: "/tools/open_advertisers_page";
|
|
185
200
|
readonly method: "POST";
|
|
@@ -642,7 +657,7 @@ export declare const operations: {
|
|
|
642
657
|
}, {
|
|
643
658
|
readonly m2mOAuth: readonly ["interchange:read"];
|
|
644
659
|
}];
|
|
645
|
-
readonly summary: "Accept Terms, set the payment terms sellers are asked for, or accept a plan, answer its offer and change its renewal. Cards stay off MCP.";
|
|
660
|
+
readonly summary: "Accept Terms, set the payment terms sellers are asked for, or accept a plan, answer its offer and change its renewal. Accepting a plan needs an administrator to approve it on our site. Cards stay off MCP.";
|
|
646
661
|
};
|
|
647
662
|
readonly save_business_rules: {
|
|
648
663
|
readonly path: "/tools/save_business_rules";
|
|
@@ -856,7 +871,7 @@ export declare const operations: {
|
|
|
856
871
|
}, {
|
|
857
872
|
readonly m2mOAuth: readonly ["interchange:write"];
|
|
858
873
|
}];
|
|
859
|
-
readonly summary: "Manage seller lessons in a seller account
|
|
874
|
+
readonly summary: "Manage seller lessons in a seller account; send the accountId of that account. propose requires lesson; approve and retire require lessonId; preview requires lessonId and brief. Preserve seller words from a private Session note and ask if kind or scope is unclear.";
|
|
860
875
|
};
|
|
861
876
|
readonly save_library_request: {
|
|
862
877
|
readonly path: "/tools/save_library_request";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Generated. Do not edit.
|
|
2
|
-
export const version = '0.
|
|
2
|
+
export const version = '0.40.0';
|
|
3
3
|
export const baseUrl = "https://api.apostra.com/api/v3";
|
|
4
4
|
export const m2mTokenUrl = "https://identity.scope3.com/oauth2/token";
|
|
5
5
|
export const operations = {
|
|
@@ -246,6 +246,26 @@ export const operations = {
|
|
|
246
246
|
],
|
|
247
247
|
"summary": "Current account, state, blockers, exact fixes, and reachable accounts. For seller demand, use it to tell whether readiness stops requests before source calls; read before diagnosing source health, empty responses, or demand. A Developer account adds each agent's stage, blocker, and next call."
|
|
248
248
|
},
|
|
249
|
+
"log_event": {
|
|
250
|
+
"path": "/tools/log_event",
|
|
251
|
+
"method": "POST",
|
|
252
|
+
"body": true,
|
|
253
|
+
"binary": false,
|
|
254
|
+
"idempotencyKey": true,
|
|
255
|
+
"bodyKeyField": "idempotencyKey",
|
|
256
|
+
"parameters": [],
|
|
257
|
+
"security": [
|
|
258
|
+
{
|
|
259
|
+
"apiKeyAuth": []
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
"m2mOAuth": [
|
|
263
|
+
"interchange:write"
|
|
264
|
+
]
|
|
265
|
+
}
|
|
266
|
+
],
|
|
267
|
+
"summary": "Send up to 10,000 AdCP conversion events (log_event) to an event source the advertiser registered with save_event_source. Events must also pass the v2 rules: no raw email or phone in user_match, each event_type + event_id once per call. One invalid event refuses the whole call."
|
|
268
|
+
},
|
|
249
269
|
"open_advertisers_page": {
|
|
250
270
|
"path": "/tools/open_advertisers_page",
|
|
251
271
|
"method": "POST",
|
|
@@ -873,7 +893,7 @@ export const operations = {
|
|
|
873
893
|
]
|
|
874
894
|
}
|
|
875
895
|
],
|
|
876
|
-
"summary": "Accept Terms, set the payment terms sellers are asked for, or accept a plan, answer its offer and change its renewal. Cards stay off MCP."
|
|
896
|
+
"summary": "Accept Terms, set the payment terms sellers are asked for, or accept a plan, answer its offer and change its renewal. Accepting a plan needs an administrator to approve it on our site. Cards stay off MCP."
|
|
877
897
|
},
|
|
878
898
|
"save_business_rules": {
|
|
879
899
|
"path": "/tools/save_business_rules",
|
|
@@ -1162,7 +1182,7 @@ export const operations = {
|
|
|
1162
1182
|
]
|
|
1163
1183
|
}
|
|
1164
1184
|
],
|
|
1165
|
-
"summary": "Manage seller lessons in a seller account
|
|
1185
|
+
"summary": "Manage seller lessons in a seller account; send the accountId of that account. propose requires lesson; approve and retire require lessonId; preview requires lessonId and brief. Preserve seller words from a private Session note and ask if kind or scope is unclear."
|
|
1166
1186
|
},
|
|
1167
1187
|
"save_library_request": {
|
|
1168
1188
|
"path": "/tools/save_library_request",
|