@elmohq/sdk 0.0.0-stage → 0.1.1

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.
Files changed (129) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +326 -2
  3. package/dist/calls/index.d.mts +288 -0
  4. package/dist/calls/index.d.mts.map +1 -0
  5. package/dist/calls/index.mjs +390 -0
  6. package/dist/calls/index.mjs.map +1 -0
  7. package/dist/index.d.mts +2 -0
  8. package/dist/index.mjs +1031 -0
  9. package/dist/index.mjs.map +1 -0
  10. package/dist/request-options-B9S9d24M.d.mts +1549 -0
  11. package/dist/request-options-B9S9d24M.d.mts.map +1 -0
  12. package/dist/tools-7Hs5J2xb.d.mts +1945 -0
  13. package/dist/tools-7Hs5J2xb.d.mts.map +1 -0
  14. package/dist/tools-B1lVtYAr.mjs +2459 -0
  15. package/dist/tools-B1lVtYAr.mjs.map +1 -0
  16. package/dist/types/index.d.mts +2 -0
  17. package/dist/types/index.mjs +1 -0
  18. package/package.json +68 -4
  19. package/src/calls/brands-analytics-get.ts +33 -0
  20. package/src/calls/brands-citations-domains-list.ts +36 -0
  21. package/src/calls/brands-citations-urls-list.ts +32 -0
  22. package/src/calls/brands-create.ts +19 -0
  23. package/src/calls/brands-get.ts +19 -0
  24. package/src/calls/brands-list.ts +18 -0
  25. package/src/calls/brands-opportunities-get.ts +42 -0
  26. package/src/calls/brands-prompt-performance-list.ts +39 -0
  27. package/src/calls/brands-query-fanout-get.ts +30 -0
  28. package/src/calls/brands-tags-list.ts +28 -0
  29. package/src/calls/brands-update.ts +20 -0
  30. package/src/calls/competitors-create.ts +23 -0
  31. package/src/calls/competitors-delete.ts +19 -0
  32. package/src/calls/competitors-get.ts +19 -0
  33. package/src/calls/competitors-list.ts +23 -0
  34. package/src/calls/competitors-update.ts +24 -0
  35. package/src/calls/index.ts +33 -0
  36. package/src/calls/me-get.ts +18 -0
  37. package/src/calls/models-list.ts +20 -0
  38. package/src/calls/organizations-billing-get.ts +37 -0
  39. package/src/calls/organizations-get.ts +24 -0
  40. package/src/calls/organizations-list.ts +27 -0
  41. package/src/calls/prompts-create.ts +27 -0
  42. package/src/calls/prompts-delete.ts +28 -0
  43. package/src/calls/prompts-get.ts +23 -0
  44. package/src/calls/prompts-list.ts +28 -0
  45. package/src/calls/prompts-runs-get.ts +27 -0
  46. package/src/calls/prompts-runs-list.ts +30 -0
  47. package/src/calls/prompts-snapshot-get.ts +28 -0
  48. package/src/calls/prompts-update.ts +29 -0
  49. package/src/calls/reports-create.ts +31 -0
  50. package/src/calls/reports-get.ts +27 -0
  51. package/src/calls/reports-list.ts +28 -0
  52. package/src/calls/tools-analyze.ts +26 -0
  53. package/src/client.ts +649 -0
  54. package/src/index.ts +21 -0
  55. package/src/internal/binding/rest/binding.ts +127 -0
  56. package/src/internal/binding/rest/errors.ts +107 -0
  57. package/src/internal/binding/rest/path.ts +9 -0
  58. package/src/internal/binding/rest/url.ts +97 -0
  59. package/src/internal/codec/json.ts +66 -0
  60. package/src/internal/codec/registry.ts +55 -0
  61. package/src/internal/core/backoff.ts +170 -0
  62. package/src/internal/core/body.ts +54 -0
  63. package/src/internal/core/browser.ts +11 -0
  64. package/src/internal/core/call-promise.ts +145 -0
  65. package/src/internal/core/callable.ts +11 -0
  66. package/src/internal/core/client.ts +89 -0
  67. package/src/internal/core/config.ts +84 -0
  68. package/src/internal/core/credentials.ts +40 -0
  69. package/src/internal/core/dispatch.ts +225 -0
  70. package/src/internal/core/env.ts +68 -0
  71. package/src/internal/core/errors.ts +431 -0
  72. package/src/internal/core/features.ts +60 -0
  73. package/src/internal/core/lazy-promise.ts +39 -0
  74. package/src/internal/core/metadata.ts +79 -0
  75. package/src/internal/core/page.ts +402 -0
  76. package/src/internal/core/params.ts +98 -0
  77. package/src/internal/core/protocol.ts +17 -0
  78. package/src/internal/core/read-reply.ts +7 -0
  79. package/src/internal/core/text.ts +7 -0
  80. package/src/internal/core/types.ts +554 -0
  81. package/src/internal/feature/auth.ts +201 -0
  82. package/src/internal/feature/interceptors.ts +36 -0
  83. package/src/internal/feature/logger.ts +222 -0
  84. package/src/internal/feature/retry.ts +168 -0
  85. package/src/internal/feature/rules.ts +54 -0
  86. package/src/internal/feature/timeout.ts +146 -0
  87. package/src/internal/feature/validate.ts +82 -0
  88. package/src/internal/transport/fetch.ts +82 -0
  89. package/src/resources/analytics.ts +364 -0
  90. package/src/resources/brands.ts +288 -0
  91. package/src/resources/competitors.ts +213 -0
  92. package/src/resources/identity.ts +49 -0
  93. package/src/resources/models.ts +32 -0
  94. package/src/resources/opportunities.ts +81 -0
  95. package/src/resources/organizations.ts +182 -0
  96. package/src/resources/prompts.ts +293 -0
  97. package/src/resources/reports.ts +212 -0
  98. package/src/resources/runs.ts +124 -0
  99. package/src/resources/shared/auth.ts +13 -0
  100. package/src/resources/shared/request-options.ts +26 -0
  101. package/src/resources/shared/resource.ts +23 -0
  102. package/src/resources/shared/rule.ts +25 -0
  103. package/src/resources/snapshots.ts +54 -0
  104. package/src/resources/tags.ts +46 -0
  105. package/src/resources/tools.ts +69 -0
  106. package/src/types/analytics.ts +497 -0
  107. package/src/types/brands.ts +228 -0
  108. package/src/types/competitors.ts +196 -0
  109. package/src/types/identity.ts +55 -0
  110. package/src/types/index.ts +163 -0
  111. package/src/types/models.ts +40 -0
  112. package/src/types/opportunities.ts +84 -0
  113. package/src/types/organizations.ts +157 -0
  114. package/src/types/prompts.ts +231 -0
  115. package/src/types/reports.ts +266 -0
  116. package/src/types/runs.ts +131 -0
  117. package/src/types/shared/brand-id-path.ts +2 -0
  118. package/src/types/shared/conflict-error.ts +7 -0
  119. package/src/types/shared/error.ts +29 -0
  120. package/src/types/shared/limit.ts +8 -0
  121. package/src/types/shared/mention-entry.ts +21 -0
  122. package/src/types/shared/model-filter.ts +15 -0
  123. package/src/types/shared/not-found-error.ts +4 -0
  124. package/src/types/shared/page.ts +7 -0
  125. package/src/types/shared/pagination.ts +7 -0
  126. package/src/types/shared/validation-error.ts +4 -0
  127. package/src/types/snapshots.ts +88 -0
  128. package/src/types/tags.ts +47 -0
  129. package/src/types/tools.ts +78 -0
