@elmohq/sdk 0.0.0-stage → 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.md +21 -0
- package/README.md +325 -2
- package/dist/calls/index.d.mts +288 -0
- package/dist/calls/index.d.mts.map +1 -0
- package/dist/calls/index.mjs +390 -0
- package/dist/calls/index.mjs.map +1 -0
- package/dist/index.d.mts +2 -0
- package/dist/index.mjs +1029 -0
- package/dist/index.mjs.map +1 -0
- package/dist/request-options-DWYI_Ldj.d.mts +1550 -0
- package/dist/request-options-DWYI_Ldj.d.mts.map +1 -0
- package/dist/tools-7Hs5J2xb.d.mts +1945 -0
- package/dist/tools-7Hs5J2xb.d.mts.map +1 -0
- package/dist/tools-SwP0sK8H.mjs +2458 -0
- package/dist/tools-SwP0sK8H.mjs.map +1 -0
- package/dist/types/index.d.mts +2 -0
- package/dist/types/index.mjs +1 -0
- package/package.json +67 -4
- package/src/calls/brands-analytics-get.ts +33 -0
- package/src/calls/brands-citations-domains-list.ts +36 -0
- package/src/calls/brands-citations-urls-list.ts +32 -0
- package/src/calls/brands-create.ts +19 -0
- package/src/calls/brands-get.ts +19 -0
- package/src/calls/brands-list.ts +18 -0
- package/src/calls/brands-opportunities-get.ts +42 -0
- package/src/calls/brands-prompt-performance-list.ts +39 -0
- package/src/calls/brands-query-fanout-get.ts +30 -0
- package/src/calls/brands-tags-list.ts +28 -0
- package/src/calls/brands-update.ts +20 -0
- package/src/calls/competitors-create.ts +23 -0
- package/src/calls/competitors-delete.ts +19 -0
- package/src/calls/competitors-get.ts +19 -0
- package/src/calls/competitors-list.ts +23 -0
- package/src/calls/competitors-update.ts +24 -0
- package/src/calls/index.ts +33 -0
- package/src/calls/me-get.ts +18 -0
- package/src/calls/models-list.ts +20 -0
- package/src/calls/organizations-billing-get.ts +37 -0
- package/src/calls/organizations-get.ts +24 -0
- package/src/calls/organizations-list.ts +27 -0
- package/src/calls/prompts-create.ts +27 -0
- package/src/calls/prompts-delete.ts +28 -0
- package/src/calls/prompts-get.ts +23 -0
- package/src/calls/prompts-list.ts +28 -0
- package/src/calls/prompts-runs-get.ts +27 -0
- package/src/calls/prompts-runs-list.ts +30 -0
- package/src/calls/prompts-snapshot-get.ts +28 -0
- package/src/calls/prompts-update.ts +29 -0
- package/src/calls/reports-create.ts +31 -0
- package/src/calls/reports-get.ts +27 -0
- package/src/calls/reports-list.ts +28 -0
- package/src/calls/tools-analyze.ts +26 -0
- package/src/client.ts +662 -0
- package/src/index.ts +21 -0
- package/src/internal/binding/rest/binding.ts +127 -0
- package/src/internal/binding/rest/errors.ts +107 -0
- package/src/internal/binding/rest/path.ts +9 -0
- package/src/internal/binding/rest/url.ts +97 -0
- package/src/internal/codec/json.ts +66 -0
- package/src/internal/codec/registry.ts +55 -0
- package/src/internal/core/backoff.ts +170 -0
- package/src/internal/core/body.ts +54 -0
- package/src/internal/core/browser.ts +11 -0
- package/src/internal/core/call-promise.ts +145 -0
- package/src/internal/core/callable.ts +11 -0
- package/src/internal/core/client.ts +89 -0
- package/src/internal/core/config.ts +84 -0
- package/src/internal/core/credentials.ts +40 -0
- package/src/internal/core/dispatch.ts +227 -0
- package/src/internal/core/env.ts +68 -0
- package/src/internal/core/errors.ts +431 -0
- package/src/internal/core/features.ts +60 -0
- package/src/internal/core/lazy-promise.ts +39 -0
- package/src/internal/core/metadata.ts +79 -0
- package/src/internal/core/params.ts +98 -0
- package/src/internal/core/protocol.ts +17 -0
- package/src/internal/core/read-reply.ts +7 -0
- package/src/internal/core/text.ts +7 -0
- package/src/internal/core/types.ts +556 -0
- package/src/internal/feature/auth.ts +201 -0
- package/src/internal/feature/interceptors.ts +36 -0
- package/src/internal/feature/logger.ts +222 -0
- package/src/internal/feature/retry.ts +165 -0
- package/src/internal/feature/rules.ts +54 -0
- package/src/internal/feature/timeout.ts +146 -0
- package/src/internal/feature/validate.ts +74 -0
- package/src/internal/page/page.ts +402 -0
- package/src/internal/transport/fetch.ts +82 -0
- package/src/resources/analytics.ts +363 -0
- package/src/resources/brands.ts +285 -0
- package/src/resources/competitors.ts +212 -0
- package/src/resources/identity.ts +48 -0
- package/src/resources/models.ts +32 -0
- package/src/resources/opportunities.ts +79 -0
- package/src/resources/organizations.ts +181 -0
- package/src/resources/prompts.ts +292 -0
- package/src/resources/reports.ts +211 -0
- package/src/resources/runs.ts +123 -0
- package/src/resources/shared/auth.ts +13 -0
- package/src/resources/shared/request-options.ts +26 -0
- package/src/resources/shared/resource.ts +23 -0
- package/src/resources/shared/rule.ts +25 -0
- package/src/resources/snapshots.ts +54 -0
- package/src/resources/tags.ts +46 -0
- package/src/resources/tools.ts +68 -0
- package/src/types/analytics.ts +497 -0
- package/src/types/brands.ts +228 -0
- package/src/types/competitors.ts +196 -0
- package/src/types/identity.ts +55 -0
- package/src/types/index.ts +163 -0
- package/src/types/models.ts +40 -0
- package/src/types/opportunities.ts +84 -0
- package/src/types/organizations.ts +157 -0
- package/src/types/prompts.ts +231 -0
- package/src/types/reports.ts +266 -0
- package/src/types/runs.ts +131 -0
- package/src/types/shared/brand-id-path.ts +2 -0
- package/src/types/shared/conflict-error.ts +7 -0
- package/src/types/shared/error.ts +29 -0
- package/src/types/shared/limit.ts +8 -0
- package/src/types/shared/mention-entry.ts +21 -0
- package/src/types/shared/model-filter.ts +15 -0
- package/src/types/shared/not-found-error.ts +4 -0
- package/src/types/shared/page.ts +7 -0
- package/src/types/shared/pagination.ts +7 -0
- package/src/types/shared/validation-error.ts +4 -0
- package/src/types/snapshots.ts +88 -0
- package/src/types/tags.ts +47 -0
- package/src/types/tools.ts +78 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { InputRule } from '../../internal/core/types';
|
|
2
|
+
|
|
3
|
+
export const nameRule: InputRule = {
|
|
4
|
+
min: 1,
|
|
5
|
+
name: 'name',
|
|
6
|
+
of: 'characters',
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const domainsRule: InputRule = {
|
|
10
|
+
min: 1,
|
|
11
|
+
name: 'domains',
|
|
12
|
+
of: 'items',
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const brandNameRule: InputRule = {
|
|
16
|
+
min: 1,
|
|
17
|
+
name: 'brandName',
|
|
18
|
+
of: 'characters',
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const valueRule: InputRule = {
|
|
22
|
+
min: 1,
|
|
23
|
+
name: 'value',
|
|
24
|
+
of: 'characters',
|
|
25
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { apiKeyRequirements } from './shared/auth';
|
|
2
|
+
import type { RequestOptions } from './shared/request-options';
|
|
3
|
+
import { ElmoResource } from './shared/resource';
|
|
4
|
+
import { callPromise, RestCallPromise } from '../internal/core/call-promise';
|
|
5
|
+
import { callable } from '../internal/core/callable';
|
|
6
|
+
import { mergeParams, placeParams } from '../internal/core/params';
|
|
7
|
+
import type {
|
|
8
|
+
CitedURLEntry,
|
|
9
|
+
GetPromptSnapshotErrors,
|
|
10
|
+
GetPromptSnapshotParams,
|
|
11
|
+
GetPromptSnapshotResponses,
|
|
12
|
+
PromptSnapshot,
|
|
13
|
+
} from '../types/snapshots';
|
|
14
|
+
|
|
15
|
+
export const getPromptSnapshotFields = { path: ['promptId'] };
|
|
16
|
+
|
|
17
|
+
export const getPromptSnapshotDescriptor = /* @__PURE__ */ callable({
|
|
18
|
+
address: '/prompts/{promptId}/snapshot',
|
|
19
|
+
auth: apiKeyRequirements,
|
|
20
|
+
method: 'get',
|
|
21
|
+
returns: 'json',
|
|
22
|
+
} as const);
|
|
23
|
+
|
|
24
|
+
/** Aggregated analytics snapshots for prompts */
|
|
25
|
+
export class Snapshot extends ElmoResource {
|
|
26
|
+
/**
|
|
27
|
+
* Get an aggregated snapshot of mention and citation analytics for a specific prompt over a date
|
|
28
|
+
* range. Use this to identify competitive gaps, track brand visibility trends, and discover top
|
|
29
|
+
* cited URLs.
|
|
30
|
+
*
|
|
31
|
+
* @param promptId The ID of the prompt
|
|
32
|
+
*/
|
|
33
|
+
public get(
|
|
34
|
+
promptId: string,
|
|
35
|
+
params: GetPromptSnapshotParams,
|
|
36
|
+
options?: RequestOptions,
|
|
37
|
+
): RestCallPromise<GetPromptSnapshotResponses, GetPromptSnapshotErrors> {
|
|
38
|
+
return callPromise(
|
|
39
|
+
options?.client ?? this.client,
|
|
40
|
+
getPromptSnapshotDescriptor,
|
|
41
|
+
mergeParams(placeParams({ ...params, promptId }, getPromptSnapshotFields, 'query'), options),
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export declare namespace Snapshot {
|
|
47
|
+
export type {
|
|
48
|
+
CitedURLEntry,
|
|
49
|
+
GetPromptSnapshotErrors,
|
|
50
|
+
GetPromptSnapshotParams,
|
|
51
|
+
GetPromptSnapshotResponses,
|
|
52
|
+
PromptSnapshot,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { apiKeyRequirements } from './shared/auth';
|
|
2
|
+
import type { RequestOptions } from './shared/request-options';
|
|
3
|
+
import { ElmoResource } from './shared/resource';
|
|
4
|
+
import { callPromise, RestCallPromise } from '../internal/core/call-promise';
|
|
5
|
+
import { callable } from '../internal/core/callable';
|
|
6
|
+
import { mergeParams, placeParams } from '../internal/core/params';
|
|
7
|
+
import type { BrandIdPath } from '../types/shared/brand-id-path';
|
|
8
|
+
import type { ListBrandTagsErrors, ListBrandTagsResponses, Tag, TagList } from '../types/tags';
|
|
9
|
+
|
|
10
|
+
export const listBrandTagsFields = { path: ['brandId'] };
|
|
11
|
+
|
|
12
|
+
export const listBrandTagsDescriptor = /* @__PURE__ */ callable({
|
|
13
|
+
address: '/brands/{brandId}/tags',
|
|
14
|
+
auth: apiKeyRequirements,
|
|
15
|
+
method: 'get',
|
|
16
|
+
returns: 'json',
|
|
17
|
+
} as const);
|
|
18
|
+
|
|
19
|
+
/** The tags in use on a brand's prompts */
|
|
20
|
+
export class Tags extends ElmoResource {
|
|
21
|
+
/**
|
|
22
|
+
* List a brand's tags
|
|
23
|
+
*
|
|
24
|
+
* Every tag in use on the brand's prompts, with how many carry each — enough to build the same
|
|
25
|
+
* filter the dashboard shows without paging the whole prompt list to derive it.
|
|
26
|
+
*
|
|
27
|
+
* Tags are not a resource of their own: a tag exists exactly as long as some prompt carries it.
|
|
28
|
+
* `branded` and `unbranded` are computed by Elmo and always listed.
|
|
29
|
+
*
|
|
30
|
+
* @param brandId Brand identifier.
|
|
31
|
+
*/
|
|
32
|
+
public list(
|
|
33
|
+
brandId: BrandIdPath,
|
|
34
|
+
options?: RequestOptions,
|
|
35
|
+
): RestCallPromise<ListBrandTagsResponses, ListBrandTagsErrors> {
|
|
36
|
+
return callPromise(
|
|
37
|
+
options?.client ?? this.client,
|
|
38
|
+
listBrandTagsDescriptor,
|
|
39
|
+
mergeParams(placeParams({ brandId }, listBrandTagsFields, 'query'), options),
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export declare namespace Tags {
|
|
45
|
+
export type { ListBrandTagsErrors, ListBrandTagsResponses, Tag, TagList };
|
|
46
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { apiKeyRequirements } from './shared/auth';
|
|
2
|
+
import type { RequestOptions } from './shared/request-options';
|
|
3
|
+
import { ElmoResource } from './shared/resource';
|
|
4
|
+
import { callPromise, RestCallPromise } from '../internal/core/call-promise';
|
|
5
|
+
import { callable } from '../internal/core/callable';
|
|
6
|
+
import { groupParams, mergeParams } from '../internal/core/params';
|
|
7
|
+
import type {
|
|
8
|
+
AnalyzeBrandErrors,
|
|
9
|
+
AnalyzeBrandParams,
|
|
10
|
+
AnalyzeBrandResponses,
|
|
11
|
+
OnboardingSuggestion,
|
|
12
|
+
} from '../types/tools';
|
|
13
|
+
|
|
14
|
+
export const analyzeBrandDescriptor = /* @__PURE__ */ callable({
|
|
15
|
+
address: '/tools/analyze',
|
|
16
|
+
auth: apiKeyRequirements,
|
|
17
|
+
mediaType: 'application/json',
|
|
18
|
+
method: 'post',
|
|
19
|
+
returns: 'json',
|
|
20
|
+
rules: [
|
|
21
|
+
{
|
|
22
|
+
min: 1,
|
|
23
|
+
name: 'website',
|
|
24
|
+
of: 'characters',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
max: 100,
|
|
28
|
+
min: 0,
|
|
29
|
+
name: 'maxCompetitors',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
max: 100,
|
|
33
|
+
min: 0,
|
|
34
|
+
name: 'maxPrompts',
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
} as const);
|
|
38
|
+
|
|
39
|
+
/** One-shot helpers (e.g. brand analysis) that don't persist anything */
|
|
40
|
+
export class Tools extends ElmoResource {
|
|
41
|
+
/**
|
|
42
|
+
* Analyze a website
|
|
43
|
+
*
|
|
44
|
+
* Run brand analysis without persisting anything. Returns suggested additional domains, aliases,
|
|
45
|
+
* competitors, and prompts.
|
|
46
|
+
*
|
|
47
|
+
* Requires an instance admin key; organization keys receive `403`.
|
|
48
|
+
*/
|
|
49
|
+
public analyze(
|
|
50
|
+
params: AnalyzeBrandParams,
|
|
51
|
+
options?: RequestOptions,
|
|
52
|
+
): RestCallPromise<AnalyzeBrandResponses, AnalyzeBrandErrors> {
|
|
53
|
+
return callPromise(
|
|
54
|
+
options?.client ?? this.client,
|
|
55
|
+
analyzeBrandDescriptor,
|
|
56
|
+
mergeParams(groupParams(params, 'body'), options),
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export declare namespace Tools {
|
|
62
|
+
export type {
|
|
63
|
+
AnalyzeBrandErrors,
|
|
64
|
+
AnalyzeBrandParams,
|
|
65
|
+
AnalyzeBrandResponses,
|
|
66
|
+
OnboardingSuggestion,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
@@ -0,0 +1,497 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ForbiddenError,
|
|
3
|
+
InternalServerError,
|
|
4
|
+
RateLimitError,
|
|
5
|
+
UnauthorizedError,
|
|
6
|
+
} from './shared/error';
|
|
7
|
+
import type { ModelFilter, WindowEnd, WindowStart } from './shared/model-filter';
|
|
8
|
+
import type { NotFoundError } from './shared/not-found-error';
|
|
9
|
+
import type { ValidationError } from './shared/validation-error';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The window the response was computed over, echoed back as the half-open instants it resolved to.
|
|
13
|
+
*/
|
|
14
|
+
export type DateRange = {
|
|
15
|
+
/** Exclusive upper bound, in UTC. */
|
|
16
|
+
end: Date;
|
|
17
|
+
/** Inclusive lower bound, in UTC. */
|
|
18
|
+
start: Date;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export type VisibilityPoint = {
|
|
22
|
+
date: string;
|
|
23
|
+
/**
|
|
24
|
+
* Null on days with no runs to plot; the series is not gap-filled with zeros. Ratio 0–1; multiply
|
|
25
|
+
* by 100 for a percentage.
|
|
26
|
+
*
|
|
27
|
+
* @minimum 0
|
|
28
|
+
* @maximum 1
|
|
29
|
+
*/
|
|
30
|
+
visibility: number | null;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export type ShareOfVoiceEntry = {
|
|
34
|
+
/** True for the tracked brand's own row. */
|
|
35
|
+
isBrand: boolean;
|
|
36
|
+
mentions: number;
|
|
37
|
+
/** Brand or competitor name. */
|
|
38
|
+
name: string;
|
|
39
|
+
/** Distinct prompts this entity appeared in. */
|
|
40
|
+
prompts: number;
|
|
41
|
+
/**
|
|
42
|
+
* This entity's share of all brand and competitor mentions. Ratio 0–1; multiply by 100 for a
|
|
43
|
+
* percentage.
|
|
44
|
+
*
|
|
45
|
+
* @minimum 0
|
|
46
|
+
* @maximum 1
|
|
47
|
+
*/
|
|
48
|
+
share: number;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export type ShareOfVoicePoint = {
|
|
52
|
+
date: string;
|
|
53
|
+
/**
|
|
54
|
+
* The brand's share on this day. Null on days with no runs. Ratio 0–1; multiply by 100 for a
|
|
55
|
+
* percentage.
|
|
56
|
+
*
|
|
57
|
+
* @minimum 0
|
|
58
|
+
* @maximum 1
|
|
59
|
+
*/
|
|
60
|
+
share: number | null;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export type CitationDomain = {
|
|
64
|
+
/** Which side of the citation landscape the domain sits on. */
|
|
65
|
+
category:
|
|
66
|
+
| 'brand'
|
|
67
|
+
| 'competitor'
|
|
68
|
+
| 'editorial'
|
|
69
|
+
| 'reviews'
|
|
70
|
+
| 'ecommerce'
|
|
71
|
+
| 'social'
|
|
72
|
+
| 'developer'
|
|
73
|
+
| 'pr'
|
|
74
|
+
| 'reference'
|
|
75
|
+
| 'institutional'
|
|
76
|
+
| 'other';
|
|
77
|
+
/**
|
|
78
|
+
* How this window compares with the equal-length window before it, as a multiplier of the
|
|
79
|
+
* previous count: 2 means twice as many citations, 0.5 means half, 1 means unchanged. Not a
|
|
80
|
+
* percentage change — 1.5 is "1.5x", which is a 50% increase. Null when the domain had no
|
|
81
|
+
* citations in the previous window, so there is nothing to divide by.
|
|
82
|
+
*
|
|
83
|
+
* @minimum 0
|
|
84
|
+
*/
|
|
85
|
+
changeFactor: number | null;
|
|
86
|
+
/** Citations to this domain in the window. */
|
|
87
|
+
count: number;
|
|
88
|
+
domain: string;
|
|
89
|
+
/** Citations in the equal-length window immediately before this one. */
|
|
90
|
+
previousCount: number;
|
|
91
|
+
/** Distinct prompts whose answers cited this domain. */
|
|
92
|
+
promptCount: number;
|
|
93
|
+
/**
|
|
94
|
+
* Share of all citations in the window. Ratio 0–1; multiply by 100 for a percentage.
|
|
95
|
+
*
|
|
96
|
+
* @minimum 0
|
|
97
|
+
* @maximum 1
|
|
98
|
+
*/
|
|
99
|
+
share: number;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
export type CitationDomainList = {
|
|
103
|
+
brandId: string;
|
|
104
|
+
/** Every domain cited over the window, ordered by citation count. */
|
|
105
|
+
data: Array<CitationDomain>;
|
|
106
|
+
range: DateRange;
|
|
107
|
+
totals: {
|
|
108
|
+
citations: number;
|
|
109
|
+
uniqueDomains: number;
|
|
110
|
+
uniqueUrls: number;
|
|
111
|
+
};
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
export type CitationURL = {
|
|
115
|
+
/** Which side of the citation landscape the domain sits on. */
|
|
116
|
+
category:
|
|
117
|
+
| 'brand'
|
|
118
|
+
| 'competitor'
|
|
119
|
+
| 'editorial'
|
|
120
|
+
| 'reviews'
|
|
121
|
+
| 'ecommerce'
|
|
122
|
+
| 'social'
|
|
123
|
+
| 'developer'
|
|
124
|
+
| 'pr'
|
|
125
|
+
| 'reference'
|
|
126
|
+
| 'institutional'
|
|
127
|
+
| 'other';
|
|
128
|
+
count: number;
|
|
129
|
+
domain: string;
|
|
130
|
+
/** Not cited in the equal-length window immediately before this one. */
|
|
131
|
+
isNew: boolean;
|
|
132
|
+
/** What kind of page was cited. */
|
|
133
|
+
pageType:
|
|
134
|
+
| 'homepage'
|
|
135
|
+
| 'article'
|
|
136
|
+
| 'listicle'
|
|
137
|
+
| 'howto'
|
|
138
|
+
| 'comparison'
|
|
139
|
+
| 'review'
|
|
140
|
+
| 'forum'
|
|
141
|
+
| 'video'
|
|
142
|
+
| 'doc'
|
|
143
|
+
| 'product'
|
|
144
|
+
| 'info'
|
|
145
|
+
| 'search'
|
|
146
|
+
| 'shopping'
|
|
147
|
+
| 'other';
|
|
148
|
+
promptCount: number;
|
|
149
|
+
title: string | null;
|
|
150
|
+
url: string;
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
export type CitationURLList = {
|
|
154
|
+
brandId: string;
|
|
155
|
+
/** Every URL cited over the window, ordered by citation count. */
|
|
156
|
+
data: Array<CitationURL>;
|
|
157
|
+
range: DateRange;
|
|
158
|
+
totals: {
|
|
159
|
+
citations: number;
|
|
160
|
+
uniqueDomains: number;
|
|
161
|
+
uniqueUrls: number;
|
|
162
|
+
};
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
export type FanoutQuery = {
|
|
166
|
+
promptCount: number;
|
|
167
|
+
/** A search the engine ran while answering. */
|
|
168
|
+
query: string;
|
|
169
|
+
runs: number;
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
export type BrandQueryFanout = {
|
|
173
|
+
avgQueriesPerRun: number;
|
|
174
|
+
brandId: string;
|
|
175
|
+
/**
|
|
176
|
+
* Share of fan-out query instances whose answer mentioned the brand. Ratio 0–1; multiply by 100
|
|
177
|
+
* for a percentage.
|
|
178
|
+
*
|
|
179
|
+
* @minimum 0
|
|
180
|
+
* @maximum 1
|
|
181
|
+
*/
|
|
182
|
+
coverageRate: number;
|
|
183
|
+
/** Every distinct sub-query over the window, ordered by the runs that ran it. */
|
|
184
|
+
data: Array<FanoutQuery>;
|
|
185
|
+
/**
|
|
186
|
+
* Runs that searched at all. Engines that don't expose their searches contribute runs but no
|
|
187
|
+
* queries.
|
|
188
|
+
*/
|
|
189
|
+
fanoutRuns: number;
|
|
190
|
+
range: DateRange;
|
|
191
|
+
totalQueries: number;
|
|
192
|
+
totalRuns: number;
|
|
193
|
+
uniqueQueries: number;
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
export type PromptPerformance = {
|
|
197
|
+
/**
|
|
198
|
+
* Share of this prompt's runs mentioning the brand. Ratio 0–1; multiply by 100 for a percentage.
|
|
199
|
+
*
|
|
200
|
+
* @minimum 0
|
|
201
|
+
* @maximum 1
|
|
202
|
+
*/
|
|
203
|
+
brandMentionRate: number;
|
|
204
|
+
/**
|
|
205
|
+
* Share of this prompt's runs mentioning any tracked competitor. Ratio 0–1; multiply by 100 for a
|
|
206
|
+
* percentage.
|
|
207
|
+
*
|
|
208
|
+
* @minimum 0
|
|
209
|
+
* @maximum 1
|
|
210
|
+
*/
|
|
211
|
+
competitorMentionRate: number;
|
|
212
|
+
firstEvaluatedAt: Date | null;
|
|
213
|
+
lastRunAt: Date | null;
|
|
214
|
+
promptId: string;
|
|
215
|
+
tags: Array<string>;
|
|
216
|
+
totalRuns: number;
|
|
217
|
+
value: string;
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
export type PromptPerformanceList = {
|
|
221
|
+
brandId: string;
|
|
222
|
+
/** Every prompt sampled over the window, with its results. */
|
|
223
|
+
data: Array<PromptPerformance>;
|
|
224
|
+
range: DateRange;
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
export type ModelVisibility = {
|
|
228
|
+
brandMentions: number;
|
|
229
|
+
citations: number;
|
|
230
|
+
label: string;
|
|
231
|
+
model: string;
|
|
232
|
+
runs: number;
|
|
233
|
+
/**
|
|
234
|
+
* Share of this model's runs that mentioned the brand. Ratio 0–1; multiply by 100 for a
|
|
235
|
+
* percentage.
|
|
236
|
+
*
|
|
237
|
+
* @minimum 0
|
|
238
|
+
* @maximum 1
|
|
239
|
+
*/
|
|
240
|
+
visibility: number | null;
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Every non-paginated figure for a brand over one window. There is no parameter for selecting a
|
|
245
|
+
* subset: the four computations behind this share one scope resolution and run concurrently, so a
|
|
246
|
+
* subset would save a caller a fraction of one request and cost everyone a parameter to reason
|
|
247
|
+
* about.
|
|
248
|
+
*/
|
|
249
|
+
export type BrandAnalytics = {
|
|
250
|
+
brandId: string;
|
|
251
|
+
brandName: string;
|
|
252
|
+
/** Per-model visibility and run counts. Only models that produced a run in the window appear. */
|
|
253
|
+
models: Array<ModelVisibility>;
|
|
254
|
+
range: DateRange;
|
|
255
|
+
/** The brand against its tracked competitors. */
|
|
256
|
+
shareOfVoice: {
|
|
257
|
+
/**
|
|
258
|
+
* The brand's own share at the end of the window. Ratio 0–1; multiply by 100 for a percentage.
|
|
259
|
+
*
|
|
260
|
+
* @minimum 0
|
|
261
|
+
* @maximum 1
|
|
262
|
+
*/
|
|
263
|
+
brand: number | null;
|
|
264
|
+
/** Leaderboard, highest share first. */
|
|
265
|
+
entries: Array<ShareOfVoiceEntry>;
|
|
266
|
+
/** The brand's share over time. */
|
|
267
|
+
series: Array<ShareOfVoicePoint>;
|
|
268
|
+
};
|
|
269
|
+
totals: {
|
|
270
|
+
citations: number;
|
|
271
|
+
/** Enabled prompts counted in the window. */
|
|
272
|
+
prompts: number;
|
|
273
|
+
runs: number;
|
|
274
|
+
uniqueDomains: number;
|
|
275
|
+
uniqueUrls: number;
|
|
276
|
+
};
|
|
277
|
+
/** How often the brand is mentioned at all. */
|
|
278
|
+
visibility: {
|
|
279
|
+
/**
|
|
280
|
+
* The last plotted point — the number the dashboard hero shows. Ratio 0–1; multiply by 100 for
|
|
281
|
+
* a percentage.
|
|
282
|
+
*
|
|
283
|
+
* @minimum 0
|
|
284
|
+
* @maximum 1
|
|
285
|
+
*/
|
|
286
|
+
current: number | null;
|
|
287
|
+
series: Array<VisibilityPoint>;
|
|
288
|
+
};
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
/** Comma-separated prompt tags. Only prompts carrying at least one of them are counted. */
|
|
292
|
+
export type TagsFilter = string;
|
|
293
|
+
|
|
294
|
+
export type GetBrandAnalyticsErrors = {
|
|
295
|
+
/** Invalid request data */
|
|
296
|
+
400: ValidationError;
|
|
297
|
+
/** Authentication required */
|
|
298
|
+
401: UnauthorizedError;
|
|
299
|
+
/**
|
|
300
|
+
* The key is valid but not permitted: a missing scope, an admin-only endpoint, or a write in
|
|
301
|
+
* read-only (demo) mode.
|
|
302
|
+
*/
|
|
303
|
+
403: ForbiddenError;
|
|
304
|
+
/** Resource not found */
|
|
305
|
+
404: NotFoundError;
|
|
306
|
+
/** Per-key rate limit exceeded. */
|
|
307
|
+
429: RateLimitError;
|
|
308
|
+
/** Internal server error */
|
|
309
|
+
500: InternalServerError;
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
export type GetBrandAnalyticsResponses = {
|
|
313
|
+
/** Get a brand's analytics */
|
|
314
|
+
200: BrandAnalytics;
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
export type ListBrandCitationDomainsErrors = {
|
|
318
|
+
/** Invalid request data */
|
|
319
|
+
400: ValidationError;
|
|
320
|
+
/** Authentication required */
|
|
321
|
+
401: UnauthorizedError;
|
|
322
|
+
/**
|
|
323
|
+
* The key is valid but not permitted: a missing scope, an admin-only endpoint, or a write in
|
|
324
|
+
* read-only (demo) mode.
|
|
325
|
+
*/
|
|
326
|
+
403: ForbiddenError;
|
|
327
|
+
/** Resource not found */
|
|
328
|
+
404: NotFoundError;
|
|
329
|
+
/** Per-key rate limit exceeded. */
|
|
330
|
+
429: RateLimitError;
|
|
331
|
+
/** Internal server error */
|
|
332
|
+
500: InternalServerError;
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
export type ListBrandCitationDomainsResponses = {
|
|
336
|
+
/** List cited domains */
|
|
337
|
+
200: CitationDomainList;
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
export type ListBrandCitationURLsErrors = {
|
|
341
|
+
/** Invalid request data */
|
|
342
|
+
400: ValidationError;
|
|
343
|
+
/** Authentication required */
|
|
344
|
+
401: UnauthorizedError;
|
|
345
|
+
/**
|
|
346
|
+
* The key is valid but not permitted: a missing scope, an admin-only endpoint, or a write in
|
|
347
|
+
* read-only (demo) mode.
|
|
348
|
+
*/
|
|
349
|
+
403: ForbiddenError;
|
|
350
|
+
/** Resource not found */
|
|
351
|
+
404: NotFoundError;
|
|
352
|
+
/** Per-key rate limit exceeded. */
|
|
353
|
+
429: RateLimitError;
|
|
354
|
+
/** Internal server error */
|
|
355
|
+
500: InternalServerError;
|
|
356
|
+
};
|
|
357
|
+
|
|
358
|
+
export type ListBrandCitationURLsResponses = {
|
|
359
|
+
/** List cited URLs */
|
|
360
|
+
200: CitationURLList;
|
|
361
|
+
};
|
|
362
|
+
|
|
363
|
+
export type ListBrandPromptPerformanceErrors = {
|
|
364
|
+
/** Invalid request data */
|
|
365
|
+
400: ValidationError;
|
|
366
|
+
/** Authentication required */
|
|
367
|
+
401: UnauthorizedError;
|
|
368
|
+
/**
|
|
369
|
+
* The key is valid but not permitted: a missing scope, an admin-only endpoint, or a write in
|
|
370
|
+
* read-only (demo) mode.
|
|
371
|
+
*/
|
|
372
|
+
403: ForbiddenError;
|
|
373
|
+
/** Resource not found */
|
|
374
|
+
404: NotFoundError;
|
|
375
|
+
/** Per-key rate limit exceeded. */
|
|
376
|
+
429: RateLimitError;
|
|
377
|
+
/** Internal server error */
|
|
378
|
+
500: InternalServerError;
|
|
379
|
+
};
|
|
380
|
+
|
|
381
|
+
export type ListBrandPromptPerformanceResponses = {
|
|
382
|
+
/** List prompt performance */
|
|
383
|
+
200: PromptPerformanceList;
|
|
384
|
+
};
|
|
385
|
+
|
|
386
|
+
export type GetBrandQueryFanoutErrors = {
|
|
387
|
+
/** Invalid request data */
|
|
388
|
+
400: ValidationError;
|
|
389
|
+
/** Authentication required */
|
|
390
|
+
401: UnauthorizedError;
|
|
391
|
+
/**
|
|
392
|
+
* The key is valid but not permitted: a missing scope, an admin-only endpoint, or a write in
|
|
393
|
+
* read-only (demo) mode.
|
|
394
|
+
*/
|
|
395
|
+
403: ForbiddenError;
|
|
396
|
+
/** Resource not found */
|
|
397
|
+
404: NotFoundError;
|
|
398
|
+
/** Per-key rate limit exceeded. */
|
|
399
|
+
429: RateLimitError;
|
|
400
|
+
/** Internal server error */
|
|
401
|
+
500: InternalServerError;
|
|
402
|
+
};
|
|
403
|
+
|
|
404
|
+
export type GetBrandQueryFanoutResponses = {
|
|
405
|
+
/** Get query fan-out */
|
|
406
|
+
200: BrandQueryFanout;
|
|
407
|
+
};
|
|
408
|
+
|
|
409
|
+
export type GetBrandAnalyticsParams = {
|
|
410
|
+
/**
|
|
411
|
+
* Inclusive lower bound of the window, an ISO 8601 timestamp such as `2026-01-01T00:00:00Z`. A
|
|
412
|
+
* bare `YYYY-MM-DD` is rejected: that is `/prompts/{promptId}/snapshot`'s spelling and means a
|
|
413
|
+
* local calendar day there.
|
|
414
|
+
*/
|
|
415
|
+
start: WindowStart;
|
|
416
|
+
/**
|
|
417
|
+
* Exclusive upper bound of the window, an ISO 8601 timestamp. The window is half-open: a run at
|
|
418
|
+
* exactly `end` is outside it.
|
|
419
|
+
*/
|
|
420
|
+
end: WindowEnd;
|
|
421
|
+
/** Restrict to one model, e.g. `chatgpt`. See `models.list()`. */
|
|
422
|
+
model?: ModelFilter;
|
|
423
|
+
/** Comma-separated prompt tags. Only prompts carrying at least one of them are counted. */
|
|
424
|
+
tags?: TagsFilter;
|
|
425
|
+
};
|
|
426
|
+
|
|
427
|
+
export type ListBrandCitationDomainsParams = {
|
|
428
|
+
/**
|
|
429
|
+
* Inclusive lower bound of the window, an ISO 8601 timestamp such as `2026-01-01T00:00:00Z`. A
|
|
430
|
+
* bare `YYYY-MM-DD` is rejected: that is `/prompts/{promptId}/snapshot`'s spelling and means a
|
|
431
|
+
* local calendar day there.
|
|
432
|
+
*/
|
|
433
|
+
start: WindowStart;
|
|
434
|
+
/**
|
|
435
|
+
* Exclusive upper bound of the window, an ISO 8601 timestamp. The window is half-open: a run at
|
|
436
|
+
* exactly `end` is outside it.
|
|
437
|
+
*/
|
|
438
|
+
end: WindowEnd;
|
|
439
|
+
/** Restrict to one model, e.g. `chatgpt`. See `models.list()`. */
|
|
440
|
+
model?: ModelFilter;
|
|
441
|
+
/** Comma-separated prompt tags. Only prompts carrying at least one of them are counted. */
|
|
442
|
+
tags?: TagsFilter;
|
|
443
|
+
};
|
|
444
|
+
|
|
445
|
+
export type ListBrandCitationURLsParams = {
|
|
446
|
+
/**
|
|
447
|
+
* Inclusive lower bound of the window, an ISO 8601 timestamp such as `2026-01-01T00:00:00Z`. A
|
|
448
|
+
* bare `YYYY-MM-DD` is rejected: that is `/prompts/{promptId}/snapshot`'s spelling and means a
|
|
449
|
+
* local calendar day there.
|
|
450
|
+
*/
|
|
451
|
+
start: WindowStart;
|
|
452
|
+
/**
|
|
453
|
+
* Exclusive upper bound of the window, an ISO 8601 timestamp. The window is half-open: a run at
|
|
454
|
+
* exactly `end` is outside it.
|
|
455
|
+
*/
|
|
456
|
+
end: WindowEnd;
|
|
457
|
+
/** Restrict to one model, e.g. `chatgpt`. See `models.list()`. */
|
|
458
|
+
model?: ModelFilter;
|
|
459
|
+
/** Comma-separated prompt tags. Only prompts carrying at least one of them are counted. */
|
|
460
|
+
tags?: TagsFilter;
|
|
461
|
+
};
|
|
462
|
+
|
|
463
|
+
export type ListBrandPromptPerformanceParams = {
|
|
464
|
+
/**
|
|
465
|
+
* Inclusive lower bound of the window, an ISO 8601 timestamp such as `2026-01-01T00:00:00Z`. A
|
|
466
|
+
* bare `YYYY-MM-DD` is rejected: that is `/prompts/{promptId}/snapshot`'s spelling and means a
|
|
467
|
+
* local calendar day there.
|
|
468
|
+
*/
|
|
469
|
+
start: WindowStart;
|
|
470
|
+
/**
|
|
471
|
+
* Exclusive upper bound of the window, an ISO 8601 timestamp. The window is half-open: a run at
|
|
472
|
+
* exactly `end` is outside it.
|
|
473
|
+
*/
|
|
474
|
+
end: WindowEnd;
|
|
475
|
+
/** Restrict to one model, e.g. `chatgpt`. See `models.list()`. */
|
|
476
|
+
model?: ModelFilter;
|
|
477
|
+
/** Comma-separated prompt tags. Only prompts carrying at least one of them are counted. */
|
|
478
|
+
tags?: TagsFilter;
|
|
479
|
+
};
|
|
480
|
+
|
|
481
|
+
export type GetBrandQueryFanoutParams = {
|
|
482
|
+
/**
|
|
483
|
+
* Inclusive lower bound of the window, an ISO 8601 timestamp such as `2026-01-01T00:00:00Z`. A
|
|
484
|
+
* bare `YYYY-MM-DD` is rejected: that is `/prompts/{promptId}/snapshot`'s spelling and means a
|
|
485
|
+
* local calendar day there.
|
|
486
|
+
*/
|
|
487
|
+
start: WindowStart;
|
|
488
|
+
/**
|
|
489
|
+
* Exclusive upper bound of the window, an ISO 8601 timestamp. The window is half-open: a run at
|
|
490
|
+
* exactly `end` is outside it.
|
|
491
|
+
*/
|
|
492
|
+
end: WindowEnd;
|
|
493
|
+
/** Restrict to one model, e.g. `chatgpt`. See `models.list()`. */
|
|
494
|
+
model?: ModelFilter;
|
|
495
|
+
/** Comma-separated prompt tags. Only prompts carrying at least one of them are counted. */
|
|
496
|
+
tags?: TagsFilter;
|
|
497
|
+
};
|