@@ -0,0 +1,196 @@
1
+ import type { ConflictError, PaymentRequiredError } from './shared/conflict-error';
2
+ import type {
3
+ ForbiddenError,
4
+ InternalServerError,
5
+ RateLimitError,
6
+ UnauthorizedError,
7
+ } from './shared/error';
8
+ import type { Limit } from './shared/limit';
9
+ import type { NotFoundError } from './shared/not-found-error';
10
+ import type { Page } from './shared/page';
11
+ import type { Pagination } from './shared/pagination';
12
+ import type { ValidationError } from './shared/validation-error';
13
+
14
+ export type Competitor = {
15
+ aliases: Array<string>;
16
+ brandId: string;
17
+ createdAt: Date;
18
+ domains: Array<string>;
19
+ id: string;
20
+ name: string;
21
+ updatedAt: Date;
22
+ };
23
+
24
+ export type CompetitorsList = {
25
+ /**
26
+ * Deprecated: read `data` instead. Kept while the one known consumer migrates, and removed in a
27
+ * future release.
28
+ *
29
+ * @deprecated
30
+ */
31
+ competitors: Array<Competitor>;
32
+ /** The items on this page. Read this rather than the named key below. */
33
+ data: Array<Competitor>;
34
+ pagination: Pagination;
35
+ };
36
+
37
+ export type ListCompetitorsErrors = {
38
+ /** Authentication required */
39
+ 401: UnauthorizedError;
40
+ /**
41
+ * The key is valid but not permitted: a missing scope, an admin-only endpoint, or a write in
42
+ * read-only (demo) mode.
43
+ */
44
+ 403: ForbiddenError;
45
+ /** Per-key rate limit exceeded. */
46
+ 429: RateLimitError;
47
+ /** Internal server error */
48
+ 500: InternalServerError;
49
+ };
50
+
51
+ export type ListCompetitorsResponses = {
52
+ /** Paginated list of competitors */
53
+ 200: CompetitorsList;
54
+ };
55
+
56
+ export type CreateCompetitorErrors = {
57
+ /** Invalid request data */
58
+ 400: ValidationError;
59
+ /** Authentication required */
60
+ 401: UnauthorizedError;
61
+ /** The organization has no active subscription. Cloud deployments only. */
62
+ 402: PaymentRequiredError;
63
+ /**
64
+ * The key is valid but not permitted: a missing scope, an admin-only endpoint, or a write in
65
+ * read-only (demo) mode.
66
+ */
67
+ 403: ForbiddenError;
68
+ /** Resource already exists */
69
+ 409: ConflictError;
70
+ /** Per-key rate limit exceeded. */
71
+ 429: RateLimitError;
72
+ /** Internal server error */
73
+ 500: InternalServerError;
74
+ };
75
+
76
+ export type CreateCompetitorResponses = {
77
+ /** Competitor created */
78
+ 201: Competitor;
79
+ };
80
+
81
+ export type DeleteCompetitorErrors = {
82
+ /** Invalid request data */
83
+ 400: ValidationError;
84
+ /** Authentication required */
85
+ 401: UnauthorizedError;
86
+ /** The organization has no active subscription. Cloud deployments only. */
87
+ 402: PaymentRequiredError;
88
+ /**
89
+ * The key is valid but not permitted: a missing scope, an admin-only endpoint, or a write in
90
+ * read-only (demo) mode.
91
+ */
92
+ 403: ForbiddenError;
93
+ /** Resource not found */
94
+ 404: NotFoundError;
95
+ /** Resource already exists */
96
+ 409: ConflictError;
97
+ /** Per-key rate limit exceeded. */
98
+ 429: RateLimitError;
99
+ /** Internal server error */
100
+ 500: InternalServerError;
101
+ };
102
+
103
+ export type DeleteCompetitorResponses = {
104
+ /** Competitor deleted (returns the deleted competitor) */
105
+ 200: Competitor;
106
+ };
107
+
108
+ export type GetCompetitorErrors = {
109
+ /** Invalid request data */
110
+ 400: ValidationError;
111
+ /** Authentication required */
112
+ 401: UnauthorizedError;
113
+ /**
114
+ * The key is valid but not permitted: a missing scope, an admin-only endpoint, or a write in
115
+ * read-only (demo) mode.
116
+ */
117
+ 403: ForbiddenError;
118
+ /** Resource not found */
119
+ 404: NotFoundError;
120
+ /** Per-key rate limit exceeded. */
121
+ 429: RateLimitError;
122
+ /** Internal server error */
123
+ 500: InternalServerError;
124
+ };
125
+
126
+ export type GetCompetitorResponses = {
127
+ /** Competitor */
128
+ 200: Competitor;
129
+ };
130
+
131
+ export type UpdateCompetitorErrors = {
132
+ /** Invalid request data */
133
+ 400: ValidationError;
134
+ /** Authentication required */
135
+ 401: UnauthorizedError;
136
+ /** The organization has no active subscription. Cloud deployments only. */
137
+ 402: PaymentRequiredError;
138
+ /**
139
+ * The key is valid but not permitted: a missing scope, an admin-only endpoint, or a write in
140
+ * read-only (demo) mode.
141
+ */
142
+ 403: ForbiddenError;
143
+ /** Resource not found */
144
+ 404: NotFoundError;
145
+ /** Resource already exists */
146
+ 409: ConflictError;
147
+ /** Per-key rate limit exceeded. */
148
+ 429: RateLimitError;
149
+ /** Internal server error */
150
+ 500: InternalServerError;
151
+ };
152
+
153
+ export type UpdateCompetitorResponses = {
154
+ /** Competitor updated */
155
+ 200: Competitor;
156
+ };
157
+
158
+ export type ListCompetitorsParams = {
159
+ brandId?: string;
160
+ /**
161
+ * Page number, 1-based.
162
+ *
163
+ * @default 1
164
+ * @minimum 1
165
+ */
166
+ page?: Page;
167
+ /**
168
+ * Items per page. Values above the maximum are clamped, not rejected.
169
+ *
170
+ * @default 20
171
+ * @minimum 1
172
+ * @maximum 100
173
+ */
174
+ limit?: Limit;
175
+ };
176
+
177
+ /** Add a competitor to a brand. */
178
+ export type CreateCompetitorParams = {
179
+ /** @minLength 1 */
180
+ brandId: string;
181
+ /** @minLength 1 */
182
+ name: string;
183
+ domains?: Array<string>;
184
+ aliases?: Array<string>;
185
+ };
186
+
187
+ /**
188
+ * Update a competitor. At least one field must be provided. Provided arrays replace the stored
189
+ * values verbatim.
190
+ */
191
+ export type UpdateCompetitorParams = {
192
+ /** @minLength 1 */
193
+ name?: string;
194
+ domains?: Array<string>;
195
+ aliases?: Array<string>;
196
+ };
@@ -0,0 +1,55 @@
1
+ import type {
2
+ ForbiddenError,
3
+ InternalServerError,
4
+ RateLimitError,
5
+ UnauthorizedError,
6
+ } from './shared/error';
7
+
8
+ export type APIKeyIdentity = {
9
+ /**
10
+ * Brands the key is narrowed to, or null when it reaches every brand in its organization. Never
11
+ * an empty array — a restriction to no brands is rejected at creation rather than treated as no
12
+ * restriction.
13
+ */
14
+ brandIds: Array<string> | null;
15
+ createdAt: Date | null;
16
+ /** The key's label, as given when it was issued. Null for admin keys. */
17
+ createdBy: string | null;
18
+ /** When the key stops working, if it has an expiry. */
19
+ expiresAt: Date | null;
20
+ /** `admin` for an instance key, `organization` for a dashboard-issued key. */
21
+ keyType: 'admin' | 'organization';
22
+ lastUsedAt: Date | null;
23
+ /** The organization this key acts inside. Null for admin keys. */
24
+ organizationId: string | null;
25
+ organizationName: string | null;
26
+ /**
27
+ * The key's configured limit — generous by design: it exists to stop a runaway loop, not to meter
28
+ * normal use. Enforcement is a fixed window and approximate under concurrency.
29
+ */
30
+ rateLimit: {
31
+ limit: number;
32
+ window: 'minute' | 'hour';
33
+ } | null;
34
+ /** Scopes this key holds. A read-write key lists both; an admin key always does. */
35
+ scopes: Array<'read' | 'write'>;
36
+ };
37
+
38
+ export type GetMeErrors = {
39
+ /** Authentication required */
40
+ 401: UnauthorizedError;
41
+ /**
42
+ * The key is valid but not permitted: a missing scope, an admin-only endpoint, or a write in
43
+ * read-only (demo) mode.
44
+ */
45
+ 403: ForbiddenError;
46
+ /** Per-key rate limit exceeded. */
47
+ 429: RateLimitError;
48
+ /** Internal server error */
49
+ 500: InternalServerError;
50
+ };
51
+
52
+ export type GetMeResponses = {
53
+ /** Describe the calling key */
54
+ 200: APIKeyIdentity;
55
+ };
@@ -0,0 +1,163 @@
1
+ export type {
2
+ BrandAnalytics,
3
+ BrandQueryFanout,
4
+ CitationDomain,
5
+ CitationDomainList,
6
+ CitationURL,
7
+ CitationURLList,
8
+ DateRange,
9
+ FanoutQuery,
10
+ GetBrandAnalyticsErrors,
11
+ GetBrandAnalyticsParams,
12
+ GetBrandAnalyticsResponses,
13
+ GetBrandQueryFanoutErrors,
14
+ GetBrandQueryFanoutParams,
15
+ GetBrandQueryFanoutResponses,
16
+ ListBrandCitationDomainsErrors,
17
+ ListBrandCitationDomainsParams,
18
+ ListBrandCitationDomainsResponses,
19
+ ListBrandCitationURLsErrors,
20
+ ListBrandCitationURLsParams,
21
+ ListBrandCitationURLsResponses,
22
+ ListBrandPromptPerformanceErrors,
23
+ ListBrandPromptPerformanceParams,
24
+ ListBrandPromptPerformanceResponses,
25
+ ModelVisibility,
26
+ PromptPerformance,
27
+ PromptPerformanceList,
28
+ ShareOfVoiceEntry,
29
+ ShareOfVoicePoint,
30
+ TagsFilter,
31
+ VisibilityPoint,
32
+ } from './analytics';
33
+ export type {
34
+ Brand,
35
+ BrandsList,
36
+ CreateBrandErrors,
37
+ CreateBrandParams,
38
+ CreateBrandResponses,
39
+ GetBrandErrors,
40
+ GetBrandResponses,
41
+ ListBrandsErrors,
42
+ ListBrandsParams,
43
+ ListBrandsResponses,
44
+ UpdateBrandErrors,
45
+ UpdateBrandParams,
46
+ UpdateBrandResponses,
47
+ } from './brands';
48
+ export type {
49
+ Competitor,
50
+ CompetitorsList,
51
+ CreateCompetitorErrors,
52
+ CreateCompetitorParams,
53
+ CreateCompetitorResponses,
54
+ DeleteCompetitorErrors,
55
+ DeleteCompetitorResponses,
56
+ GetCompetitorErrors,
57
+ GetCompetitorResponses,
58
+ ListCompetitorsErrors,
59
+ ListCompetitorsParams,
60
+ ListCompetitorsResponses,
61
+ UpdateCompetitorErrors,
62
+ UpdateCompetitorParams,
63
+ UpdateCompetitorResponses,
64
+ } from './competitors';
65
+ export type { APIKeyIdentity, GetMeErrors, GetMeResponses } from './identity';
66
+ export type { ListModelsErrors, ListModelsResponses, Model, ModelList } from './models';
67
+ export type {
68
+ BrandOpportunities,
69
+ CitedPage,
70
+ GetBrandOpportunitiesErrors,
71
+ GetBrandOpportunitiesResponses,
72
+ Opportunity,
73
+ OpportunityPrompt,
74
+ } from './opportunities';
75
+ export type {
76
+ BillingPlan,
77
+ GetOrganizationBillingErrors,
78
+ GetOrganizationBillingResponses,
79
+ GetOrganizationErrors,
80
+ GetOrganizationResponses,
81
+ ListOrganizationsErrors,
82
+ ListOrganizationsParams,
83
+ ListOrganizationsResponses,
84
+ Organization,
85
+ OrganizationBilling,
86
+ OrganizationList,
87
+ PlanLimits,
88
+ } from './organizations';
89
+ export type {
90
+ CreatePromptErrors,
91
+ CreatePromptParams,
92
+ CreatePromptResponses,
93
+ DeletePromptErrors,
94
+ DeletePromptResponse,
95
+ DeletePromptResponses,
96
+ GetPromptErrors,
97
+ GetPromptResponses,
98
+ ListPromptsErrors,
99
+ ListPromptsParams,
100
+ ListPromptsResponse,
101
+ ListPromptsResponses,
102
+ Prompt,
103
+ UpdatePromptErrors,
104
+ UpdatePromptParams,
105
+ UpdatePromptResponses,
106
+ } from './prompts';
107
+ export type {
108
+ CreateReportErrors,
109
+ CreateReportParams,
110
+ CreateReportResponse,
111
+ CreateReportResponses,
112
+ GetReportErrors,
113
+ GetReportParams,
114
+ GetReportResponse,
115
+ GetReportResponses,
116
+ ListReportsErrors,
117
+ ListReportsParams,
118
+ ListReportsResponse,
119
+ ListReportsResponses,
120
+ ReportPromptSnapshot,
121
+ ReportSummary,
122
+ } from './reports';
123
+ export type {
124
+ GetRunErrors,
125
+ GetRunResponses,
126
+ ListPromptRunsErrors,
127
+ ListPromptRunsParams,
128
+ ListPromptRunsResponses,
129
+ Run,
130
+ RunCitation,
131
+ RunList,
132
+ RunSummary,
133
+ } from './runs';
134
+ export type { BrandIdPath } from './shared/brand-id-path';
135
+ export type { ConflictError, PaymentRequiredError } from './shared/conflict-error';
136
+ export type {
137
+ Error,
138
+ ForbiddenError,
139
+ InternalServerError,
140
+ RateLimitError,
141
+ UnauthorizedError,
142
+ } from './shared/error';
143
+ export type { Limit } from './shared/limit';
144
+ export type { MentionEntry, MentionsSummary } from './shared/mention-entry';
145
+ export type { ModelFilter, WindowEnd, WindowStart } from './shared/model-filter';
146
+ export type { NotFoundError } from './shared/not-found-error';
147
+ export type { Page } from './shared/page';
148
+ export type { Pagination } from './shared/pagination';
149
+ export type { ValidationError } from './shared/validation-error';
150
+ export type {
151
+ CitedURLEntry,
152
+ GetPromptSnapshotErrors,
153
+ GetPromptSnapshotParams,
154
+ GetPromptSnapshotResponses,
155
+ PromptSnapshot,
156
+ } from './snapshots';
157
+ export type { ListBrandTagsErrors, ListBrandTagsResponses, Tag, TagList } from './tags';
158
+ export type {
159
+ AnalyzeBrandErrors,
160
+ AnalyzeBrandParams,
161
+ AnalyzeBrandResponses,
162
+ OnboardingSuggestion,
163
+ } from './tools';
@@ -0,0 +1,40 @@
1
+ import type {
2
+ ForbiddenError,
3
+ InternalServerError,
4
+ RateLimitError,
5
+ UnauthorizedError,
6
+ } from './shared/error';
7
+
8
+ export type ModelList = {
9
+ data: Array<Model>;
10
+ };
11
+
12
+ export type Model = {
13
+ /** Whether this deployment is actually wired to reach it. */
14
+ configured: boolean;
15
+ /** Identifier used by the `model` filter, e.g. `chatgpt`. */
16
+ id: string;
17
+ /** Human-readable name. */
18
+ label: string;
19
+ /** Whether this model can be tracked grounded, spending a premium pairing. */
20
+ premiumCapable: boolean;
21
+ };
22
+
23
+ export type ListModelsErrors = {
24
+ /** Authentication required */
25
+ 401: UnauthorizedError;
26
+ /**
27
+ * The key is valid but not permitted: a missing scope, an admin-only endpoint, or a write in
28
+ * read-only (demo) mode.
29
+ */
30
+ 403: ForbiddenError;
31
+ /** Per-key rate limit exceeded. */
32
+ 429: RateLimitError;
33
+ /** Internal server error */
34
+ 500: InternalServerError;
35
+ };
36
+
37
+ export type ListModelsResponses = {
38
+ /** List trackable models */
39
+ 200: ModelList;
40
+ };
@@ -0,0 +1,84 @@
1
+ import type {
2
+ ForbiddenError,
3
+ InternalServerError,
4
+ RateLimitError,
5
+ UnauthorizedError,
6
+ } from './shared/error';
7
+ import type { NotFoundError } from './shared/not-found-error';
8
+
9
+ export type OpportunityPrompt = {
10
+ /** The tracked prompt it resolved to, or null when it didn't match one. */
11
+ promptId: string | null;
12
+ /** The prompt as the report names it. */
13
+ text: string;
14
+ };
15
+
16
+ export type CitedPage = {
17
+ domain: string;
18
+ title: string | null;
19
+ url: string;
20
+ };
21
+
22
+ export type Opportunity = {
23
+ /**
24
+ * Which workstream this belongs to: `creation` is net-new content, `existing-content` is a page
25
+ * that could win the mention with a refresh, `outreach` is earning a placement on a third-party
26
+ * site assistants cite, `social` is the community conversations they pull from.
27
+ */
28
+ category: 'creation' | 'existing-content' | 'outreach' | 'social';
29
+ /** Pages on competitor domains cited for those prompts. */
30
+ competitorCitations: Array<CitedPage>;
31
+ /** Tracked prompts this would help. May be empty. */
32
+ relatedPrompts: Array<OpportunityPrompt>;
33
+ /** Short and action-oriented — the concrete surface or angle. */
34
+ title: string;
35
+ /** Why it is worth doing, in plain language. */
36
+ why: string;
37
+ /** Pages on the brand's own domains already cited for those prompts. */
38
+ yourCitations: Array<CitedPage>;
39
+ };
40
+
41
+ /**
42
+ * The brand's latest Opportunities report — the same LLM-generated analysis the dashboard shows,
43
+ * read from the append-only history rather than regenerated. Elmo decides when to produce a new
44
+ * one; there is no way to trigger generation over the API, because it spends provider budget with
45
+ * no per-call metering behind it.
46
+ */
47
+ export type BrandOpportunities = {
48
+ brandId: string;
49
+ generatedAt: Date | null;
50
+ /** The model that produced the report, when recorded. */
51
+ model: string | null;
52
+ /** Prioritized, highest impact first. */
53
+ opportunities: Array<Opportunity>;
54
+ /** Caveats: hard-to-win areas, or tactics to avoid. */
55
+ risks: Array<string>;
56
+ /**
57
+ * `ready` when a report is present. `insufficient-data` when the brand hasn't accumulated enough
58
+ * tracked answers to say anything useful yet, in which case the lists are empty.
59
+ */
60
+ status: 'ready' | 'insufficient-data';
61
+ /** A few bullets on where the brand stands and the through-line of the plan. */
62
+ summary: Array<string>;
63
+ };
64
+
65
+ export type GetBrandOpportunitiesErrors = {
66
+ /** Authentication required */
67
+ 401: UnauthorizedError;
68
+ /**
69
+ * The key is valid but not permitted: a missing scope, an admin-only endpoint, or a write in
70
+ * read-only (demo) mode.
71
+ */
72
+ 403: ForbiddenError;
73
+ /** Resource not found */
74
+ 404: NotFoundError;
75
+ /** Per-key rate limit exceeded. */
76
+ 429: RateLimitError;
77
+ /** Internal server error */
78
+ 500: InternalServerError;
79
+ };
80
+
81
+ export type GetBrandOpportunitiesResponses = {
82
+ /** Get the latest opportunities report */
83
+ 200: BrandOpportunities;
84
+ };
@@ -0,0 +1,157 @@
1
+ import type {
2
+ ForbiddenError,
3
+ InternalServerError,
4
+ RateLimitError,
5
+ UnauthorizedError,
6
+ } from './shared/error';
7
+ import type { Limit } from './shared/limit';
8
+ import type { NotFoundError } from './shared/not-found-error';
9
+ import type { Page } from './shared/page';
10
+ import type { Pagination } from './shared/pagination';
11
+
12
+ export type Organization = {
13
+ brandCount: number;
14
+ createdAt: Date;
15
+ id: string;
16
+ name: string;
17
+ slug: string;
18
+ };
19
+
20
+ /** The organization's plan limits. Every field is null on deployments without billing. */
21
+ export type PlanLimits = {
22
+ /** Null means no limit. */
23
+ maxBrands: number | null;
24
+ /** Enabled prompts across the whole organization. Null means no limit. */
25
+ maxPrompts: number | null;
26
+ /** Models the plan may pick from. Null means any. */
27
+ modelMenu: Array<string> | null;
28
+ /** Models trackable per brand. */
29
+ modelPicks: number | null;
30
+ /** Prompt/model pairings trackable grounded. */
31
+ premiumPool: number;
32
+ premiumRunsPerDay: number;
33
+ standardRunsPerDay: number | null;
34
+ };
35
+
36
+ /**
37
+ * Read-only view of an organization's subscription, limits, and usage. The API has no way to change
38
+ * any of it: there is no billing write endpoint and no billing write scope. Stripe identifiers,
39
+ * payment methods, and invoices are deliberately not exposed — those live in the Stripe customer
40
+ * portal.
41
+ */
42
+ export type OrganizationBilling = {
43
+ /** False on self-hosted deployments, where nothing is metered. */
44
+ billingEnabled: boolean;
45
+ limits: PlanLimits | null;
46
+ organizationId: string;
47
+ /** Null when the organization has no subscription, or when billing is disabled. */
48
+ plan: BillingPlan | null;
49
+ usage: {
50
+ brands: number;
51
+ enabledPrompts: number;
52
+ premiumPairingsAssigned: number;
53
+ };
54
+ };
55
+
56
+ export type BillingPlan = {
57
+ cancelAtPeriodEnd: boolean;
58
+ /** Null on a negotiated plan, which carries no billing interval. */
59
+ interval?: 'monthly' | 'annual' | null;
60
+ /** Plan identifier, or `custom` for a negotiated plan. */
61
+ key: string | null;
62
+ /** Display name. */
63
+ name: string;
64
+ periodEnd?: Date | null;
65
+ /**
66
+ * What the subscription means for service, and the only field a caller needs to act on: `active`
67
+ * and `grace` keep tracking running, `paused` stops it, `none` is unsubscribed. The payment
68
+ * provider's own status string is deliberately not passed through.
69
+ */
70
+ standing: 'active' | 'grace' | 'paused' | 'none';
71
+ /** Whether prompts are currently being sampled. */
72
+ trackingActive: boolean;
73
+ };
74
+
75
+ export type OrganizationList = {
76
+ data: Array<Organization>;
77
+ pagination: Pagination;
78
+ };
79
+
80
+ export type ListOrganizationsErrors = {
81
+ /** Authentication required */
82
+ 401: UnauthorizedError;
83
+ /**
84
+ * The key is valid but not permitted: a missing scope, an admin-only endpoint, or a write in
85
+ * read-only (demo) mode.
86
+ */
87
+ 403: ForbiddenError;
88
+ /** Per-key rate limit exceeded. */
89
+ 429: RateLimitError;
90
+ /** Internal server error */
91
+ 500: InternalServerError;
92
+ };
93
+
94
+ export type ListOrganizationsResponses = {
95
+ /** List organizations */
96
+ 200: OrganizationList;
97
+ };
98
+
99
+ export type GetOrganizationErrors = {
100
+ /** Authentication required */
101
+ 401: UnauthorizedError;
102
+ /**
103
+ * The key is valid but not permitted: a missing scope, an admin-only endpoint, or a write in
104
+ * read-only (demo) mode.
105
+ */
106
+ 403: ForbiddenError;
107
+ /** Resource not found */
108
+ 404: NotFoundError;
109
+ /** Per-key rate limit exceeded. */
110
+ 429: RateLimitError;
111
+ /** Internal server error */
112
+ 500: InternalServerError;
113
+ };
114
+
115
+ export type GetOrganizationResponses = {
116
+ /** Get an organization */
117
+ 200: Organization;
118
+ };
119
+
120
+ export type GetOrganizationBillingErrors = {
121
+ /** Authentication required */
122
+ 401: UnauthorizedError;
123
+ /**
124
+ * The key is valid but not permitted: a missing scope, an admin-only endpoint, or a write in
125
+ * read-only (demo) mode.
126
+ */
127
+ 403: ForbiddenError;
128
+ /** Resource not found */
129
+ 404: NotFoundError;
130
+ /** Per-key rate limit exceeded. */
131
+ 429: RateLimitError;
132
+ /** Internal server error */
133
+ 500: InternalServerError;
134
+ };
135
+
136
+ export type GetOrganizationBillingResponses = {
137
+ /** Get billing state */
138
+ 200: OrganizationBilling;
139
+ };
140
+
141
+ export type ListOrganizationsParams = {
142
+ /**
143
+ * Page number, 1-based.
144
+ *
145
+ * @default 1
146
+ * @minimum 1
147
+ */
148
+ page?: Page;
149
+ /**
150
+ * Items per page. Values above the maximum are clamped, not rejected.
151
+ *
152
+ * @default 20
153
+ * @minimum 1
154
+ * @maximum 100
155
+ */
156
+ limit?: Limit;
157
+ };