coss 0.3.0 → 0.5.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/README.md +63 -10
- package/dist/authjs.d.ts +64 -0
- package/dist/authjs.js +97 -0
- package/dist/better-auth.d.ts +128 -0
- package/dist/better-auth.js +269 -0
- package/dist/client-CCVBtkpV.js +2364 -0
- package/dist/client-avnHVMry.d.ts +3850 -0
- package/dist/device.js +1 -1
- package/dist/index.d.ts +4 -3101
- package/dist/index.js +2 -1956
- package/dist/integration-p3vtLNgq.d.ts +35 -0
- package/dist/mime-C8bhhjvD.js +152 -0
- package/dist/nodemailer.d.ts +75 -0
- package/dist/nodemailer.js +193 -0
- package/package.json +32 -2
|
@@ -0,0 +1,3850 @@
|
|
|
1
|
+
//#region src/api-version.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* API versions this SDK knows, oldest first: a hand-written mirror of `API_VERSIONS` in the API
|
|
4
|
+
* (`apps/api/test/sdk-contract.test.ts` keeps them equal).
|
|
5
|
+
*/
|
|
6
|
+
declare const API_VERSIONS: readonly ["2026-10-10"];
|
|
7
|
+
/** A dated API version, sent as the `Coss-Version` header. */
|
|
8
|
+
type ApiVersion = (typeof API_VERSIONS)[number];
|
|
9
|
+
/** The version this SDK's types describe, sent with every request unless `apiVersion` overrides it. */
|
|
10
|
+
declare const API_VERSION: ApiVersion;
|
|
11
|
+
//#endregion
|
|
12
|
+
//#region src/core/errors.d.ts
|
|
13
|
+
/** Error types returned by the API, plus the client-side `connection_error` and `timeout_error`. */
|
|
14
|
+
type CossErrorType = "invalid_request_error" | "authentication_error" | "permission_error" | "not_found_error" | "idempotency_error" | "rate_limit_error" | "billing_error" | "api_error" | "connection_error" | "timeout_error";
|
|
15
|
+
/** One field-level validation problem (`invalid_request_error` / `validation_error`). */
|
|
16
|
+
interface CossErrorIssue {
|
|
17
|
+
path: string;
|
|
18
|
+
message: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* A failed request. API errors mirror the API's `{ "error": { … } }` envelope; failures that never
|
|
22
|
+
* produced a response (network, timeout, abort) have `status: null`.
|
|
23
|
+
*/
|
|
24
|
+
interface CossError {
|
|
25
|
+
type: CossErrorType;
|
|
26
|
+
/** Machine-readable reason, e.g. `invalid_api_key`, `validation_error`, `aborted`. */
|
|
27
|
+
code: string;
|
|
28
|
+
message: string;
|
|
29
|
+
/** HTTP status, or `null` when no response was received. */
|
|
30
|
+
status: number | null;
|
|
31
|
+
/** The API's `X-Request-Id`. Include it when contacting support. */
|
|
32
|
+
request_id: string | null;
|
|
33
|
+
/** The request parameter the error relates to, when there is one. */
|
|
34
|
+
param?: string;
|
|
35
|
+
issues?: CossErrorIssue[];
|
|
36
|
+
}
|
|
37
|
+
type CossResult<T> = {
|
|
38
|
+
data: T;
|
|
39
|
+
error: null;
|
|
40
|
+
} | {
|
|
41
|
+
data: null;
|
|
42
|
+
error: CossError;
|
|
43
|
+
};
|
|
44
|
+
//#endregion
|
|
45
|
+
//#region src/core/http.d.ts
|
|
46
|
+
/** Any WHATWG-compatible `fetch` (global fetch, undici, a test double, `app.fetch` adapters …). */
|
|
47
|
+
type FetchLike = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
|
|
48
|
+
/** Per-request options accepted by every resource method. */
|
|
49
|
+
interface RequestOptions {
|
|
50
|
+
/**
|
|
51
|
+
* Sent as `Idempotency-Key` on POST requests. When omitted a random UUID is generated; either way
|
|
52
|
+
* the same key is reused for every retry of the call, so a retried send is never duplicated.
|
|
53
|
+
*/
|
|
54
|
+
idempotencyKey?: string;
|
|
55
|
+
/** Aborting cancels the in-flight attempt and any pending retry. */
|
|
56
|
+
signal?: AbortSignal;
|
|
57
|
+
}
|
|
58
|
+
interface HttpClientOptions {
|
|
59
|
+
apiKey: string;
|
|
60
|
+
baseUrl: string;
|
|
61
|
+
fetch: FetchLike;
|
|
62
|
+
/** Per-attempt timeout in milliseconds. */
|
|
63
|
+
timeout: number;
|
|
64
|
+
maxRetries: number;
|
|
65
|
+
/** Sent as `Coss-Version` with every request. */
|
|
66
|
+
apiVersion: string;
|
|
67
|
+
/** Appended to the `User-Agent`, e.g. `nodemailer` for `coss/nodemailer`. */
|
|
68
|
+
integration?: string;
|
|
69
|
+
/** Waits between retries; must resolve early when `signal` aborts. Overridable for tests. */
|
|
70
|
+
sleep?: (ms: number, signal?: AbortSignal) => Promise<void>;
|
|
71
|
+
}
|
|
72
|
+
interface ApiRequest {
|
|
73
|
+
/** Disable automatic retries for operations without server-side deduplication. */
|
|
74
|
+
retry?: boolean;
|
|
75
|
+
method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
76
|
+
/** Path including the version prefix, e.g. `/v1/emails`. */
|
|
77
|
+
path: string;
|
|
78
|
+
/** Query parameters; `undefined` values are left out. */
|
|
79
|
+
query?: Record<string, string | number | undefined>;
|
|
80
|
+
/** Serialized as JSON. */
|
|
81
|
+
body?: unknown;
|
|
82
|
+
/**
|
|
83
|
+
* `text` returns the raw body of a successful response (e.g. CSV) instead of parsing JSON;
|
|
84
|
+
* `bytes` returns it as a `Uint8Array` (a received email's raw message, an attachment).
|
|
85
|
+
*/
|
|
86
|
+
responseType?: "json" | "text" | "bytes";
|
|
87
|
+
idempotencyKey?: string;
|
|
88
|
+
signal?: AbortSignal;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* The request pipeline shared by all resources: auth + JSON, a per-attempt timeout, retries with
|
|
92
|
+
* backoff, and mapping every failure to a `CossError`. It never throws for API or network errors.
|
|
93
|
+
*/
|
|
94
|
+
declare class HttpClient {
|
|
95
|
+
#private;
|
|
96
|
+
constructor(options: HttpClientOptions);
|
|
97
|
+
request<T>(request: ApiRequest): Promise<CossResult<T>>;
|
|
98
|
+
}
|
|
99
|
+
//#endregion
|
|
100
|
+
//#region src/types/environment.d.ts
|
|
101
|
+
/** Environment wire types (hand-written mirrors of the API's `Environment` schema). */
|
|
102
|
+
/** A project or organization, as named in the dashboard. */
|
|
103
|
+
interface NamedResource {
|
|
104
|
+
id: string;
|
|
105
|
+
name: string;
|
|
106
|
+
/** As in dashboard URLs. */
|
|
107
|
+
slug: string;
|
|
108
|
+
}
|
|
109
|
+
/** `GET /v1/environment`: the environment the API key belongs to. */
|
|
110
|
+
interface Environment {
|
|
111
|
+
object: "environment";
|
|
112
|
+
id: string;
|
|
113
|
+
name: string;
|
|
114
|
+
slug: string;
|
|
115
|
+
/** `live` delivers email; `sandbox` (`coss_test_` keys) never does. */
|
|
116
|
+
mode: "live" | "sandbox";
|
|
117
|
+
project: NamedResource;
|
|
118
|
+
organization: NamedResource & {
|
|
119
|
+
/** The organization's pinned API version (for requests without `Coss-Version`). */
|
|
120
|
+
api_version: string;
|
|
121
|
+
};
|
|
122
|
+
/** The API key making the request. */
|
|
123
|
+
api_key: {
|
|
124
|
+
id: string;
|
|
125
|
+
name: string | null;
|
|
126
|
+
/** The key's first characters, as shown in the dashboard. */
|
|
127
|
+
start: string | null;
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
/** `DELETE /v1/api_key`: the key revoked itself. */
|
|
131
|
+
interface DeletedApiKey {
|
|
132
|
+
object: "api_key";
|
|
133
|
+
id: string;
|
|
134
|
+
deleted: true;
|
|
135
|
+
}
|
|
136
|
+
//#endregion
|
|
137
|
+
//#region src/resources/api-key.d.ts
|
|
138
|
+
type ReadOptions$18 = Pick<RequestOptions, "signal">;
|
|
139
|
+
/** `coss.apiKey`: the API key the client was created with. */
|
|
140
|
+
declare class ApiKeyResource {
|
|
141
|
+
#private;
|
|
142
|
+
/** @internal Use `new Coss().apiKey`. */
|
|
143
|
+
constructor(http: HttpClient);
|
|
144
|
+
/** Revokes the client's own API key, at once: every later request with it fails. */
|
|
145
|
+
revoke(options?: ReadOptions$18): Promise<CossResult<DeletedApiKey>>;
|
|
146
|
+
}
|
|
147
|
+
//#endregion
|
|
148
|
+
//#region src/types/audit-event.d.ts
|
|
149
|
+
/** Audit log wire types (hand-written mirrors of the API's schemas). */
|
|
150
|
+
/**
|
|
151
|
+
* `user`: a member, in the dashboard. `api_key`: a request made with an API key. `system`: coss.com
|
|
152
|
+
* itself, including coss.com support.
|
|
153
|
+
*/
|
|
154
|
+
type AuditActorType = "user" | "api_key" | "system";
|
|
155
|
+
/** One change to the organization. */
|
|
156
|
+
interface AuditEvent {
|
|
157
|
+
object: "audit_event";
|
|
158
|
+
id: string;
|
|
159
|
+
/** ISO 8601 timestamp. */
|
|
160
|
+
created_at: string;
|
|
161
|
+
actor_type: AuditActorType;
|
|
162
|
+
/** The user's or API key's id; `null` for the system. */
|
|
163
|
+
actor_id: string | null;
|
|
164
|
+
/** The user's email, the API key's id, or `coss.com support` (copied when recorded). */
|
|
165
|
+
actor_label: string;
|
|
166
|
+
/** `<resource>.<verb>`, e.g. `api_key.created`, `domain.deleted`, `member.role_changed`. */
|
|
167
|
+
action: string;
|
|
168
|
+
/** What was changed: `domain`, `api_key`, `member`… */
|
|
169
|
+
target_type: string | null;
|
|
170
|
+
target_id: string | null;
|
|
171
|
+
/** A readable name for the target when it was changed. */
|
|
172
|
+
target_label: string | null;
|
|
173
|
+
/** `null` for organization-wide changes (domains, members…). */
|
|
174
|
+
project_id: string | null;
|
|
175
|
+
/** `null` for organization-wide changes (domains, members…). */
|
|
176
|
+
environment_id: string | null;
|
|
177
|
+
/** Details of the change; API changes include their `request_id`. */
|
|
178
|
+
metadata: Record<string, unknown>;
|
|
179
|
+
client_ip: string | null;
|
|
180
|
+
user_agent: string | null;
|
|
181
|
+
}
|
|
182
|
+
type OneOrMany$1<T> = T | readonly T[];
|
|
183
|
+
/** Query of `GET /v1/audit_events`. Lists may be given as arrays or comma-separated strings. */
|
|
184
|
+
interface ListAuditEventsParams {
|
|
185
|
+
/** Actions, e.g. `"api_key.created"`; an entry ending in `.` (`"domain."`) matches a whole resource. */
|
|
186
|
+
action?: OneOrMany$1<string>;
|
|
187
|
+
actor_type?: OneOrMany$1<AuditActorType>;
|
|
188
|
+
/** Only changes made by this user or API key. */
|
|
189
|
+
actor_id?: string;
|
|
190
|
+
/** Only changes to this resource, e.g. a `dom_…` id. */
|
|
191
|
+
target_id?: string;
|
|
192
|
+
/** Only changes in this environment. */
|
|
193
|
+
environment_id?: string;
|
|
194
|
+
/** Only events at or after this time. */
|
|
195
|
+
from?: string | Date;
|
|
196
|
+
/** Only events before this time. */
|
|
197
|
+
to?: string | Date;
|
|
198
|
+
/** 1-100, default 50. */
|
|
199
|
+
limit?: number;
|
|
200
|
+
/** The `id` of the last event of the previous page. */
|
|
201
|
+
after?: string;
|
|
202
|
+
}
|
|
203
|
+
//#endregion
|
|
204
|
+
//#region src/types/email-template.d.ts
|
|
205
|
+
/** Wire types of email templates (`coss.email.templates`). */
|
|
206
|
+
/** A variable's type. `list` is an array of objects with the declared `fields`. */
|
|
207
|
+
type TemplateVariableType = "string" | "number" | "boolean" | "list";
|
|
208
|
+
type TemplateScalarType = "string" | "number" | "boolean";
|
|
209
|
+
/** A declared variable, used in the template as `{{name}}`. */
|
|
210
|
+
interface TemplateVariable {
|
|
211
|
+
name: string;
|
|
212
|
+
type: TemplateVariableType;
|
|
213
|
+
/** Sends must pass it unless it has a `default`. */
|
|
214
|
+
required: boolean;
|
|
215
|
+
/** Used when a send leaves it out. */
|
|
216
|
+
default?: string | number | boolean;
|
|
217
|
+
description?: string;
|
|
218
|
+
/** A list's item fields. */
|
|
219
|
+
fields?: {
|
|
220
|
+
name: string;
|
|
221
|
+
type: TemplateScalarType;
|
|
222
|
+
required: boolean;
|
|
223
|
+
}[];
|
|
224
|
+
}
|
|
225
|
+
/** A variable to declare. `required` defaults to true. */
|
|
226
|
+
interface TemplateVariableParams {
|
|
227
|
+
/** 1-64 letters, digits and underscores, not starting with a digit. */
|
|
228
|
+
name: string;
|
|
229
|
+
type: TemplateVariableType;
|
|
230
|
+
required?: boolean;
|
|
231
|
+
/** Not for lists. */
|
|
232
|
+
default?: string | number | boolean;
|
|
233
|
+
description?: string;
|
|
234
|
+
/** Required for lists, only for lists. */
|
|
235
|
+
fields?: {
|
|
236
|
+
name: string;
|
|
237
|
+
type: TemplateScalarType;
|
|
238
|
+
required?: boolean;
|
|
239
|
+
}[];
|
|
240
|
+
}
|
|
241
|
+
/** One locale's subject, HTML and text templates. */
|
|
242
|
+
interface TemplateContent {
|
|
243
|
+
/** A BCP 47 language tag, e.g. `"en"` or `"pt-BR"`. */
|
|
244
|
+
locale: string;
|
|
245
|
+
subject: string;
|
|
246
|
+
html: string | null;
|
|
247
|
+
text: string | null;
|
|
248
|
+
}
|
|
249
|
+
/** One locale's templates. Provide `html`, `text`, or both. */
|
|
250
|
+
interface TemplateContentParams {
|
|
251
|
+
locale: string;
|
|
252
|
+
subject: string;
|
|
253
|
+
html?: string | null;
|
|
254
|
+
text?: string | null;
|
|
255
|
+
}
|
|
256
|
+
/** A problem that keeps a draft from being published, at a line and column of one field. */
|
|
257
|
+
interface TemplateProblem {
|
|
258
|
+
locale: string;
|
|
259
|
+
field: "subject" | "html" | "text";
|
|
260
|
+
message: string;
|
|
261
|
+
line: number;
|
|
262
|
+
column: number;
|
|
263
|
+
}
|
|
264
|
+
interface EmailTemplate {
|
|
265
|
+
object: "email_template";
|
|
266
|
+
id: string;
|
|
267
|
+
/** Send it by this name in any environment that has a template with the same alias. */
|
|
268
|
+
alias: string | null;
|
|
269
|
+
name: string;
|
|
270
|
+
description: string | null;
|
|
271
|
+
/** The version sends use; `null` until the draft is first published. */
|
|
272
|
+
published_version: number | null;
|
|
273
|
+
/** ISO 8601 timestamp, or `null`. */
|
|
274
|
+
published_at: string | null;
|
|
275
|
+
/** Whether the draft was changed since it was last published. */
|
|
276
|
+
has_unpublished_changes: boolean;
|
|
277
|
+
created_at: string;
|
|
278
|
+
updated_at: string;
|
|
279
|
+
}
|
|
280
|
+
/** A template's draft (`version: null`) or a published version (which never changes). */
|
|
281
|
+
interface EmailTemplateVersion {
|
|
282
|
+
object: "email_template_version";
|
|
283
|
+
template_id: string;
|
|
284
|
+
version: number | null;
|
|
285
|
+
/** Counts the draft's saves; pass it back to refuse overwriting someone else's changes. */
|
|
286
|
+
revision: number;
|
|
287
|
+
/** The locale sends fall back to. */
|
|
288
|
+
default_locale: string;
|
|
289
|
+
variables: TemplateVariable[];
|
|
290
|
+
/** Example values for previews and test sends. */
|
|
291
|
+
sample_variables: Record<string, unknown>;
|
|
292
|
+
contents: TemplateContent[];
|
|
293
|
+
/** Problems of a draft; always empty for published versions. */
|
|
294
|
+
problems: TemplateProblem[];
|
|
295
|
+
published_at: string | null;
|
|
296
|
+
created_at: string;
|
|
297
|
+
updated_at: string;
|
|
298
|
+
}
|
|
299
|
+
interface TemplateDraftParams {
|
|
300
|
+
/** Defaults to the first entry of `contents` (or `"en"`). */
|
|
301
|
+
default_locale?: string;
|
|
302
|
+
variables?: TemplateVariableParams[];
|
|
303
|
+
sample_variables?: Record<string, unknown>;
|
|
304
|
+
contents?: TemplateContentParams[];
|
|
305
|
+
}
|
|
306
|
+
/** Parameters of `coss.email.templates.create`. */
|
|
307
|
+
interface CreateEmailTemplateParams extends TemplateDraftParams {
|
|
308
|
+
name: string;
|
|
309
|
+
/** 1-64 lower-case letters, digits, `-` and `_`, e.g. `"welcome"`. */
|
|
310
|
+
alias?: string;
|
|
311
|
+
description?: string;
|
|
312
|
+
}
|
|
313
|
+
/** Parameters of `coss.email.templates.update`. */
|
|
314
|
+
interface UpdateEmailTemplateParams {
|
|
315
|
+
name?: string;
|
|
316
|
+
/** `null` removes the alias. */
|
|
317
|
+
alias?: string | null;
|
|
318
|
+
description?: string | null;
|
|
319
|
+
}
|
|
320
|
+
/** Parameters of `coss.email.templates.updateDraft`: replaces the whole draft. */
|
|
321
|
+
interface UpdateEmailTemplateDraftParams extends TemplateDraftParams {
|
|
322
|
+
/** The `revision` you read: refused (`template_revision_mismatch`) if the draft changed since. */
|
|
323
|
+
revision?: number;
|
|
324
|
+
}
|
|
325
|
+
/** Parameters of `coss.email.templates.publish`. */
|
|
326
|
+
interface PublishEmailTemplateParams {
|
|
327
|
+
/** The draft `revision` you reviewed: refused if the draft changed since. */
|
|
328
|
+
revision?: number;
|
|
329
|
+
}
|
|
330
|
+
interface ListEmailTemplatesParams {
|
|
331
|
+
/** 1-100, default 50. */
|
|
332
|
+
limit?: number;
|
|
333
|
+
/** Cursor: the `id` of the last template of the previous page. */
|
|
334
|
+
after?: string;
|
|
335
|
+
}
|
|
336
|
+
interface ListEmailTemplateVersionsParams {
|
|
337
|
+
/** 1-20, default 10. */
|
|
338
|
+
limit?: number;
|
|
339
|
+
/** Cursor: the `version` of the last version of the previous page. */
|
|
340
|
+
after?: number;
|
|
341
|
+
}
|
|
342
|
+
interface DeletedEmailTemplate {
|
|
343
|
+
object: "email_template";
|
|
344
|
+
id: string;
|
|
345
|
+
deleted: true;
|
|
346
|
+
}
|
|
347
|
+
/** The template an email was rendered from. */
|
|
348
|
+
interface EmailTemplateReference {
|
|
349
|
+
id: string;
|
|
350
|
+
/** `null` for a dashboard test send of the draft. */
|
|
351
|
+
version: number | null;
|
|
352
|
+
locale: string;
|
|
353
|
+
}
|
|
354
|
+
//#endregion
|
|
355
|
+
//#region src/types/suppression.d.ts
|
|
356
|
+
/** Suppression list wire types (hand-written mirrors of the API's schemas). */
|
|
357
|
+
/**
|
|
358
|
+
* Why an address is suppressed. `bounce`: a permanent bounce. `complaint`: a spam complaint.
|
|
359
|
+
* `manual`: added one by one through the API or the dashboard. `import`: added by a bulk import.
|
|
360
|
+
* `unsubscribe`: the recipient's one-click unsubscribe, scoped to the email's category.
|
|
361
|
+
*/
|
|
362
|
+
type SuppressionReason = "bounce" | "complaint" | "manual" | "import" | "unsubscribe";
|
|
363
|
+
/** An entry of the API key's environment's suppression list. */
|
|
364
|
+
interface Suppression {
|
|
365
|
+
object: "suppression";
|
|
366
|
+
id: string;
|
|
367
|
+
/** The bare, lower-cased address. */
|
|
368
|
+
address: string;
|
|
369
|
+
/** `"*"` (every email) or a category: only emails sent with that `category` skip the address. */
|
|
370
|
+
scope: string;
|
|
371
|
+
reason: SuppressionReason;
|
|
372
|
+
/** The email whose bounce or complaint added this entry. */
|
|
373
|
+
email_id: string | null;
|
|
374
|
+
/** ISO 8601 timestamp. */
|
|
375
|
+
created_at: string;
|
|
376
|
+
}
|
|
377
|
+
/** Body of `POST /v1/suppressions`. */
|
|
378
|
+
interface CreateSuppressionParams {
|
|
379
|
+
/** Display names are ignored; matching is case-insensitive. */
|
|
380
|
+
address: string;
|
|
381
|
+
/** `"*"` (the default) suppresses every email; a category only suppresses those emails. */
|
|
382
|
+
scope?: string;
|
|
383
|
+
}
|
|
384
|
+
/** Query of `GET /v1/suppressions`. */
|
|
385
|
+
interface ListSuppressionsParams {
|
|
386
|
+
address?: string;
|
|
387
|
+
scope?: string;
|
|
388
|
+
/** 1-100, default 50. */
|
|
389
|
+
limit?: number;
|
|
390
|
+
/** The `id` of the last entry of the previous page. */
|
|
391
|
+
after?: string;
|
|
392
|
+
}
|
|
393
|
+
/** Query of `GET /v1/suppressions/check`. */
|
|
394
|
+
interface CheckSuppressionParams {
|
|
395
|
+
address: string;
|
|
396
|
+
/** The category of the email you plan to send. Without it, only `"*"` entries count. */
|
|
397
|
+
category?: string;
|
|
398
|
+
}
|
|
399
|
+
/** Whether a send would skip an address. */
|
|
400
|
+
interface SuppressionCheck {
|
|
401
|
+
object: "suppression_check";
|
|
402
|
+
address: string;
|
|
403
|
+
suppressed: boolean;
|
|
404
|
+
/** The entries that match. */
|
|
405
|
+
suppressions: Suppression[];
|
|
406
|
+
}
|
|
407
|
+
/** Response of `DELETE /v1/suppressions/{id}`. */
|
|
408
|
+
interface DeletedSuppression {
|
|
409
|
+
object: "suppression";
|
|
410
|
+
id: string;
|
|
411
|
+
deleted: true;
|
|
412
|
+
}
|
|
413
|
+
/** One entry of `POST /v1/suppressions/import`. */
|
|
414
|
+
interface ImportSuppressionEntry {
|
|
415
|
+
address: string;
|
|
416
|
+
/** `"*"` (the default) or a category. */
|
|
417
|
+
scope?: string;
|
|
418
|
+
}
|
|
419
|
+
/** Input of `coss.email.suppressions.import()`; the SDK sends 1,000 entries per request. */
|
|
420
|
+
interface ImportSuppressionsParams {
|
|
421
|
+
suppressions: ImportSuppressionEntry[];
|
|
422
|
+
}
|
|
423
|
+
/** What an import did. */
|
|
424
|
+
interface SuppressionImport {
|
|
425
|
+
object: "suppression_import";
|
|
426
|
+
/** Entries added. */
|
|
427
|
+
created: number;
|
|
428
|
+
/** Valid entries that were already on the list (or repeated in the import); unchanged. */
|
|
429
|
+
existing: number;
|
|
430
|
+
/** Skipped entries; `index` is the entry's position in `suppressions`. */
|
|
431
|
+
invalid: Array<{
|
|
432
|
+
index: number;
|
|
433
|
+
address: string;
|
|
434
|
+
message: string;
|
|
435
|
+
}>;
|
|
436
|
+
}
|
|
437
|
+
/** Query of `GET /v1/suppressions/export`. */
|
|
438
|
+
interface ExportSuppressionsParams {
|
|
439
|
+
scope?: string;
|
|
440
|
+
reason?: SuppressionReason;
|
|
441
|
+
}
|
|
442
|
+
//#endregion
|
|
443
|
+
//#region src/types/email.d.ts
|
|
444
|
+
/** A `name`/`value` pair attached to an email for your own filtering and analytics. */
|
|
445
|
+
interface EmailTag {
|
|
446
|
+
name: string;
|
|
447
|
+
value: string;
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* A file to attach (at most 20 per email, 25 MB combined). Executables and other file types the
|
|
451
|
+
* delivery provider refuses (such as `.exe` or `.js`) are rejected.
|
|
452
|
+
*/
|
|
453
|
+
interface EmailAttachmentParams {
|
|
454
|
+
/** The name recipients see. Must include an extension, e.g. `"invoice.pdf"`. */
|
|
455
|
+
filename: string;
|
|
456
|
+
/** The file's bytes, base64-encoded (no line breaks or `data:` prefix). */
|
|
457
|
+
content: string;
|
|
458
|
+
/** Media type such as `"application/pdf"`. Defaults from the filename's extension. */
|
|
459
|
+
content_type?: string;
|
|
460
|
+
/**
|
|
461
|
+
* Makes the attachment inline: reference it from `html` as `<img src="cid:logo@acme">`
|
|
462
|
+
* (without angle brackets here).
|
|
463
|
+
*/
|
|
464
|
+
content_id?: string;
|
|
465
|
+
}
|
|
466
|
+
/** Metadata of a sent attachment. The content itself is never returned. */
|
|
467
|
+
interface EmailAttachment {
|
|
468
|
+
id: string;
|
|
469
|
+
filename: string;
|
|
470
|
+
content_type: string;
|
|
471
|
+
/** Set for inline attachments. */
|
|
472
|
+
content_id: string | null;
|
|
473
|
+
/** Size in bytes. */
|
|
474
|
+
size: number;
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* Whether the email was handed to the delivery provider. `scheduled` emails wait for their
|
|
478
|
+
* `scheduled_at`; `canceled` ones were canceled before that. Delivery is tracked per recipient.
|
|
479
|
+
*/
|
|
480
|
+
type EmailStatus = "queued" | "sent" | "failed" | "scheduled" | "canceled";
|
|
481
|
+
/**
|
|
482
|
+
* Delivery status of one recipient. It only moves forward: `queued` → `sent` →
|
|
483
|
+
* `delivery_delayed` → `delivered`, then `bounced` / `suppressed` / `failed`, then `complained`.
|
|
484
|
+
* `suppressed` means the address is on the environment's suppression list (for every email or for
|
|
485
|
+
* the email's `category`), so it was skipped. `canceled` means the scheduled email was canceled.
|
|
486
|
+
*/
|
|
487
|
+
type EmailRecipientStatus = "queued" | "sent" | "delivery_delayed" | "delivered" | "bounced" | "suppressed" | "complained" | "failed" | "canceled";
|
|
488
|
+
/** One distinct recipient address of an email. */
|
|
489
|
+
interface EmailRecipient {
|
|
490
|
+
/** The bare, lower-cased address. */
|
|
491
|
+
address: string;
|
|
492
|
+
type: "to" | "cc" | "bcc";
|
|
493
|
+
status: EmailRecipientStatus;
|
|
494
|
+
/** ISO 8601 timestamp of the latest event for this recipient, or `null`. */
|
|
495
|
+
last_event_at: string | null;
|
|
496
|
+
}
|
|
497
|
+
type EmailEventType = "email.sent" | "email.delivered" | "email.delivery_delayed" | "email.bounced" | "email.complained" | "email.failed" | "email.suppressed" | "email.scheduled" | "email.canceled" | "email.opened" | "email.clicked" | "email.rescheduled" | "email.unsubscribed";
|
|
498
|
+
/** Details of an event; which member is present depends on the event type. */
|
|
499
|
+
interface EmailEventData {
|
|
500
|
+
bounce?: {
|
|
501
|
+
type: "permanent" | "transient" | "undetermined";
|
|
502
|
+
sub_type: string;
|
|
503
|
+
diagnostic_code: string | null;
|
|
504
|
+
};
|
|
505
|
+
complaint?: {
|
|
506
|
+
feedback_type: string | null;
|
|
507
|
+
sub_type: string | null;
|
|
508
|
+
};
|
|
509
|
+
delay?: {
|
|
510
|
+
type: string;
|
|
511
|
+
expires_at: string | null;
|
|
512
|
+
diagnostic_code: string | null;
|
|
513
|
+
};
|
|
514
|
+
delivery?: {
|
|
515
|
+
smtp_response: string | null;
|
|
516
|
+
};
|
|
517
|
+
failure?: {
|
|
518
|
+
code: string;
|
|
519
|
+
message: string;
|
|
520
|
+
};
|
|
521
|
+
/** Only for `email.suppressed`: the entry that matched the recipient. */
|
|
522
|
+
suppression?: {
|
|
523
|
+
id: string;
|
|
524
|
+
scope: string;
|
|
525
|
+
reason: SuppressionReason;
|
|
526
|
+
};
|
|
527
|
+
/** Only for `email.opened`. */
|
|
528
|
+
open?: {
|
|
529
|
+
user_agent: string | null;
|
|
530
|
+
};
|
|
531
|
+
/** Only for `email.clicked`: the original link and its index among the tracked links. */
|
|
532
|
+
click?: {
|
|
533
|
+
url: string;
|
|
534
|
+
link_position: number;
|
|
535
|
+
user_agent: string | null;
|
|
536
|
+
};
|
|
537
|
+
/** Only for `email.rescheduled`: the new time and the one it replaced. */
|
|
538
|
+
reschedule?: {
|
|
539
|
+
scheduled_at: string;
|
|
540
|
+
previous_scheduled_at: string;
|
|
541
|
+
};
|
|
542
|
+
}
|
|
543
|
+
/** A delivery event of an email. */
|
|
544
|
+
interface EmailEvent {
|
|
545
|
+
object: "email_event";
|
|
546
|
+
id: string;
|
|
547
|
+
email_id: string;
|
|
548
|
+
type: EmailEventType;
|
|
549
|
+
/**
|
|
550
|
+
* The recipient this event is about; `null` for the whole email (`email.sent`, `email.failed`),
|
|
551
|
+
* and for opens and clicks of an email with several recipients.
|
|
552
|
+
*/
|
|
553
|
+
recipient: string | null;
|
|
554
|
+
/** ISO 8601 timestamp. */
|
|
555
|
+
occurred_at: string;
|
|
556
|
+
data: EmailEventData;
|
|
557
|
+
}
|
|
558
|
+
/** A list response. */
|
|
559
|
+
interface List<T> {
|
|
560
|
+
object: "list";
|
|
561
|
+
data: T[];
|
|
562
|
+
has_more: boolean;
|
|
563
|
+
}
|
|
564
|
+
/**
|
|
565
|
+
* Overrides the environment's tracking settings for one email. Omitted fields keep the configured
|
|
566
|
+
* setting (the email's category rule, else the environment default, else off).
|
|
567
|
+
*/
|
|
568
|
+
interface TrackingOptions {
|
|
569
|
+
/** Add an invisible pixel to the HTML body and record `email.opened` events. */
|
|
570
|
+
opens?: boolean;
|
|
571
|
+
/**
|
|
572
|
+
* Send HTML links through a coss.com redirect and record `email.clicked` events. Links with a
|
|
573
|
+
* `data-coss-no-track` attribute are left alone.
|
|
574
|
+
*/
|
|
575
|
+
clicks?: boolean;
|
|
576
|
+
/**
|
|
577
|
+
* Add one-click unsubscribe headers (`List-Unsubscribe` and `List-Unsubscribe-Post`, RFC 8058).
|
|
578
|
+
* An unsubscribe suppresses the recipient for this email's category and records
|
|
579
|
+
* `email.unsubscribed`. Needs a `category`, a single recipient, no `List-Unsubscribe` header of
|
|
580
|
+
* your own and at most 13 custom headers.
|
|
581
|
+
*/
|
|
582
|
+
unsubscribe?: boolean;
|
|
583
|
+
}
|
|
584
|
+
/**
|
|
585
|
+
* A React element, such as `<WelcomeEmail name="Ada" />`. Described by its shape so the SDK needs
|
|
586
|
+
* no React types: any JSX element fits.
|
|
587
|
+
*/
|
|
588
|
+
interface ReactEmailElement {
|
|
589
|
+
type: unknown;
|
|
590
|
+
props: unknown;
|
|
591
|
+
key: unknown;
|
|
592
|
+
}
|
|
593
|
+
/** What every send has, with or without a template. */
|
|
594
|
+
interface SendEmailBaseParams {
|
|
595
|
+
/** `"you@example.com"` or `"Your Name <you@example.com>"`. */
|
|
596
|
+
from: string;
|
|
597
|
+
to: string | string[];
|
|
598
|
+
cc?: string | string[];
|
|
599
|
+
bcc?: string | string[];
|
|
600
|
+
reply_to?: string | string[];
|
|
601
|
+
/** Custom headers. Names are case-insensitive; reserved names such as `subject` are rejected. */
|
|
602
|
+
headers?: Record<string, string>;
|
|
603
|
+
tags?: EmailTag[];
|
|
604
|
+
/**
|
|
605
|
+
* What kind of email this is, e.g. `"marketing"`. Recipients suppressed for this category (or
|
|
606
|
+
* for every email) are skipped.
|
|
607
|
+
*/
|
|
608
|
+
category?: string;
|
|
609
|
+
/**
|
|
610
|
+
* Send at this time instead of now: an ISO 8601 date-time with an offset, e.g.
|
|
611
|
+
* `"2026-10-11T09:00:00Z"`, at most 30 days ahead. A time that is not in the future sends
|
|
612
|
+
* immediately. Until it is sent, move it with `coss.email.reschedule(id, …)` or cancel it with
|
|
613
|
+
* `coss.email.cancel(id)`.
|
|
614
|
+
*/
|
|
615
|
+
scheduled_at?: string;
|
|
616
|
+
attachments?: EmailAttachmentParams[];
|
|
617
|
+
tracking?: TrackingOptions;
|
|
618
|
+
}
|
|
619
|
+
/** A send with its own subject and body. */
|
|
620
|
+
interface SendEmailContentParams extends SendEmailBaseParams {
|
|
621
|
+
subject: string;
|
|
622
|
+
/** At least one of `html`, `text` or `react` is required. */
|
|
623
|
+
html?: string;
|
|
624
|
+
/** Without it, an `html` email goes out with a text part generated from the HTML. */
|
|
625
|
+
text?: string;
|
|
626
|
+
/**
|
|
627
|
+
* A [React Email](https://react.email) component, rendered by the SDK into `html` and, unless you
|
|
628
|
+
* pass `text`, into `text` too. Needs the optional peer dependency `@react-email/render`
|
|
629
|
+
* (`npm install @react-email/render`). Can't be combined with `html`; never sent to the API as is.
|
|
630
|
+
*/
|
|
631
|
+
react?: ReactEmailElement;
|
|
632
|
+
template_id?: never;
|
|
633
|
+
template_version?: never;
|
|
634
|
+
locale?: never;
|
|
635
|
+
variables?: never;
|
|
636
|
+
}
|
|
637
|
+
/** A send of a published email template (`coss.email.templates`). */
|
|
638
|
+
interface SendEmailTemplateParams extends SendEmailBaseParams {
|
|
639
|
+
/** The template's id or alias. */
|
|
640
|
+
template_id: string;
|
|
641
|
+
/** A published version to send; defaults to the latest one. */
|
|
642
|
+
template_version?: number;
|
|
643
|
+
/**
|
|
644
|
+
* The locale to send, e.g. `"pt-BR"`. Falls back to the language (`"pt"`), then to the
|
|
645
|
+
* template's default locale.
|
|
646
|
+
*/
|
|
647
|
+
locale?: string;
|
|
648
|
+
/** Values for the template's variables, keyed by name. */
|
|
649
|
+
variables?: Record<string, unknown>;
|
|
650
|
+
subject?: never;
|
|
651
|
+
html?: never;
|
|
652
|
+
text?: never;
|
|
653
|
+
react?: never;
|
|
654
|
+
}
|
|
655
|
+
/** A send: a subject and body (or `react`, which the SDK renders before sending), or a template. */
|
|
656
|
+
type SendEmailParams = SendEmailContentParams | SendEmailTemplateParams;
|
|
657
|
+
/** Parameters of `coss.email.reschedule`. */
|
|
658
|
+
interface RescheduleEmailParams {
|
|
659
|
+
/**
|
|
660
|
+
* The new time: an ISO 8601 date-time with an offset, at most 30 days ahead. A time that is not
|
|
661
|
+
* in the future sends the email right away.
|
|
662
|
+
*/
|
|
663
|
+
scheduled_at: string;
|
|
664
|
+
}
|
|
665
|
+
/**
|
|
666
|
+
* Open and click tracking as resolved when the email was sent, with engagement so far. Opens can
|
|
667
|
+
* be inflated by mail clients that prefetch images, clicks by link scanners.
|
|
668
|
+
*/
|
|
669
|
+
interface EmailTracking {
|
|
670
|
+
opens: boolean;
|
|
671
|
+
clicks: boolean;
|
|
672
|
+
/** Whether the email carries one-click unsubscribe headers (RFC 8058). */
|
|
673
|
+
unsubscribe: boolean;
|
|
674
|
+
open_count: number;
|
|
675
|
+
/** ISO 8601 timestamps, or `null`. */
|
|
676
|
+
first_opened_at: string | null;
|
|
677
|
+
last_opened_at: string | null;
|
|
678
|
+
click_count: number;
|
|
679
|
+
first_clicked_at: string | null;
|
|
680
|
+
last_clicked_at: string | null;
|
|
681
|
+
}
|
|
682
|
+
/** A link coss.com rewrote for click tracking. */
|
|
683
|
+
interface EmailLink {
|
|
684
|
+
object: "email_link";
|
|
685
|
+
id: string;
|
|
686
|
+
email_id: string;
|
|
687
|
+
/** Index of the link among the email's tracked links, in document order. */
|
|
688
|
+
position: number;
|
|
689
|
+
url: string;
|
|
690
|
+
click_count: number;
|
|
691
|
+
first_clicked_at: string | null;
|
|
692
|
+
last_clicked_at: string | null;
|
|
693
|
+
}
|
|
694
|
+
/** Why an email failed as a whole. */
|
|
695
|
+
interface EmailFailure {
|
|
696
|
+
/**
|
|
697
|
+
* E.g. `all_recipients_suppressed`, `domain_not_verified`, `content_rejected`,
|
|
698
|
+
* `attachments_unavailable`, `dispatch_failed` or `provider_error`.
|
|
699
|
+
*/
|
|
700
|
+
code: string;
|
|
701
|
+
message: string;
|
|
702
|
+
}
|
|
703
|
+
/** An email as returned by the API. Recipient fields are always arrays. */
|
|
704
|
+
interface Email {
|
|
705
|
+
object: "email";
|
|
706
|
+
id: string;
|
|
707
|
+
from: string;
|
|
708
|
+
to: string[];
|
|
709
|
+
cc: string[];
|
|
710
|
+
bcc: string[];
|
|
711
|
+
reply_to: string[];
|
|
712
|
+
subject: string;
|
|
713
|
+
html: string | null;
|
|
714
|
+
text: string | null;
|
|
715
|
+
/** Header names are lower-cased. */
|
|
716
|
+
headers: Record<string, string>;
|
|
717
|
+
tags: EmailTag[];
|
|
718
|
+
category: string | null;
|
|
719
|
+
status: EmailStatus;
|
|
720
|
+
/** Why the email failed; `null` unless `status` is `"failed"`. */
|
|
721
|
+
failure: EmailFailure | null;
|
|
722
|
+
/** Every distinct recipient across `to`, `cc` and `bcc`, with its delivery status. */
|
|
723
|
+
recipients: EmailRecipient[];
|
|
724
|
+
/** Attachment metadata; the content is discarded once the email is sent. */
|
|
725
|
+
attachments: EmailAttachment[];
|
|
726
|
+
/** `true` when sent with a sandbox (`coss_test_…`) key: nothing is actually delivered. */
|
|
727
|
+
sandbox: boolean;
|
|
728
|
+
tracking: EmailTracking;
|
|
729
|
+
/** ISO 8601 timestamp. */
|
|
730
|
+
created_at: string;
|
|
731
|
+
/** ISO 8601 timestamp, or `null` until the provider accepts the message. */
|
|
732
|
+
sent_at: string | null;
|
|
733
|
+
/** ISO 8601 timestamp the email was scheduled for, or `null` if no schedule was provided. */
|
|
734
|
+
scheduled_at: string | null;
|
|
735
|
+
/** The batch that sent the email (`coss.email.sendBatch`), or `null` if it was sent alone. */
|
|
736
|
+
batch_id: string | null;
|
|
737
|
+
/** The template the email was rendered from, or `null` if it was sent without one. */
|
|
738
|
+
template: EmailTemplateReference | null;
|
|
739
|
+
}
|
|
740
|
+
/** An email in a list (`coss.email.list`): everything but its content. */
|
|
741
|
+
type EmailSummary = Omit<Email, "html" | "text" | "headers" | "attachments">;
|
|
742
|
+
/** Filters of `coss.email.list`. Emails are returned newest first. */
|
|
743
|
+
interface ListEmailsParams {
|
|
744
|
+
/** Only emails with this recipient (in `to`, `cc` or `bcc`; the bare address, any case). */
|
|
745
|
+
to?: string;
|
|
746
|
+
/** Only emails with a recipient in one of these statuses (with `to`, that recipient's). */
|
|
747
|
+
recipient_status?: EmailRecipientStatus[];
|
|
748
|
+
/** Only emails in these statuses. */
|
|
749
|
+
status?: EmailStatus[];
|
|
750
|
+
/** Free text, matched against the subject and the `to` addresses. */
|
|
751
|
+
q?: string;
|
|
752
|
+
/** Only emails of this category. */
|
|
753
|
+
category?: string;
|
|
754
|
+
/** Only the emails of this batch. */
|
|
755
|
+
batch_id?: string;
|
|
756
|
+
/** Only emails created at or after this time. */
|
|
757
|
+
created_after?: Date | string;
|
|
758
|
+
/** Only emails created before this time. */
|
|
759
|
+
created_before?: Date | string;
|
|
760
|
+
/** 1-100, default 20. */
|
|
761
|
+
limit?: number;
|
|
762
|
+
/** Cursor: the `id` of the last email of the previous page. */
|
|
763
|
+
after?: string;
|
|
764
|
+
}
|
|
765
|
+
/** Emails sent together by `coss.email.sendBatch`. */
|
|
766
|
+
interface EmailBatch {
|
|
767
|
+
object: "email_batch";
|
|
768
|
+
id: string;
|
|
769
|
+
/** The batch's emails, in the order they were passed. */
|
|
770
|
+
data: Email[];
|
|
771
|
+
/** ISO 8601 timestamp. */
|
|
772
|
+
created_at: string;
|
|
773
|
+
}
|
|
774
|
+
//#endregion
|
|
775
|
+
//#region src/resources/audit-events.d.ts
|
|
776
|
+
type ReadOptions$17 = Pick<RequestOptions, "signal">;
|
|
777
|
+
/**
|
|
778
|
+
* `coss.auditEvents`: the organization's audit log, newest first: changes made by members, API
|
|
779
|
+
* keys and coss.com support. Organization-wide, whichever environment the key belongs to.
|
|
780
|
+
*/
|
|
781
|
+
declare class AuditEventsResource {
|
|
782
|
+
#private;
|
|
783
|
+
/** @internal Use `new Coss().auditEvents`. */
|
|
784
|
+
constructor(http: HttpClient);
|
|
785
|
+
/** Lists audit events, newest first. Pass the last `id` as `after` while `has_more` is true. */
|
|
786
|
+
list(params?: ListAuditEventsParams, options?: ReadOptions$17): Promise<CossResult<List<AuditEvent>>>;
|
|
787
|
+
/** Retrieves one audit event. */
|
|
788
|
+
get(id: string, options?: ReadOptions$17): Promise<CossResult<AuditEvent>>;
|
|
789
|
+
}
|
|
790
|
+
//#endregion
|
|
791
|
+
//#region src/types/billing.d.ts
|
|
792
|
+
/**
|
|
793
|
+
* Billing wire types (hand-written mirrors of the API's `Billing`, `Usage`, `Invoice` and `Credit`
|
|
794
|
+
* schemas). Amounts are integers in cents (USD); unit prices are dollar decimal strings.
|
|
795
|
+
*/
|
|
796
|
+
type PlanKey = "free" | "pro" | "scale" | "enterprise";
|
|
797
|
+
type Meter = "email.recipients" | "email.dedicated_ip" | "sms.segments" | "video.participant_minutes" | "scheduling.bookings";
|
|
798
|
+
type BillingHoldReason = "delinquent" | "spend_limit" | "admin";
|
|
799
|
+
/** `GET /v1/billing`: the organization's plan, the current month so far, and its standing. */
|
|
800
|
+
interface Billing {
|
|
801
|
+
object: "billing";
|
|
802
|
+
organization_id: string;
|
|
803
|
+
/** The plan in effect now (`free` without a contract). */
|
|
804
|
+
plan: PlanKey;
|
|
805
|
+
/** The contract in effect; `null` on the Free plan. */
|
|
806
|
+
contract: {
|
|
807
|
+
id: string;
|
|
808
|
+
kind: "self_serve" | "sales" | "internal";
|
|
809
|
+
effective_from: string;
|
|
810
|
+
effective_until: string | null;
|
|
811
|
+
/** End of a committed term. */
|
|
812
|
+
term_end: string | null;
|
|
813
|
+
auto_renew: boolean;
|
|
814
|
+
} | null;
|
|
815
|
+
/** A plan change that takes effect later (a downgrade, a cancellation). */
|
|
816
|
+
scheduled_change: {
|
|
817
|
+
effective_at: string;
|
|
818
|
+
plan: PlanKey;
|
|
819
|
+
} | null;
|
|
820
|
+
/** `past_due`: an invoice is overdue; `delinquent`: past its grace period (live sending is held). */
|
|
821
|
+
status: "active" | "past_due" | "delinquent";
|
|
822
|
+
/** Billing holds on live sending (sandbox keys keep working). */
|
|
823
|
+
holds: {
|
|
824
|
+
reason: BillingHoldReason;
|
|
825
|
+
since: string;
|
|
826
|
+
}[];
|
|
827
|
+
currency: "usd";
|
|
828
|
+
/** The current billing month (UTC). */
|
|
829
|
+
period: {
|
|
830
|
+
start: string;
|
|
831
|
+
end: string;
|
|
832
|
+
};
|
|
833
|
+
usage: {
|
|
834
|
+
meter: Meter;
|
|
835
|
+
quantity: number;
|
|
836
|
+
/** The plan's monthly allowance where usage stops (Free), else `null`. */
|
|
837
|
+
included: number | null;
|
|
838
|
+
}[];
|
|
839
|
+
/** This month so far, as it would be invoiced if it ended now (cents). */
|
|
840
|
+
estimate: {
|
|
841
|
+
usage: number;
|
|
842
|
+
discount: number;
|
|
843
|
+
credit: number;
|
|
844
|
+
total: number;
|
|
845
|
+
};
|
|
846
|
+
/** Unused credit usable this month (cents). */
|
|
847
|
+
credit_remaining: number;
|
|
848
|
+
/** Usage beyond the credit past which live sending is held (cents); `null`: none. */
|
|
849
|
+
spend_limit: number | null;
|
|
850
|
+
payment_method: {
|
|
851
|
+
type: string;
|
|
852
|
+
brand: string | null;
|
|
853
|
+
last4: string | null;
|
|
854
|
+
} | null;
|
|
855
|
+
/** Add-ons of the contract in effect, charged on top of the plan. */
|
|
856
|
+
add_ons: {
|
|
857
|
+
/** e.g. `dedicated_ips`. */
|
|
858
|
+
key: string;
|
|
859
|
+
name: string;
|
|
860
|
+
quantity: number;
|
|
861
|
+
/** The price per unit and interval (cents). */
|
|
862
|
+
unit_amount: number;
|
|
863
|
+
interval: "month" | "quarter" | "year";
|
|
864
|
+
}[];
|
|
865
|
+
features: {
|
|
866
|
+
tracking_domains: boolean;
|
|
867
|
+
audit_log: boolean;
|
|
868
|
+
log_drains: boolean;
|
|
869
|
+
sso: boolean;
|
|
870
|
+
scim: boolean;
|
|
871
|
+
dedicated_ips: boolean;
|
|
872
|
+
};
|
|
873
|
+
/** Resource limits (`null`: unlimited). */
|
|
874
|
+
limits: {
|
|
875
|
+
domains: number | null;
|
|
876
|
+
members: number | null;
|
|
877
|
+
webhook_endpoints_per_environment: number | null;
|
|
878
|
+
};
|
|
879
|
+
}
|
|
880
|
+
/** Billable usage of one meter in one bucket. */
|
|
881
|
+
interface Usage {
|
|
882
|
+
object: "usage";
|
|
883
|
+
meter: Meter;
|
|
884
|
+
/** e.g. `country=US` for SMS; `null` for none. */
|
|
885
|
+
dimension: string | null;
|
|
886
|
+
/** Set with `group_by: "environment"`. */
|
|
887
|
+
environment_id: string | null;
|
|
888
|
+
start: string;
|
|
889
|
+
end: string;
|
|
890
|
+
quantity: number;
|
|
891
|
+
}
|
|
892
|
+
interface ListUsageParams {
|
|
893
|
+
/** Start (inclusive, ISO 8601). Defaults to the start of the current billing month. */
|
|
894
|
+
from?: string;
|
|
895
|
+
/** End (exclusive). Defaults to now. At most 400 days after `from` (7 by hour). */
|
|
896
|
+
to?: string;
|
|
897
|
+
/** Bucket size (UTC). Defaults to `day`. */
|
|
898
|
+
granularity?: "hour" | "day" | "month";
|
|
899
|
+
/** Split each bucket per environment. */
|
|
900
|
+
group_by?: "environment";
|
|
901
|
+
/** Only this meter. */
|
|
902
|
+
meter?: Meter;
|
|
903
|
+
}
|
|
904
|
+
type InvoiceStatus = "open" | "paid" | "void" | "uncollectible";
|
|
905
|
+
type InvoiceLineKind = "plan_fee" | "proration" | "usage" | "credit" | "discount" | "commitment_fee" | "commitment_shortfall" | "add_on" | "adjustment" | "write_off";
|
|
906
|
+
interface InvoiceLine {
|
|
907
|
+
object: "invoice_line";
|
|
908
|
+
id: string;
|
|
909
|
+
kind: InvoiceLineKind;
|
|
910
|
+
description: string;
|
|
911
|
+
meter: Meter | null;
|
|
912
|
+
dimension: string | null;
|
|
913
|
+
quantity: number | null;
|
|
914
|
+
/** Units covered by an allowance or committed volume (not charged). */
|
|
915
|
+
included_quantity: number | null;
|
|
916
|
+
/** Dollars per unit, e.g. `"0.0004"`; `null` when the price varies by volume. */
|
|
917
|
+
unit_price: string | null;
|
|
918
|
+
/** Cents. */
|
|
919
|
+
amount: number;
|
|
920
|
+
period: {
|
|
921
|
+
start: string;
|
|
922
|
+
end: string;
|
|
923
|
+
};
|
|
924
|
+
}
|
|
925
|
+
/** An invoice without its lines (lists and webhook events). Amounts in cents. */
|
|
926
|
+
interface InvoiceSummary {
|
|
927
|
+
object: "invoice";
|
|
928
|
+
id: string;
|
|
929
|
+
number: string | null;
|
|
930
|
+
kind: "period" | "plan_change" | "one_off" | "final";
|
|
931
|
+
status: InvoiceStatus;
|
|
932
|
+
currency: "usd";
|
|
933
|
+
period: {
|
|
934
|
+
start: string;
|
|
935
|
+
end: string;
|
|
936
|
+
};
|
|
937
|
+
subtotal: number;
|
|
938
|
+
discount: number;
|
|
939
|
+
credit: number;
|
|
940
|
+
tax: number;
|
|
941
|
+
total: number;
|
|
942
|
+
amount_paid: number;
|
|
943
|
+
amount_due: number;
|
|
944
|
+
collection_method: "charge_automatically" | "send_invoice";
|
|
945
|
+
due_at: string | null;
|
|
946
|
+
finalized_at: string | null;
|
|
947
|
+
paid_at: string | null;
|
|
948
|
+
voided_at: string | null;
|
|
949
|
+
/** A page to view (and pay) the invoice. */
|
|
950
|
+
hosted_url: string | null;
|
|
951
|
+
pdf_url: string | null;
|
|
952
|
+
}
|
|
953
|
+
interface Invoice extends InvoiceSummary {
|
|
954
|
+
lines: InvoiceLine[];
|
|
955
|
+
}
|
|
956
|
+
interface ListInvoicesParams {
|
|
957
|
+
/** Only invoices in this status. */
|
|
958
|
+
status?: InvoiceStatus;
|
|
959
|
+
/** Continue after this id (the last of the previous page). */
|
|
960
|
+
after?: string;
|
|
961
|
+
/** At most this many (1-100, default 20). */
|
|
962
|
+
limit?: number;
|
|
963
|
+
}
|
|
964
|
+
/** Credit the organization can spend: dollars (cents) or free units of a meter. */
|
|
965
|
+
interface Credit {
|
|
966
|
+
object: "credit";
|
|
967
|
+
id: string;
|
|
968
|
+
/** `amount`: dollars (`amount` and `remaining` in cents); `units`: free units of `meter`. */
|
|
969
|
+
kind: "amount" | "units";
|
|
970
|
+
amount: number;
|
|
971
|
+
remaining: number;
|
|
972
|
+
/** What a `units` credit covers. */
|
|
973
|
+
meter: Meter | null;
|
|
974
|
+
/** What an `amount` credit pays for (`null`: any usage). */
|
|
975
|
+
meters: Meter[] | null;
|
|
976
|
+
/** `any`: also fees and other charges. */
|
|
977
|
+
applies_to: "usage" | "any";
|
|
978
|
+
source: "fee" | "commitment" | "support" | "promotion" | "refund" | "sla";
|
|
979
|
+
description: string;
|
|
980
|
+
effective_at: string;
|
|
981
|
+
expires_at: string | null;
|
|
982
|
+
voided_at: string | null;
|
|
983
|
+
created_at: string;
|
|
984
|
+
}
|
|
985
|
+
interface ListCreditsParams {
|
|
986
|
+
/** `active` (default): usable now or later, with something left; `all`: every credit. */
|
|
987
|
+
status?: "active" | "all";
|
|
988
|
+
/** Continue after this id (the last of the previous page). */
|
|
989
|
+
after?: string;
|
|
990
|
+
/** At most this many (1-100, default 20). */
|
|
991
|
+
limit?: number;
|
|
992
|
+
}
|
|
993
|
+
//#endregion
|
|
994
|
+
//#region src/resources/billing.d.ts
|
|
995
|
+
type ReadOptions$16 = Pick<RequestOptions, "signal">;
|
|
996
|
+
/** `coss.billing.invoices`: the organization's invoices, newest first. */
|
|
997
|
+
declare class BillingInvoicesResource {
|
|
998
|
+
#private;
|
|
999
|
+
/** @internal Use `new Coss().billing.invoices`. */
|
|
1000
|
+
constructor(http: HttpClient);
|
|
1001
|
+
/** Lists invoices (without lines). Pass the last `id` as `after` while `has_more` is true. */
|
|
1002
|
+
list(params?: ListInvoicesParams, options?: ReadOptions$16): Promise<CossResult<List<InvoiceSummary>>>;
|
|
1003
|
+
/** Retrieves one invoice with its lines. */
|
|
1004
|
+
get(id: string, options?: ReadOptions$16): Promise<CossResult<Invoice>>;
|
|
1005
|
+
}
|
|
1006
|
+
/** `coss.billing.credits`: the organization's credits and what's left of them. */
|
|
1007
|
+
declare class BillingCreditsResource {
|
|
1008
|
+
#private;
|
|
1009
|
+
/** @internal Use `new Coss().billing.credits`. */
|
|
1010
|
+
constructor(http: HttpClient);
|
|
1011
|
+
/** Lists credits, newest first (usable ones by default). */
|
|
1012
|
+
list(params?: ListCreditsParams, options?: ReadOptions$16): Promise<CossResult<List<Credit>>>;
|
|
1013
|
+
}
|
|
1014
|
+
/**
|
|
1015
|
+
* `coss.billing`: the organization's plan, usage, invoices and credits (read only; plan changes
|
|
1016
|
+
* are made in the dashboard). Organization-wide, whichever environment the key belongs to.
|
|
1017
|
+
*/
|
|
1018
|
+
declare class BillingResource {
|
|
1019
|
+
#private;
|
|
1020
|
+
readonly invoices: BillingInvoicesResource;
|
|
1021
|
+
readonly credits: BillingCreditsResource;
|
|
1022
|
+
/** @internal Use `new Coss().billing`. */
|
|
1023
|
+
constructor(http: HttpClient);
|
|
1024
|
+
/** The plan, the current month's usage and estimate, standing and what the plan includes. */
|
|
1025
|
+
get(options?: ReadOptions$16): Promise<CossResult<Billing>>;
|
|
1026
|
+
/** Billable usage per meter and bucket (the current month, by day, by default), oldest first. */
|
|
1027
|
+
usage(params?: ListUsageParams, options?: ReadOptions$16): Promise<CossResult<List<Usage>>>;
|
|
1028
|
+
}
|
|
1029
|
+
//#endregion
|
|
1030
|
+
//#region src/types/domain.d.ts
|
|
1031
|
+
/**
|
|
1032
|
+
* Sending domain wire types. Hand-written to mirror the API's snake_case JSON 1:1 (the API's
|
|
1033
|
+
* contract test asserts they stay assignable to and from its zod schemas).
|
|
1034
|
+
*/
|
|
1035
|
+
/**
|
|
1036
|
+
* `pending` while the DNS records are being checked, `verified` once they are,
|
|
1037
|
+
* `temporary_failure` after a transient DNS problem, and `failed` when verification gave up
|
|
1038
|
+
* (72 hours) — call `verify` to start over. `deleting` is a removal in progress.
|
|
1039
|
+
*/
|
|
1040
|
+
type DomainStatus = "pending" | "verified" | "temporary_failure" | "failed" | "deleting";
|
|
1041
|
+
/** Verification state of the `send.` bounce subdomain. */
|
|
1042
|
+
type MailFromStatus = "pending" | "success" | "temporary_failure" | "failed";
|
|
1043
|
+
/**
|
|
1044
|
+
* What a record is for: `dkim` signs messages, `mail_from_mx` and `mail_from_spf` set up the
|
|
1045
|
+
* bounce subdomain, and `dmarc` is recommended but not required.
|
|
1046
|
+
*/
|
|
1047
|
+
type DomainRecordPurpose = "dkim" | "mail_from_mx" | "mail_from_spf" | "dmarc";
|
|
1048
|
+
/** What the last DNS check saw. `not_checked` means DNS has not been consulted yet. */
|
|
1049
|
+
type DomainRecordStatus = "verified" | "missing" | "mismatch" | "not_checked";
|
|
1050
|
+
/** One DNS record a domain needs (or, when `required` is `false`, should have). */
|
|
1051
|
+
interface DomainRecord {
|
|
1052
|
+
purpose: DomainRecordPurpose;
|
|
1053
|
+
type: "CNAME" | "MX" | "TXT";
|
|
1054
|
+
/** The fully qualified record name to create. */
|
|
1055
|
+
name: string;
|
|
1056
|
+
value: string;
|
|
1057
|
+
/** `MX` records only. */
|
|
1058
|
+
priority: number | null;
|
|
1059
|
+
/** `false` for records that are only recommended. */
|
|
1060
|
+
required: boolean;
|
|
1061
|
+
status: DomainRecordStatus;
|
|
1062
|
+
/** What DNS returned when it did not match. */
|
|
1063
|
+
found: string[];
|
|
1064
|
+
}
|
|
1065
|
+
/**
|
|
1066
|
+
* `pending` until the CNAME points at coss.com and its certificate is issued, `active` once tracking
|
|
1067
|
+
* links of emails sent from the domain use it, `temporary_failure` when an active hostname stopped
|
|
1068
|
+
* working (emails fall back to the default tracking host meanwhile), and `failed` when setup gave
|
|
1069
|
+
* up (72 hours) — call `domains.verify` to start over. `deleting` is a removal in progress.
|
|
1070
|
+
*/
|
|
1071
|
+
type TrackingDomainStatus = "pending" | "active" | "temporary_failure" | "failed" | "deleting";
|
|
1072
|
+
/** The CNAME a tracking domain needs, with the result of the last check. */
|
|
1073
|
+
interface TrackingDomainRecord {
|
|
1074
|
+
type: "CNAME";
|
|
1075
|
+
/** The fully qualified record name to create. */
|
|
1076
|
+
name: string;
|
|
1077
|
+
/** The host the record must point at. */
|
|
1078
|
+
value: string;
|
|
1079
|
+
status: DomainRecordStatus;
|
|
1080
|
+
/** What DNS returned when it did not match. */
|
|
1081
|
+
found: string[];
|
|
1082
|
+
}
|
|
1083
|
+
/** A domain's custom tracking domain: open pixels and click redirects use it while `active`. */
|
|
1084
|
+
interface TrackingDomain {
|
|
1085
|
+
/** The tracking hostname, a subdomain of the domain (e.g. `links.acme.com`). */
|
|
1086
|
+
hostname: string;
|
|
1087
|
+
status: TrackingDomainStatus;
|
|
1088
|
+
record: TrackingDomainRecord;
|
|
1089
|
+
/** What is holding the hostname up, when the certificate provider said. */
|
|
1090
|
+
message: string | null;
|
|
1091
|
+
/** ISO 8601 timestamp. */
|
|
1092
|
+
created_at: string;
|
|
1093
|
+
last_checked_at: string | null;
|
|
1094
|
+
activated_at: string | null;
|
|
1095
|
+
failed_at: string | null;
|
|
1096
|
+
}
|
|
1097
|
+
/** The MX record a receiving domain needs, with the result of the last check. */
|
|
1098
|
+
interface ReceivingDomainRecord {
|
|
1099
|
+
type: "MX";
|
|
1100
|
+
/** The fully qualified record name to create. */
|
|
1101
|
+
name: string;
|
|
1102
|
+
/** The mail exchange the record must point at. */
|
|
1103
|
+
value: string;
|
|
1104
|
+
priority: number;
|
|
1105
|
+
/** `verified` once the most preferred MX records point at coss.com. */
|
|
1106
|
+
status: DomainRecordStatus;
|
|
1107
|
+
/** What DNS returned when it did not match. */
|
|
1108
|
+
found: string[];
|
|
1109
|
+
}
|
|
1110
|
+
/** A domain's receiving hostname: email to any address at it is received by `environment_id`. */
|
|
1111
|
+
interface ReceivingDomain {
|
|
1112
|
+
/** The domain itself or a subdomain of it (e.g. `inbound.acme.com`). */
|
|
1113
|
+
hostname: string;
|
|
1114
|
+
environment_id: string;
|
|
1115
|
+
record: ReceivingDomainRecord;
|
|
1116
|
+
/** ISO 8601 timestamp. */
|
|
1117
|
+
created_at: string;
|
|
1118
|
+
last_checked_at: string | null;
|
|
1119
|
+
}
|
|
1120
|
+
/**
|
|
1121
|
+
* `configured` when the BIMI record is valid and DMARC is enforced, `invalid` when a record exists
|
|
1122
|
+
* but something is wrong (see `issues`), `missing` when there is no record, and `not_checked` until
|
|
1123
|
+
* DNS has been consulted. coss.com checks DNS only: mailbox providers still validate the logo and the
|
|
1124
|
+
* certificate.
|
|
1125
|
+
*/
|
|
1126
|
+
type BimiStatus = "not_checked" | "missing" | "invalid" | "configured";
|
|
1127
|
+
/** What keeps a domain's logo from showing, as far as DNS tells. */
|
|
1128
|
+
type BimiIssueCode = "dmarc_missing" | "dmarc_not_enforced" | "dmarc_partial" | "record_multiple" | "record_invalid" | "logo_missing" | "logo_not_https" | "certificate_missing" | "certificate_not_https";
|
|
1129
|
+
/** The last BIMI check of a domain (brand logos in inboxes; the certificate is your own). */
|
|
1130
|
+
interface DomainBimi {
|
|
1131
|
+
status: BimiStatus;
|
|
1132
|
+
/**
|
|
1133
|
+
* Where the BIMI record was found, or looked up when there is none: `default._bimi.<domain>`,
|
|
1134
|
+
* or the organizational domain's when only it has one.
|
|
1135
|
+
*/
|
|
1136
|
+
name: string;
|
|
1137
|
+
/** The `v=BIMI1` record found. */
|
|
1138
|
+
record: string | null;
|
|
1139
|
+
/** The record's logo URL (`l=`). */
|
|
1140
|
+
logo_url: string | null;
|
|
1141
|
+
/** The record's VMC or CMC certificate URL (`a=`). */
|
|
1142
|
+
certificate_url: string | null;
|
|
1143
|
+
/**
|
|
1144
|
+
* The DMARC policy that applies to the domain (the organizational domain's `sp` when it has no
|
|
1145
|
+
* record of its own), `null` without a DMARC record.
|
|
1146
|
+
*/
|
|
1147
|
+
dmarc_policy: "none" | "quarantine" | "reject" | null;
|
|
1148
|
+
issues: {
|
|
1149
|
+
code: BimiIssueCode;
|
|
1150
|
+
message: string;
|
|
1151
|
+
}[];
|
|
1152
|
+
}
|
|
1153
|
+
/** A sending domain of the organization. */
|
|
1154
|
+
interface Domain {
|
|
1155
|
+
object: "domain";
|
|
1156
|
+
id: string;
|
|
1157
|
+
/** The domain, lower-cased. */
|
|
1158
|
+
name: string;
|
|
1159
|
+
status: DomainStatus;
|
|
1160
|
+
/** Whether live keys may send from this domain right now. */
|
|
1161
|
+
can_send: boolean;
|
|
1162
|
+
region: string | null;
|
|
1163
|
+
/** The envelope sender subdomain bounces come back to. */
|
|
1164
|
+
mail_from_domain: string;
|
|
1165
|
+
mail_from_status: MailFromStatus;
|
|
1166
|
+
/** The DNS records to publish, with the result of the last check. */
|
|
1167
|
+
records: DomainRecord[];
|
|
1168
|
+
/** ISO 8601 timestamp. */
|
|
1169
|
+
created_at: string;
|
|
1170
|
+
last_checked_at: string | null;
|
|
1171
|
+
verified_at: string | null;
|
|
1172
|
+
failed_at: string | null;
|
|
1173
|
+
/** The custom tracking domain, or `null` when none is set up. */
|
|
1174
|
+
tracking: TrackingDomain | null;
|
|
1175
|
+
/** The receiving hostname, or `null` when the domain doesn't receive email. */
|
|
1176
|
+
receiving: ReceivingDomain | null;
|
|
1177
|
+
/** The last BIMI check: whether mailbox providers can find the domain's brand logo. */
|
|
1178
|
+
bimi: DomainBimi;
|
|
1179
|
+
}
|
|
1180
|
+
/** Body of `POST /v1/domains`. */
|
|
1181
|
+
interface CreateDomainParams {
|
|
1182
|
+
/**
|
|
1183
|
+
* The domain to send from, without a scheme or path (`"acme.com"`, `"mail.acme.com"`).
|
|
1184
|
+
* Internationalized domains must be punycode-encoded.
|
|
1185
|
+
*/
|
|
1186
|
+
name: string;
|
|
1187
|
+
}
|
|
1188
|
+
/** Returned by `domains.delete`. */
|
|
1189
|
+
interface DeletedDomain {
|
|
1190
|
+
object: "domain";
|
|
1191
|
+
id: string;
|
|
1192
|
+
deleted: true;
|
|
1193
|
+
}
|
|
1194
|
+
/** Body of `POST /v1/domains/{id}/tracking`. */
|
|
1195
|
+
interface CreateTrackingDomainParams {
|
|
1196
|
+
/** A subdomain of the domain to serve tracking links from (`"links.acme.com"`). */
|
|
1197
|
+
hostname: string;
|
|
1198
|
+
}
|
|
1199
|
+
/** Body of `POST /v1/domains/{id}/receiving`. */
|
|
1200
|
+
interface CreateReceivingDomainParams {
|
|
1201
|
+
/** The domain itself or a subdomain of it (`"inbound.acme.com"`). */
|
|
1202
|
+
hostname: string;
|
|
1203
|
+
}
|
|
1204
|
+
//#endregion
|
|
1205
|
+
//#region src/types/dmarc.d.ts
|
|
1206
|
+
/** DMARC wire types (hand-written mirrors of the API's `DomainDmarc` and `DmarcReport` schemas). */
|
|
1207
|
+
type DmarcPolicy = "none" | "quarantine" | "reject";
|
|
1208
|
+
/** Where a domain is on the path from `p=none` to `p=reject`. */
|
|
1209
|
+
type DmarcStage = "not_checked" | "no_record" | "monitoring" | "quarantine" | "reject";
|
|
1210
|
+
/**
|
|
1211
|
+
* `publish` a first record, `add_reporting` (send reports to coss.com), `complete_rollout` (drop
|
|
1212
|
+
* `pct`/`t=y`) or `tighten` to the next policy.
|
|
1213
|
+
*/
|
|
1214
|
+
type DmarcNextStepKind = "publish" | "add_reporting" | "complete_rollout" | "tighten";
|
|
1215
|
+
type DmarcCheckId = "coverage" | "recent" | "complete" | "time_at_policy" | "coss_pass_rate" | "pass_rate" | "sources";
|
|
1216
|
+
/** The DMARC record found at `_dmarc.<domain>` by the latest DNS check. */
|
|
1217
|
+
interface DmarcPublishedRecord {
|
|
1218
|
+
/** The `v=DMARC1` TXT record as published. */
|
|
1219
|
+
value: string;
|
|
1220
|
+
p: DmarcPolicy | null;
|
|
1221
|
+
sp: DmarcPolicy | null;
|
|
1222
|
+
np: DmarcPolicy | null;
|
|
1223
|
+
adkim: "r" | "s" | null;
|
|
1224
|
+
aspf: "r" | "s" | null;
|
|
1225
|
+
/** Removed by RFC 9989 but still honored by many receivers. */
|
|
1226
|
+
pct: number | null;
|
|
1227
|
+
t: "y" | "n" | null;
|
|
1228
|
+
/** Aggregate report addresses. */
|
|
1229
|
+
rua: string[];
|
|
1230
|
+
}
|
|
1231
|
+
/** Messages from one source IP with one From domain, over the report summary's period. */
|
|
1232
|
+
interface DmarcSource {
|
|
1233
|
+
source_ip: string;
|
|
1234
|
+
/** The domain in the messages' From header. */
|
|
1235
|
+
header_from: string;
|
|
1236
|
+
messages: number;
|
|
1237
|
+
/** Messages that passed DMARC. */
|
|
1238
|
+
passing: number;
|
|
1239
|
+
/** Signed with the domain's coss.com DKIM keys or sent from its coss.com MAIL FROM domain. */
|
|
1240
|
+
via_coss: boolean;
|
|
1241
|
+
}
|
|
1242
|
+
/** One readiness check gating `DomainDmarc.next`. */
|
|
1243
|
+
interface DmarcCheck {
|
|
1244
|
+
id: DmarcCheckId;
|
|
1245
|
+
ok: boolean;
|
|
1246
|
+
message: string;
|
|
1247
|
+
}
|
|
1248
|
+
/** The next step on the path to `p=reject`. */
|
|
1249
|
+
interface DmarcNextStep {
|
|
1250
|
+
kind: DmarcNextStepKind;
|
|
1251
|
+
policy: DmarcPolicy;
|
|
1252
|
+
/** The TXT record to publish at `_dmarc.<domain>`. */
|
|
1253
|
+
record: string;
|
|
1254
|
+
}
|
|
1255
|
+
/** A domain's DMARC status: its record, the guided next step and recent reports. */
|
|
1256
|
+
interface DomainDmarc {
|
|
1257
|
+
object: "domain_dmarc";
|
|
1258
|
+
domain_id: string;
|
|
1259
|
+
/** Where the domain's aggregate reports go; `null` when the deployment doesn't receive email. */
|
|
1260
|
+
report_address: string | null;
|
|
1261
|
+
/** The domain's own record. `null`: none found (or an invalid one), or DNS not checked yet. */
|
|
1262
|
+
record: DmarcPublishedRecord | null;
|
|
1263
|
+
/** The policy receivers apply: the domain's own, else its organizational domain's (`sp`, else `p`). */
|
|
1264
|
+
policy: DmarcPolicy | null;
|
|
1265
|
+
/** The organizational domain whose record applies, when the domain publishes none of its own. */
|
|
1266
|
+
inherited_from: string | null;
|
|
1267
|
+
/** ISO 8601 timestamp: when a DNS check first saw the current policy. */
|
|
1268
|
+
policy_since: string | null;
|
|
1269
|
+
stage: DmarcStage;
|
|
1270
|
+
/** The policy applies only partly (`pct` below 100, or `t=y`). */
|
|
1271
|
+
partial: boolean;
|
|
1272
|
+
/** The published record sends aggregate reports to `report_address`. */
|
|
1273
|
+
reporting: boolean;
|
|
1274
|
+
/** Whether `next` is safe to publish now. */
|
|
1275
|
+
ready: boolean;
|
|
1276
|
+
/** `null` at `p=reject`. */
|
|
1277
|
+
next: DmarcNextStep | null;
|
|
1278
|
+
checks: DmarcCheck[];
|
|
1279
|
+
warnings: string[];
|
|
1280
|
+
report_summary: {
|
|
1281
|
+
/** ISO 8601 timestamps of the summarized period (the last 14 days). */
|
|
1282
|
+
period_start: string;
|
|
1283
|
+
period_end: string;
|
|
1284
|
+
reports: number;
|
|
1285
|
+
messages: number;
|
|
1286
|
+
passing: number;
|
|
1287
|
+
coss_messages: number;
|
|
1288
|
+
coss_passing: number;
|
|
1289
|
+
first_report_at: string | null;
|
|
1290
|
+
last_report_at: string | null;
|
|
1291
|
+
/** The 50 sources with the most messages in the period. */
|
|
1292
|
+
sources: DmarcSource[];
|
|
1293
|
+
};
|
|
1294
|
+
}
|
|
1295
|
+
/** The policy a reporter found when it evaluated the mail. */
|
|
1296
|
+
interface DmarcPolicyPublished {
|
|
1297
|
+
domain: string;
|
|
1298
|
+
p: string | null;
|
|
1299
|
+
sp: string | null;
|
|
1300
|
+
np: string | null;
|
|
1301
|
+
adkim: string | null;
|
|
1302
|
+
aspf: string | null;
|
|
1303
|
+
pct: number | null;
|
|
1304
|
+
testing: string | null;
|
|
1305
|
+
}
|
|
1306
|
+
/** A DMARC aggregate report, without its rows (lists). */
|
|
1307
|
+
interface DmarcReportSummary {
|
|
1308
|
+
object: "dmarc_report";
|
|
1309
|
+
id: string;
|
|
1310
|
+
domain_id: string;
|
|
1311
|
+
reporter: {
|
|
1312
|
+
org_name: string;
|
|
1313
|
+
email: string | null;
|
|
1314
|
+
};
|
|
1315
|
+
/** The reporter's own id of the report. */
|
|
1316
|
+
report_id: string;
|
|
1317
|
+
/** ISO 8601 timestamps. */
|
|
1318
|
+
period_start: string;
|
|
1319
|
+
period_end: string;
|
|
1320
|
+
policy_published: DmarcPolicyPublished;
|
|
1321
|
+
messages: number;
|
|
1322
|
+
passing: number;
|
|
1323
|
+
/** The report listed more rows than are kept (10,000); totals cover the kept rows. */
|
|
1324
|
+
truncated: boolean;
|
|
1325
|
+
/** ISO 8601 timestamp. */
|
|
1326
|
+
received_at: string;
|
|
1327
|
+
}
|
|
1328
|
+
/** One row of a report: messages from one source IP with one outcome. */
|
|
1329
|
+
interface DmarcReportRecord {
|
|
1330
|
+
source_ip: string;
|
|
1331
|
+
count: number;
|
|
1332
|
+
/** What the receiver did with the messages. */
|
|
1333
|
+
disposition: DmarcPolicy;
|
|
1334
|
+
/** Aligned DKIM result. */
|
|
1335
|
+
dkim: "pass" | "fail";
|
|
1336
|
+
/** Aligned SPF result. */
|
|
1337
|
+
spf: "pass" | "fail";
|
|
1338
|
+
dmarc_pass: boolean;
|
|
1339
|
+
header_from: string;
|
|
1340
|
+
envelope_from: string | null;
|
|
1341
|
+
via_coss: boolean;
|
|
1342
|
+
auth_results: {
|
|
1343
|
+
dkim: {
|
|
1344
|
+
domain: string;
|
|
1345
|
+
selector: string | null;
|
|
1346
|
+
result: string;
|
|
1347
|
+
}[];
|
|
1348
|
+
spf: {
|
|
1349
|
+
domain: string;
|
|
1350
|
+
scope: string | null;
|
|
1351
|
+
result: string;
|
|
1352
|
+
}[];
|
|
1353
|
+
};
|
|
1354
|
+
reasons: {
|
|
1355
|
+
type: string;
|
|
1356
|
+
comment: string | null;
|
|
1357
|
+
}[];
|
|
1358
|
+
}
|
|
1359
|
+
/** A DMARC aggregate report with its rows. */
|
|
1360
|
+
interface DmarcReport extends DmarcReportSummary {
|
|
1361
|
+
records: DmarcReportRecord[];
|
|
1362
|
+
}
|
|
1363
|
+
/** Query of `coss.domains.dmarc.reports.list`. */
|
|
1364
|
+
interface ListDmarcReportsParams {
|
|
1365
|
+
/** 1-100, default 20. */
|
|
1366
|
+
limit?: number;
|
|
1367
|
+
/** The `id` of the last report of the previous page. */
|
|
1368
|
+
after?: string;
|
|
1369
|
+
}
|
|
1370
|
+
//#endregion
|
|
1371
|
+
//#region src/resources/dmarc.d.ts
|
|
1372
|
+
type ReadOptions$15 = Pick<RequestOptions, "signal">;
|
|
1373
|
+
/** `coss.domains.dmarc.reports`: the aggregate reports received about a domain. */
|
|
1374
|
+
declare class DmarcReportsResource {
|
|
1375
|
+
#private;
|
|
1376
|
+
/** @internal Use `new Coss().domains.dmarc.reports`. */
|
|
1377
|
+
constructor(http: HttpClient);
|
|
1378
|
+
/** Lists the domain's reports, newest first, without their rows. */
|
|
1379
|
+
list(domainId: string, params?: ListDmarcReportsParams, options?: ReadOptions$15): Promise<CossResult<List<DmarcReportSummary>>>;
|
|
1380
|
+
/** Retrieves one report with its rows. */
|
|
1381
|
+
get(domainId: string, reportId: string, options?: ReadOptions$15): Promise<CossResult<DmarcReport>>;
|
|
1382
|
+
}
|
|
1383
|
+
/**
|
|
1384
|
+
* `coss.domains.dmarc`: a domain's DMARC record, the guided path from `p=none` to `p=reject`, and
|
|
1385
|
+
* the aggregate reports mailbox providers send to its `report_address`.
|
|
1386
|
+
*/
|
|
1387
|
+
declare class DmarcResource {
|
|
1388
|
+
#private;
|
|
1389
|
+
/** The domain's aggregate reports. */
|
|
1390
|
+
readonly reports: DmarcReportsResource;
|
|
1391
|
+
/** @internal Use `new Coss().domains.dmarc`. */
|
|
1392
|
+
constructor(http: HttpClient);
|
|
1393
|
+
/**
|
|
1394
|
+
* The domain's DMARC status: its published record, the record to publish next and whether
|
|
1395
|
+
* the last 14 days of reports say that is safe (`ready`), and a summary of those reports.
|
|
1396
|
+
*/
|
|
1397
|
+
get(domainId: string, options?: ReadOptions$15): Promise<CossResult<DomainDmarc>>;
|
|
1398
|
+
}
|
|
1399
|
+
//#endregion
|
|
1400
|
+
//#region src/resources/receiving-domains.d.ts
|
|
1401
|
+
type DeleteOptions$1 = Pick<RequestOptions, "signal">;
|
|
1402
|
+
/**
|
|
1403
|
+
* `coss.domains.receiving`: a domain's receiving hostname (the domain itself or a subdomain, e.g.
|
|
1404
|
+
* `inbound.acme.com`). Email sent to any address at it is received by the API key's environment.
|
|
1405
|
+
*/
|
|
1406
|
+
declare class ReceivingDomainsResource {
|
|
1407
|
+
#private;
|
|
1408
|
+
/** @internal Use `new Coss().domains.receiving`. */
|
|
1409
|
+
constructor(http: HttpClient);
|
|
1410
|
+
/**
|
|
1411
|
+
* Starts receiving at a hostname of the domain, for the API key's environment, and returns the
|
|
1412
|
+
* domain with the MX record to publish in `data.receiving.record`.
|
|
1413
|
+
*/
|
|
1414
|
+
create(domainId: string, params: CreateReceivingDomainParams, options?: RequestOptions): Promise<CossResult<Domain>>;
|
|
1415
|
+
/** Stops receiving at the domain's hostname. Emails already received are kept. */
|
|
1416
|
+
delete(domainId: string, options?: DeleteOptions$1): Promise<CossResult<Domain>>;
|
|
1417
|
+
}
|
|
1418
|
+
//#endregion
|
|
1419
|
+
//#region src/resources/tracking-domains.d.ts
|
|
1420
|
+
type DeleteOptions = Pick<RequestOptions, "signal">;
|
|
1421
|
+
/**
|
|
1422
|
+
* `coss.domains.tracking`: a domain's custom tracking domain (e.g. `links.acme.com`). Open pixels
|
|
1423
|
+
* and click redirects of emails sent from the domain use it while it is `active`.
|
|
1424
|
+
*/
|
|
1425
|
+
declare class TrackingDomainsResource {
|
|
1426
|
+
#private;
|
|
1427
|
+
/** @internal Use `new Coss().domains.tracking`. */
|
|
1428
|
+
constructor(http: HttpClient);
|
|
1429
|
+
/**
|
|
1430
|
+
* Sets up a subdomain of the domain as its tracking domain and returns the domain, with the
|
|
1431
|
+
* CNAME to publish in `data.tracking.record`. Setup gives up after 72 hours.
|
|
1432
|
+
*/
|
|
1433
|
+
create(domainId: string, params: CreateTrackingDomainParams, options?: RequestOptions): Promise<CossResult<Domain>>;
|
|
1434
|
+
/**
|
|
1435
|
+
* Removes the domain's tracking domain. Later emails use the default tracking host; links in
|
|
1436
|
+
* emails already sent through it stop working.
|
|
1437
|
+
*/
|
|
1438
|
+
delete(domainId: string, options?: DeleteOptions): Promise<CossResult<Domain>>;
|
|
1439
|
+
}
|
|
1440
|
+
//#endregion
|
|
1441
|
+
//#region src/resources/domains.d.ts
|
|
1442
|
+
type ReadOptions$14 = Pick<RequestOptions, "signal">;
|
|
1443
|
+
/**
|
|
1444
|
+
* `coss.domains`: the domains live (`coss_live_…`) keys may send from. Domains belong to the
|
|
1445
|
+
* organization, so every API key of the organization sees the same ones.
|
|
1446
|
+
*/
|
|
1447
|
+
declare class DomainsResource {
|
|
1448
|
+
#private;
|
|
1449
|
+
/** Each domain's custom tracking domain: add and remove it. */
|
|
1450
|
+
readonly tracking: TrackingDomainsResource;
|
|
1451
|
+
/** Each domain's receiving hostname: start and stop receiving email at it. */
|
|
1452
|
+
readonly receiving: ReceivingDomainsResource;
|
|
1453
|
+
/** Each domain's DMARC status, guidance and aggregate reports. */
|
|
1454
|
+
readonly dmarc: DmarcResource;
|
|
1455
|
+
/** @internal Use `new Coss().domains`. */
|
|
1456
|
+
constructor(http: HttpClient);
|
|
1457
|
+
/**
|
|
1458
|
+
* Adds a domain and returns the DNS records to publish (`data.records`). The records are
|
|
1459
|
+
* checked in the background; verification gives up after 72 hours.
|
|
1460
|
+
*/
|
|
1461
|
+
create(params: CreateDomainParams, options?: RequestOptions): Promise<CossResult<Domain>>;
|
|
1462
|
+
/** Lists the organization's domains, ordered by name. */
|
|
1463
|
+
list(options?: ReadOptions$14): Promise<CossResult<List<Domain>>>;
|
|
1464
|
+
/** Retrieves a domain with the result of the last DNS check. */
|
|
1465
|
+
get(id: string, options?: ReadOptions$14): Promise<CossResult<Domain>>;
|
|
1466
|
+
/**
|
|
1467
|
+
* Checks the domain's records now instead of waiting for the next background check. A `failed`
|
|
1468
|
+
* domain starts verification over with fresh DKIM records, which have to be published again.
|
|
1469
|
+
* Its tracking domain, if any, is checked too.
|
|
1470
|
+
*/
|
|
1471
|
+
verify(id: string, options?: RequestOptions): Promise<CossResult<Domain>>;
|
|
1472
|
+
/** Removes the domain. Emails already sent are unaffected; live keys can no longer use it. */
|
|
1473
|
+
delete(id: string, options?: ReadOptions$14): Promise<CossResult<DeletedDomain>>;
|
|
1474
|
+
}
|
|
1475
|
+
//#endregion
|
|
1476
|
+
//#region src/types/dedicated-ip.d.ts
|
|
1477
|
+
/** Dedicated IP wire types (hand-written mirrors of the API's `DedicatedIpPool` schema). */
|
|
1478
|
+
type DedicatedIpPoolStatus = "not_enabled" | "waiting" | "provisioning" | "warming" | "ready" | "releasing";
|
|
1479
|
+
/** `GET /v1/dedicated_ips`: the organization's dedicated IPs (the Dedicated IPs add-on). */
|
|
1480
|
+
interface DedicatedIpPool {
|
|
1481
|
+
object: "dedicated_ip_pool";
|
|
1482
|
+
/**
|
|
1483
|
+
* `warming`: live emails go through the pool while its IPs warm up (what they can't take yet
|
|
1484
|
+
* leaves from shared IPs); `ready`: at least 95% of the last 7 days' deliveries left from them.
|
|
1485
|
+
*/
|
|
1486
|
+
status: DedicatedIpPoolStatus;
|
|
1487
|
+
/** The pool's IPs, with their deliveries in the last 7 days. */
|
|
1488
|
+
ips: {
|
|
1489
|
+
ip: string;
|
|
1490
|
+
delivered_7d: number;
|
|
1491
|
+
}[];
|
|
1492
|
+
/** Share (0–1) of the last 7 days' deliveries from the pool's IPs; `null` below 1,000. */
|
|
1493
|
+
dedicated_share: number | null;
|
|
1494
|
+
/** What is holding the pool up, if anything. */
|
|
1495
|
+
message: string | null;
|
|
1496
|
+
created_at: string | null;
|
|
1497
|
+
/** When it was first `ready`. */
|
|
1498
|
+
ready_at: string | null;
|
|
1499
|
+
}
|
|
1500
|
+
//#endregion
|
|
1501
|
+
//#region src/resources/dedicated-ips.d.ts
|
|
1502
|
+
type ReadOptions$13 = Pick<RequestOptions, "signal">;
|
|
1503
|
+
/**
|
|
1504
|
+
* `coss.email.dedicatedIps`: the organization's own sending IPs (the Dedicated IPs add-on),
|
|
1505
|
+
* managed and warmed up automatically.
|
|
1506
|
+
*/
|
|
1507
|
+
declare class DedicatedIpsResource {
|
|
1508
|
+
#private;
|
|
1509
|
+
/** @internal Use `new Coss().email.dedicatedIps`. */
|
|
1510
|
+
constructor(http: HttpClient);
|
|
1511
|
+
/** The pool's status and IPs (`not_enabled` without the add-on). */
|
|
1512
|
+
get(options?: ReadOptions$13): Promise<CossResult<DedicatedIpPool>>;
|
|
1513
|
+
}
|
|
1514
|
+
//#endregion
|
|
1515
|
+
//#region src/resources/email-templates.d.ts
|
|
1516
|
+
type ReadOptions$12 = Pick<RequestOptions, "signal">;
|
|
1517
|
+
/** `coss.email.templates.versions`: a template's published versions. */
|
|
1518
|
+
declare class EmailTemplateVersionsResource {
|
|
1519
|
+
#private;
|
|
1520
|
+
/** @internal Use `new Coss().email.templates.versions`. */
|
|
1521
|
+
constructor(http: HttpClient);
|
|
1522
|
+
/** Published versions, newest first. */
|
|
1523
|
+
list(template: string, params?: ListEmailTemplateVersionsParams, options?: ReadOptions$12): Promise<CossResult<List<EmailTemplateVersion>>>;
|
|
1524
|
+
get(template: string, version: number, options?: ReadOptions$12): Promise<CossResult<EmailTemplateVersion>>;
|
|
1525
|
+
/**
|
|
1526
|
+
* Replaces the draft with this version's content; publish the draft to send it again. Never
|
|
1527
|
+
* automatically retried: every restore is a new draft revision, so a repeat could overwrite an
|
|
1528
|
+
* edit saved in between.
|
|
1529
|
+
*/
|
|
1530
|
+
restore(template: string, version: number, options?: ReadOptions$12): Promise<CossResult<EmailTemplateVersion>>;
|
|
1531
|
+
}
|
|
1532
|
+
/**
|
|
1533
|
+
* `coss.email.templates`: the environment's email templates. Templates are addressed by id or
|
|
1534
|
+
* alias. Edit the draft, publish it, then send with `coss.email.send({ template_id, variables })`.
|
|
1535
|
+
*/
|
|
1536
|
+
declare class EmailTemplatesResource {
|
|
1537
|
+
#private;
|
|
1538
|
+
/** Published versions. */
|
|
1539
|
+
readonly versions: EmailTemplateVersionsResource;
|
|
1540
|
+
/** @internal Use `new Coss().email.templates`. */
|
|
1541
|
+
constructor(http: HttpClient);
|
|
1542
|
+
/**
|
|
1543
|
+
* Creates a template and its draft. Never automatically retried: the API doesn't deduplicate it
|
|
1544
|
+
* (a template with an `alias` can't be created twice, though).
|
|
1545
|
+
*/
|
|
1546
|
+
create(params: CreateEmailTemplateParams, options?: RequestOptions): Promise<CossResult<EmailTemplate>>;
|
|
1547
|
+
/** The environment's templates, newest first. */
|
|
1548
|
+
list(params?: ListEmailTemplatesParams, options?: ReadOptions$12): Promise<CossResult<List<EmailTemplate>>>;
|
|
1549
|
+
get(template: string, options?: ReadOptions$12): Promise<CossResult<EmailTemplate>>;
|
|
1550
|
+
/** Changes its name, alias or description. */
|
|
1551
|
+
update(template: string, params: UpdateEmailTemplateParams, options?: ReadOptions$12): Promise<CossResult<EmailTemplate>>;
|
|
1552
|
+
/** Deletes it with every version. Emails already sent keep their content. */
|
|
1553
|
+
delete(template: string, options?: ReadOptions$12): Promise<CossResult<DeletedEmailTemplate>>;
|
|
1554
|
+
/** The draft, with `problems` that keep it from being published. */
|
|
1555
|
+
getDraft(template: string, options?: ReadOptions$12): Promise<CossResult<EmailTemplateVersion>>;
|
|
1556
|
+
/**
|
|
1557
|
+
* Replaces the whole draft. Sends keep using the published version until you publish. Never
|
|
1558
|
+
* automatically retried: every save is a new revision, so a repeat whose first attempt was saved
|
|
1559
|
+
* would fail with `template_revision_mismatch` (or, without `revision`, overwrite an edit saved
|
|
1560
|
+
* in between). Read the draft again before retrying.
|
|
1561
|
+
*/
|
|
1562
|
+
updateDraft(template: string, params: UpdateEmailTemplateDraftParams, options?: ReadOptions$12): Promise<CossResult<EmailTemplateVersion>>;
|
|
1563
|
+
/**
|
|
1564
|
+
* Publishes the draft as the next version, which sends use from then on. Automatically retried
|
|
1565
|
+
* only with a `revision`: a draft without changes since the last publish returns that version,
|
|
1566
|
+
* and one saved again since is refused. Without it, a retry could publish someone else's newer
|
|
1567
|
+
* edits as yet another version.
|
|
1568
|
+
*/
|
|
1569
|
+
publish(template: string, params?: PublishEmailTemplateParams, options?: ReadOptions$12): Promise<CossResult<EmailTemplateVersion>>;
|
|
1570
|
+
}
|
|
1571
|
+
//#endregion
|
|
1572
|
+
//#region src/types/received-email.d.ts
|
|
1573
|
+
/**
|
|
1574
|
+
* Received (inbound) email wire types. Hand-written to mirror the API's snake_case JSON 1:1 (the
|
|
1575
|
+
* API's contract test asserts they stay assignable to and from its zod schemas).
|
|
1576
|
+
*/
|
|
1577
|
+
/** `received`, or `blocked` when the message carried a virus (only its envelope is kept). */
|
|
1578
|
+
type ReceivedEmailStatus = "received" | "blocked";
|
|
1579
|
+
/** What the receiving server concluded; `null` when the check did not run. */
|
|
1580
|
+
type VerdictStatus = "pass" | "fail" | "gray" | "processing_failed";
|
|
1581
|
+
interface ReceivedEmailVerdicts {
|
|
1582
|
+
spam: VerdictStatus | null;
|
|
1583
|
+
virus: VerdictStatus | null;
|
|
1584
|
+
spf: VerdictStatus | null;
|
|
1585
|
+
dkim: VerdictStatus | null;
|
|
1586
|
+
dmarc: VerdictStatus | null;
|
|
1587
|
+
/** The sender domain's DMARC policy (`none`, `quarantine`, `reject`) when DMARC failed. */
|
|
1588
|
+
dmarc_policy: string | null;
|
|
1589
|
+
}
|
|
1590
|
+
/** Metadata of an attachment; download it with `email.received.getAttachment`. */
|
|
1591
|
+
interface ReceivedEmailAttachment {
|
|
1592
|
+
id: string;
|
|
1593
|
+
/** `null` when the part named none. */
|
|
1594
|
+
filename: string | null;
|
|
1595
|
+
content_type: string;
|
|
1596
|
+
/** Set for parts the HTML references (`cid:` URLs). */
|
|
1597
|
+
content_id: string | null;
|
|
1598
|
+
disposition: "attachment" | "inline";
|
|
1599
|
+
/** Size in bytes. */
|
|
1600
|
+
size: number;
|
|
1601
|
+
}
|
|
1602
|
+
/** A received email as lists return it: without bodies and headers. */
|
|
1603
|
+
interface ReceivedEmailSummary {
|
|
1604
|
+
object: "received_email";
|
|
1605
|
+
id: string;
|
|
1606
|
+
status: ReceivedEmailStatus;
|
|
1607
|
+
blocked_reason: "virus" | null;
|
|
1608
|
+
/** The envelope sender (`MAIL FROM`); empty for bounces. */
|
|
1609
|
+
mail_from: string;
|
|
1610
|
+
/** The envelope recipients this environment received it for (Bcc'd addresses included). */
|
|
1611
|
+
recipients: string[];
|
|
1612
|
+
/** The `From` header. */
|
|
1613
|
+
from: string | null;
|
|
1614
|
+
to: string[];
|
|
1615
|
+
cc: string[];
|
|
1616
|
+
subject: string | null;
|
|
1617
|
+
/** The `Message-ID` header. */
|
|
1618
|
+
message_id: string | null;
|
|
1619
|
+
attachments: ReceivedEmailAttachment[];
|
|
1620
|
+
/** Size of the raw message in bytes. */
|
|
1621
|
+
size: number;
|
|
1622
|
+
/** Whether the spam verdict is `fail`. */
|
|
1623
|
+
spam: boolean;
|
|
1624
|
+
verdicts: ReceivedEmailVerdicts;
|
|
1625
|
+
/** Whether a sandbox environment received it. */
|
|
1626
|
+
sandbox: boolean;
|
|
1627
|
+
/** ISO 8601 timestamp. */
|
|
1628
|
+
received_at: string;
|
|
1629
|
+
}
|
|
1630
|
+
/** A received email with its headers and bodies. HTML is the sender's: sanitize it to show it. */
|
|
1631
|
+
interface ReceivedEmail extends ReceivedEmailSummary {
|
|
1632
|
+
reply_to: string[];
|
|
1633
|
+
in_reply_to: string | null;
|
|
1634
|
+
/** Message ids of the `References` header. */
|
|
1635
|
+
references: string[];
|
|
1636
|
+
/** The `Date` header, when valid (ISO 8601). */
|
|
1637
|
+
sent_at: string | null;
|
|
1638
|
+
/** Every header in message order, duplicates included. */
|
|
1639
|
+
headers: {
|
|
1640
|
+
name: string;
|
|
1641
|
+
value: string;
|
|
1642
|
+
}[];
|
|
1643
|
+
text: string | null;
|
|
1644
|
+
html: string | null;
|
|
1645
|
+
/** Whether `text`, `html` or `headers` were shortened; `getRaw` always has everything. */
|
|
1646
|
+
truncated: boolean;
|
|
1647
|
+
}
|
|
1648
|
+
/** Query of `email.received.list`. */
|
|
1649
|
+
interface ListReceivedEmailsParams {
|
|
1650
|
+
/** 1-100, default 20. */
|
|
1651
|
+
limit?: number;
|
|
1652
|
+
/** The `id` of the last email of the previous page. */
|
|
1653
|
+
after?: string;
|
|
1654
|
+
}
|
|
1655
|
+
/** Returned by `email.received.delete`. */
|
|
1656
|
+
interface DeletedReceivedEmail {
|
|
1657
|
+
object: "received_email";
|
|
1658
|
+
id: string;
|
|
1659
|
+
deleted: true;
|
|
1660
|
+
}
|
|
1661
|
+
/** The environment's own domain under coss.com's inbound domain: any address at it is received. */
|
|
1662
|
+
interface InboundAddress {
|
|
1663
|
+
object: "inbound_address";
|
|
1664
|
+
environment_id: string;
|
|
1665
|
+
domain: string;
|
|
1666
|
+
}
|
|
1667
|
+
//#endregion
|
|
1668
|
+
//#region src/resources/received-emails.d.ts
|
|
1669
|
+
type ReadOptions$11 = Pick<RequestOptions, "signal">;
|
|
1670
|
+
/**
|
|
1671
|
+
* `coss.email.received`: emails received by the API key's environment, at its inbound address
|
|
1672
|
+
* (`address()`) or at a receiving domain (`coss.domains.receiving`). An `email.received` webhook
|
|
1673
|
+
* announces each one.
|
|
1674
|
+
*/
|
|
1675
|
+
declare class ReceivedEmailsResource {
|
|
1676
|
+
#private;
|
|
1677
|
+
/** @internal Use `new Coss().email.received`. */
|
|
1678
|
+
constructor(http: HttpClient);
|
|
1679
|
+
/** Lists received emails, newest first, without bodies. Pass the last `id` as `after` while `has_more` is true. */
|
|
1680
|
+
list(params?: ListReceivedEmailsParams, options?: ReadOptions$11): Promise<CossResult<List<ReceivedEmailSummary>>>;
|
|
1681
|
+
/** Retrieves a received email with its headers and bodies. */
|
|
1682
|
+
get(id: string, options?: ReadOptions$11): Promise<CossResult<ReceivedEmail>>;
|
|
1683
|
+
/** The whole message as received (`message/rfc822` bytes). */
|
|
1684
|
+
getRaw(id: string, options?: ReadOptions$11): Promise<CossResult<Uint8Array>>;
|
|
1685
|
+
/** An attachment's bytes (untrusted: its declared type is the attachment's `content_type`). */
|
|
1686
|
+
getAttachment(id: string, attachmentId: string, options?: ReadOptions$11): Promise<CossResult<Uint8Array>>;
|
|
1687
|
+
/**
|
|
1688
|
+
* The environment's inbound domain: email to any address at it (`support@<domain>`) is
|
|
1689
|
+
* received, with no DNS setup.
|
|
1690
|
+
*/
|
|
1691
|
+
address(options?: ReadOptions$11): Promise<CossResult<InboundAddress>>;
|
|
1692
|
+
/** Deletes a received email with its raw message and attachments right away. */
|
|
1693
|
+
delete(id: string, options?: ReadOptions$11): Promise<CossResult<DeletedReceivedEmail>>;
|
|
1694
|
+
}
|
|
1695
|
+
//#endregion
|
|
1696
|
+
//#region src/resources/suppressions.d.ts
|
|
1697
|
+
type ReadOptions$10 = Pick<RequestOptions, "signal">;
|
|
1698
|
+
/**
|
|
1699
|
+
* `coss.email.suppressions`: the suppression list of the API key's environment. Sends skip
|
|
1700
|
+
* suppressed recipients; permanent bounces and complaints are added automatically.
|
|
1701
|
+
*/
|
|
1702
|
+
declare class SuppressionResource {
|
|
1703
|
+
#private;
|
|
1704
|
+
/** @internal Use `new Coss().email.suppressions`. */
|
|
1705
|
+
constructor(http: HttpClient);
|
|
1706
|
+
/**
|
|
1707
|
+
* Suppresses an address for every email (`scope: "*"`, the default) or for one category, e.g.
|
|
1708
|
+
* when a recipient unsubscribes. Returns the existing entry if there already is one.
|
|
1709
|
+
*/
|
|
1710
|
+
add(params: CreateSuppressionParams, options?: RequestOptions): Promise<CossResult<Suppression>>;
|
|
1711
|
+
/**
|
|
1712
|
+
* Adds many entries at once (reason `import`), 1,000 per request. Invalid entries are skipped
|
|
1713
|
+
* and reported in `invalid`; entries already on the list count as `existing`. If a request
|
|
1714
|
+
* fails, the earlier batches stay imported: importing everything again is safe.
|
|
1715
|
+
*/
|
|
1716
|
+
import(params: ImportSuppressionsParams, options?: ReadOptions$10): Promise<CossResult<SuppressionImport>>;
|
|
1717
|
+
/**
|
|
1718
|
+
* The whole list as CSV (`address,scope,reason,created_at,email_id,id`, oldest first), which
|
|
1719
|
+
* `import` (or the dashboard) accepts again.
|
|
1720
|
+
*/
|
|
1721
|
+
export(params?: ExportSuppressionsParams, options?: ReadOptions$10): Promise<CossResult<string>>;
|
|
1722
|
+
/** Lists entries, newest first. Pass the last `id` as `after` while `has_more` is true. */
|
|
1723
|
+
list(params?: ListSuppressionsParams, options?: ReadOptions$10): Promise<CossResult<List<Suppression>>>;
|
|
1724
|
+
/** Whether a send to `address` (with `category`, if given) would skip it. */
|
|
1725
|
+
check(params: CheckSuppressionParams, options?: ReadOptions$10): Promise<CossResult<SuppressionCheck>>;
|
|
1726
|
+
/** Retrieves one entry. */
|
|
1727
|
+
get(id: string, options?: ReadOptions$10): Promise<CossResult<Suppression>>;
|
|
1728
|
+
/** Removes an entry, so later sends reach the address again (e.g. when a recipient resubscribes). */
|
|
1729
|
+
remove(id: string, options?: ReadOptions$10): Promise<CossResult<DeletedSuppression>>;
|
|
1730
|
+
}
|
|
1731
|
+
//#endregion
|
|
1732
|
+
//#region src/types/tracking.d.ts
|
|
1733
|
+
/** Tracking settings wire types (hand-written mirrors of the API's schemas). */
|
|
1734
|
+
/** An environment's tracking default (`category: null`) or the rule for one category. */
|
|
1735
|
+
interface TrackingRule {
|
|
1736
|
+
object: "tracking_rule";
|
|
1737
|
+
id: string;
|
|
1738
|
+
/** The category the rule applies to; `null` for the environment default. */
|
|
1739
|
+
category: string | null;
|
|
1740
|
+
/** Whether opens are tracked. */
|
|
1741
|
+
opens: boolean;
|
|
1742
|
+
/** Whether clicks are tracked. */
|
|
1743
|
+
clicks: boolean;
|
|
1744
|
+
/**
|
|
1745
|
+
* Whether emails get one-click unsubscribe headers (only emails with a category and a single
|
|
1746
|
+
* recipient).
|
|
1747
|
+
*/
|
|
1748
|
+
unsubscribe: boolean;
|
|
1749
|
+
/** ISO 8601 timestamp. */
|
|
1750
|
+
created_at: string;
|
|
1751
|
+
/** ISO 8601 timestamp. */
|
|
1752
|
+
updated_at: string;
|
|
1753
|
+
}
|
|
1754
|
+
/**
|
|
1755
|
+
* Open and click tracking and one-click unsubscribe settings of the API key's environment. For
|
|
1756
|
+
* each of `opens`, `clicks` and `unsubscribe`, a send's own `tracking` wins, then its category's
|
|
1757
|
+
* rule, then `default`, then off.
|
|
1758
|
+
*/
|
|
1759
|
+
interface TrackingSettings {
|
|
1760
|
+
object: "tracking_settings";
|
|
1761
|
+
/** The environment default; `null` when none is set. */
|
|
1762
|
+
default: TrackingRule | null;
|
|
1763
|
+
/** Category rules, by category name. */
|
|
1764
|
+
categories: TrackingRule[];
|
|
1765
|
+
}
|
|
1766
|
+
/**
|
|
1767
|
+
* Body of `PATCH /v1/tracking_settings/default` and `…/categories/{category}`: at least one
|
|
1768
|
+
* field. Fields left out keep their value; a new rule starts with all off.
|
|
1769
|
+
*/
|
|
1770
|
+
interface UpdateTrackingRuleParams {
|
|
1771
|
+
opens?: boolean;
|
|
1772
|
+
clicks?: boolean;
|
|
1773
|
+
/** Add one-click unsubscribe headers to emails with a category and a single recipient. */
|
|
1774
|
+
unsubscribe?: boolean;
|
|
1775
|
+
}
|
|
1776
|
+
/** Returned when a rule is removed. */
|
|
1777
|
+
interface DeletedTrackingRule {
|
|
1778
|
+
object: "tracking_rule";
|
|
1779
|
+
id: string;
|
|
1780
|
+
category: string | null;
|
|
1781
|
+
deleted: true;
|
|
1782
|
+
}
|
|
1783
|
+
//#endregion
|
|
1784
|
+
//#region src/resources/tracking.d.ts
|
|
1785
|
+
type ReadOptions$9 = Pick<RequestOptions, "signal">;
|
|
1786
|
+
/**
|
|
1787
|
+
* `coss.email.tracking`: which emails of the API key's environment have their opens and clicks
|
|
1788
|
+
* tracked and get one-click unsubscribe headers. Emails keep the settings that applied when they
|
|
1789
|
+
* were sent; a send's own `tracking` option wins over them.
|
|
1790
|
+
*/
|
|
1791
|
+
declare class TrackingResource {
|
|
1792
|
+
#private;
|
|
1793
|
+
/** @internal Use `new Coss().email.tracking`. */
|
|
1794
|
+
constructor(http: HttpClient);
|
|
1795
|
+
/** The environment default and the category rules. */
|
|
1796
|
+
get(options?: ReadOptions$9): Promise<CossResult<TrackingSettings>>;
|
|
1797
|
+
/**
|
|
1798
|
+
* Sets the environment default, which applies to emails without a rule for their category.
|
|
1799
|
+
* Fields left out keep their value; a new default starts with both off.
|
|
1800
|
+
*/
|
|
1801
|
+
updateDefault(params: UpdateTrackingRuleParams, options?: ReadOptions$9): Promise<CossResult<TrackingRule>>;
|
|
1802
|
+
/** Removes the environment default: emails without a category rule are then not tracked. */
|
|
1803
|
+
removeDefault(options?: ReadOptions$9): Promise<CossResult<DeletedTrackingRule>>;
|
|
1804
|
+
/**
|
|
1805
|
+
* Sets the rule for emails sent with `category`, which wins over the default. Fields left out
|
|
1806
|
+
* keep their value; a new rule starts with both off.
|
|
1807
|
+
*/
|
|
1808
|
+
updateCategory(category: string, params: UpdateTrackingRuleParams, options?: ReadOptions$9): Promise<CossResult<TrackingRule>>;
|
|
1809
|
+
/** Removes a category's rule: its emails follow the environment default again. */
|
|
1810
|
+
removeCategory(category: string, options?: ReadOptions$9): Promise<CossResult<DeletedTrackingRule>>;
|
|
1811
|
+
}
|
|
1812
|
+
//#endregion
|
|
1813
|
+
//#region src/resources/email.d.ts
|
|
1814
|
+
/** `coss.email`: transactional email. */
|
|
1815
|
+
declare class EmailResource {
|
|
1816
|
+
#private;
|
|
1817
|
+
/** The environment's suppression list. */
|
|
1818
|
+
readonly suppressions: SuppressionResource;
|
|
1819
|
+
/** The environment's open and click tracking settings. */
|
|
1820
|
+
readonly tracking: TrackingResource;
|
|
1821
|
+
/** Emails the environment received. */
|
|
1822
|
+
readonly received: ReceivedEmailsResource;
|
|
1823
|
+
/** The environment's email templates. */
|
|
1824
|
+
readonly templates: EmailTemplatesResource;
|
|
1825
|
+
/** The organization's dedicated IPs. */
|
|
1826
|
+
readonly dedicatedIps: DedicatedIpsResource;
|
|
1827
|
+
/** @internal Use `new Coss().email`. */
|
|
1828
|
+
constructor(http: HttpClient);
|
|
1829
|
+
/**
|
|
1830
|
+
* Sends an email, with its own subject and body or from a published template (`template_id`
|
|
1831
|
+
* and `variables`). It is returned `queued` and handed to the delivery provider moments later:
|
|
1832
|
+
* `get` it or listen for the `email.sent` / `email.failed` webhooks for the outcome. Safe to
|
|
1833
|
+
* retry: the request always carries an `Idempotency-Key` (yours, or a generated one reused
|
|
1834
|
+
* across automatic retries), so the API never sends it twice. A `react` component is rendered
|
|
1835
|
+
* once, before the first attempt.
|
|
1836
|
+
*/
|
|
1837
|
+
send(params: SendEmailParams, options?: RequestOptions): Promise<CossResult<Email>>;
|
|
1838
|
+
/**
|
|
1839
|
+
* Sends up to 100 emails in one request, each as `send` would. The batch is all or nothing: if
|
|
1840
|
+
* any email is invalid (the error's `issues` name it, e.g. `emails.3.to`), none is sent. Its
|
|
1841
|
+
* recipients count against the send quota together. Safe to retry: one `Idempotency-Key` covers
|
|
1842
|
+
* the whole batch. Larger lists need several calls, each with its own key.
|
|
1843
|
+
*/
|
|
1844
|
+
sendBatch(emails: SendEmailParams[], options?: RequestOptions): Promise<CossResult<EmailBatch>>;
|
|
1845
|
+
/** Retrieves a batch sent by `sendBatch`, with its emails' current statuses in request order. */
|
|
1846
|
+
getBatch(id: string, options?: Pick<RequestOptions, "signal">): Promise<CossResult<EmailBatch>>;
|
|
1847
|
+
/** Retrieves an email sent from the same environment as the API key. */
|
|
1848
|
+
get(id: string, options?: Pick<RequestOptions, "signal">): Promise<CossResult<Email>>;
|
|
1849
|
+
/**
|
|
1850
|
+
* Lists emails sent from the same environment as the API key, newest first and without their
|
|
1851
|
+
* content (`get` one for `html`, `text`, `headers` and `attachments`). Pass the last `id` as
|
|
1852
|
+
* `after` while `has_more` is true.
|
|
1853
|
+
*/
|
|
1854
|
+
list(params?: ListEmailsParams, options?: Pick<RequestOptions, "signal">): Promise<CossResult<List<EmailSummary>>>;
|
|
1855
|
+
/**
|
|
1856
|
+
* Cancels a scheduled email. Canceling an already canceled email returns it; any other email
|
|
1857
|
+
* fails with `email_not_cancelable`.
|
|
1858
|
+
*/
|
|
1859
|
+
cancel(id: string, options?: Pick<RequestOptions, "signal">): Promise<CossResult<Email>>;
|
|
1860
|
+
/**
|
|
1861
|
+
* Moves a scheduled email to a new time and records an `email.rescheduled` event. The time it
|
|
1862
|
+
* already has returns it unchanged; an email that is no longer scheduled fails with
|
|
1863
|
+
* `email_not_reschedulable`.
|
|
1864
|
+
*/
|
|
1865
|
+
reschedule(id: string, params: RescheduleEmailParams, options?: Pick<RequestOptions, "signal">): Promise<CossResult<Email>>;
|
|
1866
|
+
/** Lists an email's delivery events, oldest first. */
|
|
1867
|
+
listEvents(id: string, options?: Pick<RequestOptions, "signal">): Promise<CossResult<List<EmailEvent>>>;
|
|
1868
|
+
/** Lists the links tracked for clicks in an email, in document order, with click counts. */
|
|
1869
|
+
listLinks(id: string, options?: Pick<RequestOptions, "signal">): Promise<CossResult<List<EmailLink>>>;
|
|
1870
|
+
}
|
|
1871
|
+
//#endregion
|
|
1872
|
+
//#region src/resources/environment.d.ts
|
|
1873
|
+
type ReadOptions$8 = Pick<RequestOptions, "signal">;
|
|
1874
|
+
/** `coss.environment`: which environment, project and organization the API key belongs to. */
|
|
1875
|
+
declare class EnvironmentResource {
|
|
1876
|
+
#private;
|
|
1877
|
+
/** @internal Use `new Coss().environment`. */
|
|
1878
|
+
constructor(http: HttpClient);
|
|
1879
|
+
/** The API key's environment, its project and organization, and the key itself. */
|
|
1880
|
+
get(options?: ReadOptions$8): Promise<CossResult<Environment>>;
|
|
1881
|
+
}
|
|
1882
|
+
//#endregion
|
|
1883
|
+
//#region src/types/hooks.d.ts
|
|
1884
|
+
/**
|
|
1885
|
+
* Hooks wire types (webhooks as a service): you send a message to one of your applications once,
|
|
1886
|
+
* coss.com delivers it to every endpoint its users registered, signed, with retries.
|
|
1887
|
+
*/
|
|
1888
|
+
/** One of your customers (or users), with their own endpoints and portal. */
|
|
1889
|
+
interface HookApplication {
|
|
1890
|
+
object: "hook_application";
|
|
1891
|
+
id: string;
|
|
1892
|
+
/** Your own id for it, unique in the environment; every method that takes an application accepts it. */
|
|
1893
|
+
uid: string | null;
|
|
1894
|
+
name: string;
|
|
1895
|
+
metadata: Record<string, string>;
|
|
1896
|
+
/** ISO 8601 timestamp. */
|
|
1897
|
+
created_at: string;
|
|
1898
|
+
updated_at: string;
|
|
1899
|
+
}
|
|
1900
|
+
/** Body of `POST /v1/hooks/applications`. */
|
|
1901
|
+
interface CreateHookApplicationParams {
|
|
1902
|
+
/** Shown to the application's users in the portal. */
|
|
1903
|
+
name: string;
|
|
1904
|
+
/** Your own id for it (1-256 letters, digits and `. _ : @ | -`). */
|
|
1905
|
+
uid?: string;
|
|
1906
|
+
/** Up to 16 keys (up to 40 characters) with string values (up to 500). */
|
|
1907
|
+
metadata?: Record<string, string>;
|
|
1908
|
+
}
|
|
1909
|
+
/** Body of `PATCH /v1/hooks/applications/{application}`. Omitted fields keep their value. */
|
|
1910
|
+
interface UpdateHookApplicationParams {
|
|
1911
|
+
name?: string;
|
|
1912
|
+
/** `null` removes it. */
|
|
1913
|
+
uid?: string | null;
|
|
1914
|
+
/** Replaces the metadata. */
|
|
1915
|
+
metadata?: Record<string, string>;
|
|
1916
|
+
}
|
|
1917
|
+
/** Query of `GET /v1/hooks/applications`. */
|
|
1918
|
+
interface ListHookApplicationsParams {
|
|
1919
|
+
/** 1-100, default 50. */
|
|
1920
|
+
limit?: number;
|
|
1921
|
+
/** Cursor: the `id` of the last application of the previous page. */
|
|
1922
|
+
after?: string;
|
|
1923
|
+
}
|
|
1924
|
+
/** Returned by `hooks.applications.delete`. */
|
|
1925
|
+
interface DeletedHookApplication {
|
|
1926
|
+
object: "hook_application";
|
|
1927
|
+
id: string;
|
|
1928
|
+
deleted: true;
|
|
1929
|
+
}
|
|
1930
|
+
/** A type of message you send (e.g. `invoice.paid`): the catalog your users subscribe from. */
|
|
1931
|
+
interface HookEventType {
|
|
1932
|
+
object: "hook_event_type";
|
|
1933
|
+
name: string;
|
|
1934
|
+
description: string | null;
|
|
1935
|
+
/** A JSON Schema of the payload, shown to your users (not enforced). */
|
|
1936
|
+
schema: Record<string, unknown> | null;
|
|
1937
|
+
/** Example payloads; the first is what a test send delivers. */
|
|
1938
|
+
examples: Record<string, unknown>[];
|
|
1939
|
+
/** Hidden from the portal and new subscriptions; already subscribed endpoints still receive it. */
|
|
1940
|
+
archived: boolean;
|
|
1941
|
+
created_at: string;
|
|
1942
|
+
updated_at: string;
|
|
1943
|
+
}
|
|
1944
|
+
/** Body of `POST /v1/hooks/event_types`. */
|
|
1945
|
+
interface CreateHookEventTypeParams {
|
|
1946
|
+
/** 1-64 letters, digits and `. _ -`. */
|
|
1947
|
+
name: string;
|
|
1948
|
+
description?: string;
|
|
1949
|
+
schema?: Record<string, unknown>;
|
|
1950
|
+
/** Up to 5. */
|
|
1951
|
+
examples?: Record<string, unknown>[];
|
|
1952
|
+
}
|
|
1953
|
+
/** Body of `PATCH /v1/hooks/event_types/{name}`. */
|
|
1954
|
+
interface UpdateHookEventTypeParams {
|
|
1955
|
+
description?: string | null;
|
|
1956
|
+
schema?: Record<string, unknown> | null;
|
|
1957
|
+
examples?: Record<string, unknown>[];
|
|
1958
|
+
/** `false` restores an archived type. */
|
|
1959
|
+
archived?: boolean;
|
|
1960
|
+
}
|
|
1961
|
+
/** Query of `GET /v1/hooks/event_types`. */
|
|
1962
|
+
interface ListHookEventTypesParams {
|
|
1963
|
+
/** Also list archived types. */
|
|
1964
|
+
include_archived?: boolean;
|
|
1965
|
+
/** 1-100, default 50. */
|
|
1966
|
+
limit?: number;
|
|
1967
|
+
/** Cursor: the `name` of the last type of the previous page. */
|
|
1968
|
+
after?: string;
|
|
1969
|
+
}
|
|
1970
|
+
/** Why an endpoint is disabled. */
|
|
1971
|
+
type HookEndpointDisabledReason = "manual" | "failing";
|
|
1972
|
+
/** A URL of an application's user that receives its messages, signed with its own secret. */
|
|
1973
|
+
interface HookEndpoint {
|
|
1974
|
+
object: "hook_endpoint";
|
|
1975
|
+
id: string;
|
|
1976
|
+
application_id: string;
|
|
1977
|
+
url: string;
|
|
1978
|
+
description: string | null;
|
|
1979
|
+
/** Event types delivered; empty means every type. */
|
|
1980
|
+
filter_types: string[];
|
|
1981
|
+
rate_limit_per_second: number | null;
|
|
1982
|
+
enabled: boolean;
|
|
1983
|
+
/** `manual`, or `failing` (its deliveries failed every attempt for five days); `null` while enabled. */
|
|
1984
|
+
disabled_reason: HookEndpointDisabledReason | null;
|
|
1985
|
+
disabled_at: string | null;
|
|
1986
|
+
/** When its current run of failed deliveries began; `null` while healthy. */
|
|
1987
|
+
failing_since: string | null;
|
|
1988
|
+
/** After a secret roll, requests are also signed with the previous secret until then. */
|
|
1989
|
+
previous_secret_expires_at: string | null;
|
|
1990
|
+
metadata: Record<string, string>;
|
|
1991
|
+
created_at: string;
|
|
1992
|
+
updated_at: string;
|
|
1993
|
+
}
|
|
1994
|
+
/** A created endpoint, or one whose secret was just rolled. */
|
|
1995
|
+
interface HookEndpointWithSecret extends HookEndpoint {
|
|
1996
|
+
/** The `whsec_…` signing secret (Standard Webhooks). */
|
|
1997
|
+
secret: string;
|
|
1998
|
+
}
|
|
1999
|
+
/** Body of `POST /v1/hooks/applications/{application}/endpoints`. */
|
|
2000
|
+
interface CreateHookEndpointParams {
|
|
2001
|
+
/** An `https://` URL. */
|
|
2002
|
+
url: string;
|
|
2003
|
+
description?: string;
|
|
2004
|
+
/** Existing, unarchived event types; omitted or empty means every type. */
|
|
2005
|
+
filter_types?: string[];
|
|
2006
|
+
/** A `whsec_` + base64 secret of 24-64 bytes (e.g. migrated from another provider). */
|
|
2007
|
+
secret?: string;
|
|
2008
|
+
/** 1-1000. */
|
|
2009
|
+
rate_limit_per_second?: number;
|
|
2010
|
+
metadata?: Record<string, string>;
|
|
2011
|
+
enabled?: boolean;
|
|
2012
|
+
}
|
|
2013
|
+
/** Body of `PATCH /v1/hooks/applications/{application}/endpoints/{id}`. */
|
|
2014
|
+
interface UpdateHookEndpointParams {
|
|
2015
|
+
url?: string;
|
|
2016
|
+
description?: string | null;
|
|
2017
|
+
filter_types?: string[];
|
|
2018
|
+
rate_limit_per_second?: number | null;
|
|
2019
|
+
metadata?: Record<string, string>;
|
|
2020
|
+
enabled?: boolean;
|
|
2021
|
+
}
|
|
2022
|
+
/** Returned by `hooks.endpoints.delete`. */
|
|
2023
|
+
interface DeletedHookEndpoint {
|
|
2024
|
+
object: "hook_endpoint";
|
|
2025
|
+
id: string;
|
|
2026
|
+
deleted: true;
|
|
2027
|
+
}
|
|
2028
|
+
/** Returned by `hooks.endpoints.getSecret`. */
|
|
2029
|
+
interface HookEndpointSecret {
|
|
2030
|
+
object: "hook_endpoint_secret";
|
|
2031
|
+
secret: string;
|
|
2032
|
+
}
|
|
2033
|
+
/** Body of `POST …/endpoints/{id}/roll_secret`. */
|
|
2034
|
+
interface RollHookEndpointSecretParams {
|
|
2035
|
+
/** Seconds the current secret keeps signing next to the new one: default 86400, at most 604800, `0` stops it now. */
|
|
2036
|
+
previous_secret_expires_in?: number;
|
|
2037
|
+
}
|
|
2038
|
+
/** Body of `POST …/endpoints/{id}/recover`. */
|
|
2039
|
+
interface RecoverHookEndpointParams {
|
|
2040
|
+
/** Requeue failed deliveries of messages sent since then (ISO 8601 string or `Date`). */
|
|
2041
|
+
since: string | Date;
|
|
2042
|
+
}
|
|
2043
|
+
/** A recovery: coss.com requeues the matching failed deliveries in the background. */
|
|
2044
|
+
interface HookEndpointRecovery {
|
|
2045
|
+
object: "hook_endpoint_recovery";
|
|
2046
|
+
id: string;
|
|
2047
|
+
endpoint_id: string;
|
|
2048
|
+
since: string;
|
|
2049
|
+
until: string;
|
|
2050
|
+
status: "pending" | "completed";
|
|
2051
|
+
requeued: number;
|
|
2052
|
+
created_at: string;
|
|
2053
|
+
completed_at: string | null;
|
|
2054
|
+
}
|
|
2055
|
+
/** Body of `POST …/endpoints/{id}/test`. */
|
|
2056
|
+
interface SendHookTestParams {
|
|
2057
|
+
event_type: string;
|
|
2058
|
+
/** Defaults to the event type's first example. */
|
|
2059
|
+
payload?: Record<string, unknown>;
|
|
2060
|
+
}
|
|
2061
|
+
/** A message sent to an application. */
|
|
2062
|
+
interface HookMessage {
|
|
2063
|
+
object: "hook_message";
|
|
2064
|
+
/** Also the `webhook-id` header of every request delivering it. */
|
|
2065
|
+
id: string;
|
|
2066
|
+
application_id: string;
|
|
2067
|
+
event_type: string;
|
|
2068
|
+
/** The JSON body delivered to each endpoint. */
|
|
2069
|
+
payload: Record<string, unknown>;
|
|
2070
|
+
created_at: string;
|
|
2071
|
+
}
|
|
2072
|
+
/** Params of `hooks.messages.send`: the application, then the body of `POST …/messages`. */
|
|
2073
|
+
interface SendHookMessageParams {
|
|
2074
|
+
/** The application's id or uid. */
|
|
2075
|
+
application: string;
|
|
2076
|
+
/** e.g. `invoice.paid`; endpoints filtering by type only get the types they chose. */
|
|
2077
|
+
event_type: string;
|
|
2078
|
+
/** At most 256 KB serialized; send integers beyond 2^53 as strings. */
|
|
2079
|
+
payload: Record<string, unknown>;
|
|
2080
|
+
}
|
|
2081
|
+
/** Query of `GET …/messages`. */
|
|
2082
|
+
interface ListHookMessagesParams {
|
|
2083
|
+
/** Only messages of this type. */
|
|
2084
|
+
event_type?: string;
|
|
2085
|
+
/** 1-100, default 50. */
|
|
2086
|
+
limit?: number;
|
|
2087
|
+
/** Cursor: the `id` of the last message of the previous page. */
|
|
2088
|
+
after?: string;
|
|
2089
|
+
}
|
|
2090
|
+
/**
|
|
2091
|
+
* `pending`: waiting for its next attempt. `succeeded`: the endpoint answered 2xx. `failed`: every
|
|
2092
|
+
* attempt failed, or the endpoint was disabled or deleted.
|
|
2093
|
+
*/
|
|
2094
|
+
type HookDeliveryStatus = "pending" | "succeeded" | "failed";
|
|
2095
|
+
/** One message's delivery to one endpoint. */
|
|
2096
|
+
interface HookDelivery {
|
|
2097
|
+
object: "hook_delivery";
|
|
2098
|
+
id: string;
|
|
2099
|
+
application_id: string;
|
|
2100
|
+
message_id: string;
|
|
2101
|
+
endpoint_id: string;
|
|
2102
|
+
status: HookDeliveryStatus;
|
|
2103
|
+
attempt_count: number;
|
|
2104
|
+
next_attempt_at: string | null;
|
|
2105
|
+
last_status_code: number | null;
|
|
2106
|
+
last_error: string | null;
|
|
2107
|
+
created_at: string;
|
|
2108
|
+
finished_at: string | null;
|
|
2109
|
+
}
|
|
2110
|
+
/** Query of `GET …/endpoints/{id}/deliveries`. */
|
|
2111
|
+
interface ListHookDeliveriesParams {
|
|
2112
|
+
status?: HookDeliveryStatus;
|
|
2113
|
+
/** 1-100, default 50. */
|
|
2114
|
+
limit?: number;
|
|
2115
|
+
/** Cursor: the `id` of the last delivery of the previous page. */
|
|
2116
|
+
after?: string;
|
|
2117
|
+
}
|
|
2118
|
+
/** One HTTP request of a delivery. */
|
|
2119
|
+
interface HookAttempt {
|
|
2120
|
+
object: "hook_attempt";
|
|
2121
|
+
id: string;
|
|
2122
|
+
delivery_id: string;
|
|
2123
|
+
endpoint_id: string;
|
|
2124
|
+
attempted_at: string;
|
|
2125
|
+
/** `null` when no response arrived. */
|
|
2126
|
+
status_code: number | null;
|
|
2127
|
+
duration_ms: number;
|
|
2128
|
+
error: string | null;
|
|
2129
|
+
/** At most 1 KB of the response body. */
|
|
2130
|
+
response_excerpt: string | null;
|
|
2131
|
+
}
|
|
2132
|
+
/** Params of `hooks.portal.createSession`. */
|
|
2133
|
+
interface CreateHookPortalSessionParams {
|
|
2134
|
+
/** The application's id or uid. */
|
|
2135
|
+
application: string;
|
|
2136
|
+
/** Seconds until it expires: default 3600, 60-86400. */
|
|
2137
|
+
expires_in?: number;
|
|
2138
|
+
/** The user can look but not change anything. */
|
|
2139
|
+
read_only?: boolean;
|
|
2140
|
+
}
|
|
2141
|
+
/** A portal sign-in for one application's user. */
|
|
2142
|
+
interface HookPortalSession {
|
|
2143
|
+
object: "hook_portal_session";
|
|
2144
|
+
id: string;
|
|
2145
|
+
application_id: string;
|
|
2146
|
+
/** Open it or embed it (from an allowed origin); the token is in its fragment. */
|
|
2147
|
+
url: string;
|
|
2148
|
+
/** The secret part of `url`. */
|
|
2149
|
+
token: string;
|
|
2150
|
+
read_only: boolean;
|
|
2151
|
+
expires_at: string;
|
|
2152
|
+
}
|
|
2153
|
+
//#endregion
|
|
2154
|
+
//#region src/resources/hooks.d.ts
|
|
2155
|
+
type ReadOptions$7 = Pick<RequestOptions, "signal">;
|
|
2156
|
+
/** `coss.hooks.applications`: your customers, each with their own endpoints and portal. */
|
|
2157
|
+
declare class HookApplicationsResource {
|
|
2158
|
+
#private;
|
|
2159
|
+
/** @internal Use `new Coss().hooks.applications`. */
|
|
2160
|
+
constructor(http: HttpClient);
|
|
2161
|
+
/** Creates an application. Never automatically retried (the API does not deduplicate it). */
|
|
2162
|
+
create(params: CreateHookApplicationParams, options?: RequestOptions): Promise<CossResult<HookApplication>>;
|
|
2163
|
+
/** Lists the environment's applications, newest first. */
|
|
2164
|
+
list(params?: ListHookApplicationsParams, options?: ReadOptions$7): Promise<CossResult<List<HookApplication>>>;
|
|
2165
|
+
/** Retrieves an application by its id or uid. */
|
|
2166
|
+
get(application: string, options?: ReadOptions$7): Promise<CossResult<HookApplication>>;
|
|
2167
|
+
update(application: string, params: UpdateHookApplicationParams, options?: ReadOptions$7): Promise<CossResult<HookApplication>>;
|
|
2168
|
+
/** Deletes the application with its endpoints and portal sessions. */
|
|
2169
|
+
delete(application: string, options?: ReadOptions$7): Promise<CossResult<DeletedHookApplication>>;
|
|
2170
|
+
}
|
|
2171
|
+
/** `coss.hooks.eventTypes`: the catalog of messages you send, which your users subscribe from. */
|
|
2172
|
+
declare class HookEventTypesResource {
|
|
2173
|
+
#private;
|
|
2174
|
+
/** @internal Use `new Coss().hooks.eventTypes`. */
|
|
2175
|
+
constructor(http: HttpClient);
|
|
2176
|
+
/** Creates an event type. Never automatically retried (a retry would find it existing). */
|
|
2177
|
+
create(params: CreateHookEventTypeParams, options?: RequestOptions): Promise<CossResult<HookEventType>>;
|
|
2178
|
+
/** Lists event types by name (archived ones only with `include_archived`). */
|
|
2179
|
+
list(params?: ListHookEventTypesParams, options?: ReadOptions$7): Promise<CossResult<List<HookEventType>>>;
|
|
2180
|
+
get(name: string, options?: ReadOptions$7): Promise<CossResult<HookEventType>>;
|
|
2181
|
+
/** Changes its description, schema or examples, or archives or restores it. */
|
|
2182
|
+
update(name: string, params: UpdateHookEventTypeParams, options?: ReadOptions$7): Promise<CossResult<HookEventType>>;
|
|
2183
|
+
/** Archives it: hidden from the portal and new subscriptions. */
|
|
2184
|
+
archive(name: string, options?: ReadOptions$7): Promise<CossResult<HookEventType>>;
|
|
2185
|
+
}
|
|
2186
|
+
/** `coss.hooks.endpoints`: an application's endpoints (usually added by its users in the portal). */
|
|
2187
|
+
declare class HookEndpointsResource {
|
|
2188
|
+
#private;
|
|
2189
|
+
/** @internal Use `new Coss().hooks.endpoints`. */
|
|
2190
|
+
constructor(http: HttpClient);
|
|
2191
|
+
/** Creates an endpoint; the result carries its secret. Never automatically retried. */
|
|
2192
|
+
create(application: string, params: CreateHookEndpointParams, options?: RequestOptions): Promise<CossResult<HookEndpointWithSecret>>;
|
|
2193
|
+
list(application: string, options?: ReadOptions$7): Promise<CossResult<List<HookEndpoint>>>;
|
|
2194
|
+
get(application: string, id: string, options?: ReadOptions$7): Promise<CossResult<HookEndpoint>>;
|
|
2195
|
+
update(application: string, id: string, params: UpdateHookEndpointParams, options?: ReadOptions$7): Promise<CossResult<HookEndpoint>>;
|
|
2196
|
+
delete(application: string, id: string, options?: ReadOptions$7): Promise<CossResult<DeletedHookEndpoint>>;
|
|
2197
|
+
/** The endpoint's current signing secret. */
|
|
2198
|
+
getSecret(application: string, id: string, options?: ReadOptions$7): Promise<CossResult<HookEndpointSecret>>;
|
|
2199
|
+
/** Replaces the signing secret. Never automatically retried (a second roll would stop the first). */
|
|
2200
|
+
rollSecret(application: string, id: string, params?: RollHookEndpointSecretParams, options?: RequestOptions): Promise<CossResult<HookEndpointWithSecret>>;
|
|
2201
|
+
/** Requeues the endpoint's failed deliveries of messages sent since `since` (in the background). */
|
|
2202
|
+
recover(application: string, id: string, params: RecoverHookEndpointParams, options?: RequestOptions): Promise<CossResult<HookEndpointRecovery>>;
|
|
2203
|
+
getRecovery(application: string, id: string, recoveryId: string, options?: ReadOptions$7): Promise<CossResult<HookEndpointRecovery>>;
|
|
2204
|
+
/** Sends a message to this endpoint only. Never automatically retried. */
|
|
2205
|
+
sendTest(application: string, id: string, params: SendHookTestParams, options?: RequestOptions): Promise<CossResult<HookMessage>>;
|
|
2206
|
+
/** The endpoint's deliveries, newest first. */
|
|
2207
|
+
listDeliveries(application: string, id: string, params?: ListHookDeliveriesParams, options?: ReadOptions$7): Promise<CossResult<List<HookDelivery>>>;
|
|
2208
|
+
}
|
|
2209
|
+
/** `coss.hooks.messages`: send a message once; coss.com delivers it to every subscribed endpoint. */
|
|
2210
|
+
declare class HookMessagesResource {
|
|
2211
|
+
#private;
|
|
2212
|
+
/** @internal Use `new Coss().hooks.messages`. */
|
|
2213
|
+
constructor(http: HttpClient);
|
|
2214
|
+
/**
|
|
2215
|
+
* Sends a message to an application. Safe to retry: every attempt carries the same
|
|
2216
|
+
* `Idempotency-Key`, so a retried send is delivered once.
|
|
2217
|
+
*/
|
|
2218
|
+
send(params: SendHookMessageParams, options?: RequestOptions): Promise<CossResult<HookMessage>>;
|
|
2219
|
+
/** The application's messages, newest first. */
|
|
2220
|
+
list(application: string, params?: ListHookMessagesParams, options?: ReadOptions$7): Promise<CossResult<List<HookMessage>>>;
|
|
2221
|
+
get(application: string, id: string, options?: ReadOptions$7): Promise<CossResult<HookMessage>>;
|
|
2222
|
+
/** One delivery per endpoint the message went to. */
|
|
2223
|
+
listDeliveries(application: string, id: string, options?: ReadOptions$7): Promise<CossResult<List<HookDelivery>>>;
|
|
2224
|
+
}
|
|
2225
|
+
/** `coss.hooks.deliveries`: one message's delivery to one endpoint. */
|
|
2226
|
+
declare class HookDeliveriesResource {
|
|
2227
|
+
#private;
|
|
2228
|
+
/** @internal Use `new Coss().hooks.deliveries`. */
|
|
2229
|
+
constructor(http: HttpClient);
|
|
2230
|
+
get(application: string, id: string, options?: ReadOptions$7): Promise<CossResult<HookDelivery>>;
|
|
2231
|
+
/** Every HTTP request of the delivery, oldest first. */
|
|
2232
|
+
listAttempts(application: string, id: string, options?: ReadOptions$7): Promise<CossResult<List<HookAttempt>>>;
|
|
2233
|
+
/** Queues a finished delivery for one more attempt. Never automatically retried. */
|
|
2234
|
+
retry(application: string, id: string, options?: RequestOptions): Promise<CossResult<HookDelivery>>;
|
|
2235
|
+
}
|
|
2236
|
+
/** `coss.hooks.portal`: a ready-made page for an application's user to manage their endpoints. */
|
|
2237
|
+
declare class HookPortalResource {
|
|
2238
|
+
#private;
|
|
2239
|
+
/** @internal Use `new Coss().hooks.portal`. */
|
|
2240
|
+
constructor(http: HttpClient);
|
|
2241
|
+
/**
|
|
2242
|
+
* Signs the application's user in to the portal: open or embed the returned `url`. Call it from
|
|
2243
|
+
* your backend each time the user opens the portal.
|
|
2244
|
+
*/
|
|
2245
|
+
createSession(params: CreateHookPortalSessionParams, options?: RequestOptions): Promise<CossResult<HookPortalSession>>;
|
|
2246
|
+
}
|
|
2247
|
+
/**
|
|
2248
|
+
* `coss.hooks`: webhooks as a service. Send a message to one of your applications once
|
|
2249
|
+
* (`coss.hooks.messages.send`); coss.com delivers it to every endpoint its users registered, signed
|
|
2250
|
+
* (Standard Webhooks), with retries, and gives them a portal to manage it all.
|
|
2251
|
+
*/
|
|
2252
|
+
declare class HooksResource {
|
|
2253
|
+
readonly applications: HookApplicationsResource;
|
|
2254
|
+
readonly eventTypes: HookEventTypesResource;
|
|
2255
|
+
readonly endpoints: HookEndpointsResource;
|
|
2256
|
+
readonly messages: HookMessagesResource;
|
|
2257
|
+
readonly deliveries: HookDeliveriesResource;
|
|
2258
|
+
readonly portal: HookPortalResource;
|
|
2259
|
+
/** @internal Use `new Coss().hooks`. */
|
|
2260
|
+
constructor(http: HttpClient);
|
|
2261
|
+
}
|
|
2262
|
+
//#endregion
|
|
2263
|
+
//#region src/types/log.d.ts
|
|
2264
|
+
/** Log wire types (hand-written mirrors of the API's schemas). */
|
|
2265
|
+
/**
|
|
2266
|
+
* `api`: a request to the API. `email`: an email event. `webhook`: a webhook delivery attempt.
|
|
2267
|
+
* `risk`: a risk assessment or its feedback.
|
|
2268
|
+
*/
|
|
2269
|
+
type LogSource = "api" | "email" | "webhook" | "risk" | "smtp";
|
|
2270
|
+
/**
|
|
2271
|
+
* `error`: 5xx responses, bounces, complaints, failures. `warning`: 4xx responses, delays,
|
|
2272
|
+
* suppressions, failed webhook attempts that will be retried. `info`: everything else.
|
|
2273
|
+
*/
|
|
2274
|
+
type LogLevel = "info" | "warning" | "error";
|
|
2275
|
+
/** One line of the API key's environment's log. */
|
|
2276
|
+
interface Log {
|
|
2277
|
+
object: "log";
|
|
2278
|
+
id: string;
|
|
2279
|
+
/** ISO 8601 timestamp. */
|
|
2280
|
+
occurred_at: string;
|
|
2281
|
+
source: LogSource;
|
|
2282
|
+
level: LogLevel;
|
|
2283
|
+
/** `api.request`, `webhook.attempt`, `webhook.forward` (`coss listen`), or an email event type such as `email.delivered`. */
|
|
2284
|
+
type: string;
|
|
2285
|
+
/** A one-line summary. */
|
|
2286
|
+
message: string;
|
|
2287
|
+
/** The `X-Request-Id` of the API request this line belongs to. */
|
|
2288
|
+
request_id: string | null;
|
|
2289
|
+
api_key_id: string | null;
|
|
2290
|
+
method: string | null;
|
|
2291
|
+
path: string | null;
|
|
2292
|
+
/** The matched route, e.g. `/v1/emails/:id`. */
|
|
2293
|
+
route: string | null;
|
|
2294
|
+
/** The API response status, or the webhook endpoint's response status. */
|
|
2295
|
+
status_code: number | null;
|
|
2296
|
+
duration_ms: number | null;
|
|
2297
|
+
client_ip: string | null;
|
|
2298
|
+
user_agent: string | null;
|
|
2299
|
+
error_code: string | null;
|
|
2300
|
+
/** What the line is about: `email`, `domain`, `webhook_endpoint`… */
|
|
2301
|
+
resource_type: string | null;
|
|
2302
|
+
resource_id: string | null;
|
|
2303
|
+
recipient: string | null;
|
|
2304
|
+
/**
|
|
2305
|
+
* Details: redacted request and response bodies for API requests, event data for emails and
|
|
2306
|
+
* webhooks.
|
|
2307
|
+
*/
|
|
2308
|
+
attributes: Record<string, unknown>;
|
|
2309
|
+
}
|
|
2310
|
+
type OneOrMany<T> = T | readonly T[];
|
|
2311
|
+
/** Query of `GET /v1/logs`. Lists may be given as arrays or comma-separated strings. */
|
|
2312
|
+
interface ListLogsParams {
|
|
2313
|
+
/** Start of the range (inclusive). Defaults to an hour before `to`. */
|
|
2314
|
+
from?: string | Date;
|
|
2315
|
+
/** End of the range (exclusive). Defaults to now. At most 31 days after `from`. */
|
|
2316
|
+
to?: string | Date;
|
|
2317
|
+
source?: OneOrMany<LogSource>;
|
|
2318
|
+
level?: OneOrMany<LogLevel>;
|
|
2319
|
+
/** e.g. `"email.bounced"`. */
|
|
2320
|
+
type?: OneOrMany<string>;
|
|
2321
|
+
/** Status codes or classes, e.g. `["4xx", "503"]`. */
|
|
2322
|
+
status?: OneOrMany<string | number>;
|
|
2323
|
+
method?: OneOrMany<string>;
|
|
2324
|
+
/** Routes such as `/v1/emails/:id`. */
|
|
2325
|
+
route?: OneOrMany<string>;
|
|
2326
|
+
api_key_id?: OneOrMany<string>;
|
|
2327
|
+
request_id?: string;
|
|
2328
|
+
/** Only lines about this resource, e.g. an `email_…` id. */
|
|
2329
|
+
resource_id?: string;
|
|
2330
|
+
/** Free text, matched against the message, path, ids and recipient. */
|
|
2331
|
+
q?: string;
|
|
2332
|
+
/** 1-100, default 50. */
|
|
2333
|
+
limit?: number;
|
|
2334
|
+
/** The `id` of the last line of the previous page. */
|
|
2335
|
+
after?: string;
|
|
2336
|
+
}
|
|
2337
|
+
//#endregion
|
|
2338
|
+
//#region src/types/log-drain.d.ts
|
|
2339
|
+
/**
|
|
2340
|
+
* What a drain forwards: `api` (requests made with the environment's API keys), `email` (email
|
|
2341
|
+
* events), `webhook` (webhook delivery attempts) and `audit` (changes to the environment, from
|
|
2342
|
+
* the organization's audit log).
|
|
2343
|
+
*/
|
|
2344
|
+
type LogDrainSource = LogSource | "audit";
|
|
2345
|
+
/** An HTTPS endpoint the environment's log is streamed to, in signed NDJSON batches. */
|
|
2346
|
+
interface LogDrain {
|
|
2347
|
+
object: "log_drain";
|
|
2348
|
+
id: string;
|
|
2349
|
+
url: string;
|
|
2350
|
+
description: string | null;
|
|
2351
|
+
/** Empty means every source, including ones added later. */
|
|
2352
|
+
sources: LogDrainSource[];
|
|
2353
|
+
/** A disabled drain receives nothing, and lines logged meanwhile are not kept for it. */
|
|
2354
|
+
enabled: boolean;
|
|
2355
|
+
/** `manual`, or `failing`: a batch failed every attempt, so coss.com disabled it. */
|
|
2356
|
+
disabled_reason: "manual" | "failing" | null;
|
|
2357
|
+
/** ISO 8601 timestamp; `null` while enabled. */
|
|
2358
|
+
disabled_at: string | null;
|
|
2359
|
+
created_at: string;
|
|
2360
|
+
updated_at: string;
|
|
2361
|
+
}
|
|
2362
|
+
/** A drain with its `whsec_…` signing secret, returned only when it is created. */
|
|
2363
|
+
interface LogDrainWithSecret extends LogDrain {
|
|
2364
|
+
secret: string;
|
|
2365
|
+
}
|
|
2366
|
+
interface DeletedLogDrain {
|
|
2367
|
+
object: "log_drain";
|
|
2368
|
+
id: string;
|
|
2369
|
+
deleted: true;
|
|
2370
|
+
}
|
|
2371
|
+
interface CreateLogDrainParams {
|
|
2372
|
+
/** An `https://` URL coss.com posts batches to. */
|
|
2373
|
+
url: string;
|
|
2374
|
+
description?: string | null;
|
|
2375
|
+
/** Defaults to every source. */
|
|
2376
|
+
sources?: LogDrainSource[];
|
|
2377
|
+
}
|
|
2378
|
+
interface UpdateLogDrainParams {
|
|
2379
|
+
url?: string;
|
|
2380
|
+
/** `null` clears it. */
|
|
2381
|
+
description?: string | null;
|
|
2382
|
+
sources?: LogDrainSource[];
|
|
2383
|
+
/** Disabling drops the lines still waiting for the drain. */
|
|
2384
|
+
enabled?: boolean;
|
|
2385
|
+
}
|
|
2386
|
+
type LogDrainBatchStatus = "pending" | "succeeded" | "failed";
|
|
2387
|
+
/** One HTTP attempt of a batch. */
|
|
2388
|
+
interface LogDrainAttempt {
|
|
2389
|
+
object: "log_drain_attempt";
|
|
2390
|
+
id: string;
|
|
2391
|
+
attempted_at: string;
|
|
2392
|
+
/** `null` when no response arrived. */
|
|
2393
|
+
status_code: number | null;
|
|
2394
|
+
duration_ms: number;
|
|
2395
|
+
error: string | null;
|
|
2396
|
+
/** At most 1 KB of the response body, as text. */
|
|
2397
|
+
response_excerpt: string | null;
|
|
2398
|
+
}
|
|
2399
|
+
/** One NDJSON request; its `id` is the `webhook-id` header, the same on every attempt. */
|
|
2400
|
+
interface LogDrainBatch {
|
|
2401
|
+
object: "log_drain_batch";
|
|
2402
|
+
id: string;
|
|
2403
|
+
drain_id: string;
|
|
2404
|
+
status: LogDrainBatchStatus;
|
|
2405
|
+
line_count: number;
|
|
2406
|
+
byte_size: number;
|
|
2407
|
+
attempt_count: number;
|
|
2408
|
+
next_attempt_at: string | null;
|
|
2409
|
+
last_status_code: number | null;
|
|
2410
|
+
last_error: string | null;
|
|
2411
|
+
/** Oldest first. */
|
|
2412
|
+
attempts: LogDrainAttempt[];
|
|
2413
|
+
created_at: string;
|
|
2414
|
+
updated_at: string;
|
|
2415
|
+
}
|
|
2416
|
+
interface ListLogDrainBatchesParams {
|
|
2417
|
+
status?: LogDrainBatchStatus;
|
|
2418
|
+
/** 1-100, default 50. */
|
|
2419
|
+
limit?: number;
|
|
2420
|
+
/** The `id` of the last batch of the previous page. */
|
|
2421
|
+
after?: string;
|
|
2422
|
+
}
|
|
2423
|
+
/**
|
|
2424
|
+
* One line of a log drain batch: a log line (as `coss.logs.list()` returns it) or an audit event
|
|
2425
|
+
* of the environment (as `coss.auditEvents.list()` returns it).
|
|
2426
|
+
*/
|
|
2427
|
+
type LogDrainLine = Log | AuditEvent;
|
|
2428
|
+
//#endregion
|
|
2429
|
+
//#region src/resources/log-drains.d.ts
|
|
2430
|
+
type ReadOptions$6 = Pick<RequestOptions, "signal">;
|
|
2431
|
+
/** `coss.logDrains.batches`: a drain's delivery log, each batch with every HTTP attempt. */
|
|
2432
|
+
declare class LogDrainBatchesResource {
|
|
2433
|
+
#private;
|
|
2434
|
+
/** @internal Use `new Coss().logDrains.batches`. */
|
|
2435
|
+
constructor(http: HttpClient);
|
|
2436
|
+
/** Lists the drain's batches, newest first. Pass the last `id` as `after` while `has_more` is true. */
|
|
2437
|
+
list(drainId: string, params?: ListLogDrainBatchesParams, options?: ReadOptions$6): Promise<CossResult<List<LogDrainBatch>>>;
|
|
2438
|
+
/** Retrieves one batch of the drain. */
|
|
2439
|
+
get(drainId: string, id: string, options?: ReadOptions$6): Promise<CossResult<LogDrainBatch>>;
|
|
2440
|
+
}
|
|
2441
|
+
/**
|
|
2442
|
+
* `coss.logDrains`: HTTPS endpoints the environment's log is streamed to (API requests, email
|
|
2443
|
+
* events, webhook attempts and audit events), in signed NDJSON batches. Drains belong to the API
|
|
2444
|
+
* key's own environment, so a `coss_test_…` key only ever manages sandbox drains.
|
|
2445
|
+
*/
|
|
2446
|
+
declare class LogDrainsResource {
|
|
2447
|
+
#private;
|
|
2448
|
+
/** Each drain's delivery log. */
|
|
2449
|
+
readonly batches: LogDrainBatchesResource;
|
|
2450
|
+
/** @internal Use `new Coss().logDrains`. */
|
|
2451
|
+
constructor(http: HttpClient);
|
|
2452
|
+
/**
|
|
2453
|
+
* Creates a drain. The result carries its `secret` (returned only here) — store it and pass it
|
|
2454
|
+
* to `verifyLogDrainBatch` for every request. Creation is never automatically retried: the API
|
|
2455
|
+
* does not deduplicate it. After a lost response, list drains and remove the one with the
|
|
2456
|
+
* unknown secret before creating a replacement.
|
|
2457
|
+
*/
|
|
2458
|
+
create(params: CreateLogDrainParams, options?: RequestOptions): Promise<CossResult<LogDrainWithSecret>>;
|
|
2459
|
+
/** Lists the environment's drains, oldest first. Secrets are never included. */
|
|
2460
|
+
list(options?: ReadOptions$6): Promise<CossResult<List<LogDrain>>>;
|
|
2461
|
+
/** Retrieves a drain of the API key's environment. */
|
|
2462
|
+
get(id: string, options?: ReadOptions$6): Promise<CossResult<LogDrain>>;
|
|
2463
|
+
/**
|
|
2464
|
+
* Changes the URL, description, sources or `enabled` flag. The signing secret stays the same.
|
|
2465
|
+
* Disabling drops the lines still waiting for the drain; enabling it again (also after coss.com
|
|
2466
|
+
* disabled it for failing) sends lines logged from then on.
|
|
2467
|
+
*/
|
|
2468
|
+
update(id: string, params: UpdateLogDrainParams, options?: ReadOptions$6): Promise<CossResult<LogDrain>>;
|
|
2469
|
+
/** Deletes the drain and its batch log. To pause it instead, update `enabled` to false. */
|
|
2470
|
+
delete(id: string, options?: ReadOptions$6): Promise<CossResult<DeletedLogDrain>>;
|
|
2471
|
+
}
|
|
2472
|
+
//#endregion
|
|
2473
|
+
//#region src/resources/logs.d.ts
|
|
2474
|
+
type ReadOptions$5 = Pick<RequestOptions, "signal">;
|
|
2475
|
+
/**
|
|
2476
|
+
* `coss.logs`: the API key's environment log, newest first: API requests made with its keys,
|
|
2477
|
+
* email events and webhook delivery attempts.
|
|
2478
|
+
*/
|
|
2479
|
+
declare class LogsResource {
|
|
2480
|
+
#private;
|
|
2481
|
+
/** @internal Use `new Coss().logs`. */
|
|
2482
|
+
constructor(http: HttpClient);
|
|
2483
|
+
/**
|
|
2484
|
+
* Lists log lines, newest first (the last hour unless `from`/`to` say otherwise). Pass the last
|
|
2485
|
+
* `id` as `after` while `has_more` is true.
|
|
2486
|
+
*/
|
|
2487
|
+
list(params?: ListLogsParams, options?: ReadOptions$5): Promise<CossResult<List<Log>>>;
|
|
2488
|
+
/** Retrieves one log line. */
|
|
2489
|
+
get(id: string, options?: ReadOptions$5): Promise<CossResult<Log>>;
|
|
2490
|
+
}
|
|
2491
|
+
//#endregion
|
|
2492
|
+
//#region src/types/reputation.d.ts
|
|
2493
|
+
/** Reputation wire types (hand-written mirrors of the API's `Reputation` schema). */
|
|
2494
|
+
type ReputationStatus = "good" | "warning" | "suspended";
|
|
2495
|
+
type ReputationCheckSeverity = "ok" | "warning" | "suspend";
|
|
2496
|
+
/** One signal the reputation guard measured, e.g. the bounce rate. */
|
|
2497
|
+
interface ReputationCheck {
|
|
2498
|
+
/** What was measured, e.g. `bounce_rate` or `complaint_rate`. */
|
|
2499
|
+
trigger: string;
|
|
2500
|
+
severity: ReputationCheckSeverity;
|
|
2501
|
+
message: string;
|
|
2502
|
+
/** `count / volume`; `null` with no volume. */
|
|
2503
|
+
rate: number | null;
|
|
2504
|
+
count: number;
|
|
2505
|
+
/** Recipients sent to (live environments) in the window. */
|
|
2506
|
+
volume: number;
|
|
2507
|
+
warning_threshold: number | null;
|
|
2508
|
+
suspend_threshold: number | null;
|
|
2509
|
+
/** Below this volume the rate is reported but never acted on. */
|
|
2510
|
+
minimum_volume: number | null;
|
|
2511
|
+
}
|
|
2512
|
+
/** `GET /v1/reputation`: the organization's standing with the reputation guard. */
|
|
2513
|
+
interface Reputation {
|
|
2514
|
+
object: "reputation";
|
|
2515
|
+
/**
|
|
2516
|
+
* `suspended` means live sending is refused (`account_suspended`) until coss.com support
|
|
2517
|
+
* reinstates the organization; sandbox keys keep working.
|
|
2518
|
+
*/
|
|
2519
|
+
status: ReputationStatus;
|
|
2520
|
+
/** The trigger behind a `warning` or `suspended` status. */
|
|
2521
|
+
reason: string | null;
|
|
2522
|
+
/** ISO 8601 timestamp. */
|
|
2523
|
+
status_changed_at: string | null;
|
|
2524
|
+
/** When `checks` were computed; `null` before the first evaluation. */
|
|
2525
|
+
evaluated_at: string | null;
|
|
2526
|
+
/** The period `checks` cover. */
|
|
2527
|
+
window: {
|
|
2528
|
+
start: string;
|
|
2529
|
+
end: string;
|
|
2530
|
+
} | null;
|
|
2531
|
+
checks: ReputationCheck[];
|
|
2532
|
+
}
|
|
2533
|
+
//#endregion
|
|
2534
|
+
//#region src/resources/reputation.d.ts
|
|
2535
|
+
type ReadOptions$4 = Pick<RequestOptions, "signal">;
|
|
2536
|
+
/**
|
|
2537
|
+
* `coss.reputation`: the organization's standing with the coss.com reputation guard, which suspends
|
|
2538
|
+
* live sending automatically when bounce or complaint rates cross its thresholds.
|
|
2539
|
+
*/
|
|
2540
|
+
declare class ReputationResource {
|
|
2541
|
+
#private;
|
|
2542
|
+
/** @internal Use `new Coss().reputation`. */
|
|
2543
|
+
constructor(http: HttpClient);
|
|
2544
|
+
/** The current status and the latest rates measured over live environments. */
|
|
2545
|
+
get(options?: ReadOptions$4): Promise<CossResult<Reputation>>;
|
|
2546
|
+
}
|
|
2547
|
+
//#endregion
|
|
2548
|
+
//#region src/types/risk.d.ts
|
|
2549
|
+
/** Risk wire types (hand-written mirrors of the API's schemas). */
|
|
2550
|
+
/** What is being assessed. Velocity is counted per event (`custom` events per `event_name`). */
|
|
2551
|
+
type RiskEvent = "signup" | "login" | "message" | "checkout" | "custom";
|
|
2552
|
+
/** `allow`: go ahead. `review`: suspicious; limit or hold it for a person. `block`: refuse it. */
|
|
2553
|
+
type RiskDecision = "allow" | "review" | "block";
|
|
2554
|
+
/** What really happened: `legitimate`, `fraud`, or `abuse` (spam, free-tier abuse…). */
|
|
2555
|
+
type RiskOutcome = "legitimate" | "fraud" | "abuse";
|
|
2556
|
+
type RiskList = "allow" | "block";
|
|
2557
|
+
/**
|
|
2558
|
+
* `email` (matched by mailbox, dots and `+tags` folded), `domain` (subdomains included), `ip` (an
|
|
2559
|
+
* address or CIDR range), `asn`, `country` (ISO 3166-1 alpha-2), `user` (your user id).
|
|
2560
|
+
*/
|
|
2561
|
+
type RiskListEntryType = "email" | "domain" | "ip" | "asn" | "country" | "user";
|
|
2562
|
+
/** Signal groups an assessment was made without (a lookup failed or timed out). */
|
|
2563
|
+
type RiskDegradedSignal = "email_dns" | "domain_age" | "ip_data" | "velocity" | "captcha" | "content" | "ip_privacy";
|
|
2564
|
+
/** What content classification scores. */
|
|
2565
|
+
type RiskContentCategory = "spam" | "phishing" | "malware" | "fraud";
|
|
2566
|
+
/**
|
|
2567
|
+
* Per category, the model's probability (0-1) that the content belongs to it. Not calibrated:
|
|
2568
|
+
* pick thresholds by looking at your own traffic.
|
|
2569
|
+
*/
|
|
2570
|
+
type RiskContentScores = Record<RiskContentCategory, number>;
|
|
2571
|
+
/** Every reason an assessment can give (see the reason catalog in the docs). */
|
|
2572
|
+
type RiskReasonCode = "email.invalid" | "email.disposable" | "email.undeliverable" | "email.role_account" | "email.typo" | "email.domain_new" | "ip.tor" | "ip.vpn_network" | "ip.hosting_provider" | "ip.vpn" | "ip.proxy" | "ip.relay" | "ip.private" | "velocity.signups_per_ip_1h" | "velocity.signups_per_ip_24h" | "velocity.signups_per_subnet_1h" | "velocity.signups_per_email_domain_1h" | "velocity.signups_per_mailbox_24h" | "velocity.signups_per_device_24h" | "velocity.checkouts_per_ip_1h" | "velocity.checkouts_per_user_1h" | "velocity.checkouts_per_card_24h" | "velocity.logins_per_ip_1h" | "velocity.logins_per_user_1h" | "velocity.events_per_ip_1h" | "velocity.events_per_user_1h" | "duplicate.canonical_mailbox" | "duplicate.device" | "history.fraud_mailbox" | "history.fraud_user" | "history.fraud_ip" | "history.fraud_subnet" | "history.fraud_card" | "history.fraud_device" | "checkout.card_country_mismatch" | "checkout.billing_country_mismatch" | "checkout.prepaid_card" | "device.automation" | "device.invalid" | "login.new_country" | "login.new_network" | "captcha.failed" | "captcha.missing" | "content.spam" | "content.phishing" | "content.malware" | "content.fraud" | "rule.matched" | "list.blocked" | "list.allowed";
|
|
2573
|
+
/** Why an assessment decided what it did. Never show reasons to the person being assessed. */
|
|
2574
|
+
interface RiskReason {
|
|
2575
|
+
code: RiskReasonCode;
|
|
2576
|
+
/** For developers (dashboards, logs). */
|
|
2577
|
+
message: string;
|
|
2578
|
+
/** The count behind a `velocity.*` reason. */
|
|
2579
|
+
value?: number;
|
|
2580
|
+
/** The count a `velocity.*` reason fires at. */
|
|
2581
|
+
threshold?: number;
|
|
2582
|
+
window?: "1h" | "24h";
|
|
2583
|
+
/** `email.typo`: the likely domain, which you may show the user ("Did you mean …?"). */
|
|
2584
|
+
suggestion?: string;
|
|
2585
|
+
/** `ip.hosting_provider`, `ip.vpn_network`: the network's operator; `ip.vpn`: the VPN service. */
|
|
2586
|
+
provider?: string;
|
|
2587
|
+
/** `duplicate.*`: your id of the user who has the mailbox or device, if known. */
|
|
2588
|
+
previous_user?: string | null;
|
|
2589
|
+
/** `duplicate.*`: the assessment that first saw the mailbox or device. */
|
|
2590
|
+
previous_assessment?: string;
|
|
2591
|
+
/** `list.*`: the matching list entry. */
|
|
2592
|
+
entry?: string;
|
|
2593
|
+
/** `list.*`: what matched. */
|
|
2594
|
+
type?: RiskListEntryType;
|
|
2595
|
+
/** `rule.matched`: the rule's id. */
|
|
2596
|
+
rule?: string;
|
|
2597
|
+
/** `rule.matched`: the rule's name. */
|
|
2598
|
+
name?: string;
|
|
2599
|
+
}
|
|
2600
|
+
interface RiskEmailSignals {
|
|
2601
|
+
/** `null` once the address is removed (90 days after the assessment). */
|
|
2602
|
+
domain: string | null;
|
|
2603
|
+
valid: boolean;
|
|
2604
|
+
disposable: boolean;
|
|
2605
|
+
/** From DNS (MX, A, AAAA). `unknown` when the lookup failed or timed out. */
|
|
2606
|
+
deliverability: "deliverable" | "undeliverable" | "unknown";
|
|
2607
|
+
role_account: boolean;
|
|
2608
|
+
free_provider: boolean;
|
|
2609
|
+
suggestion: string | null;
|
|
2610
|
+
/**
|
|
2611
|
+
* Days since the domain was registered (RDAP); `null` when unknown or not looked up (free
|
|
2612
|
+
* providers, disposable domains).
|
|
2613
|
+
*/
|
|
2614
|
+
domain_age_days: number | null;
|
|
2615
|
+
}
|
|
2616
|
+
interface RiskCaptchaSignals {
|
|
2617
|
+
provided: boolean;
|
|
2618
|
+
/** `null` when it couldn't be checked (no captcha configured, or the provider was unreachable). */
|
|
2619
|
+
passed: boolean | null;
|
|
2620
|
+
}
|
|
2621
|
+
/** Logins of a user with history: whether the country or network is new for them. */
|
|
2622
|
+
interface RiskLoginSignals {
|
|
2623
|
+
new_country: boolean;
|
|
2624
|
+
new_network: boolean;
|
|
2625
|
+
}
|
|
2626
|
+
interface RiskIpSignals {
|
|
2627
|
+
version: 4 | 6;
|
|
2628
|
+
private: boolean;
|
|
2629
|
+
tor: boolean;
|
|
2630
|
+
hosting: boolean;
|
|
2631
|
+
hosting_provider: string | null;
|
|
2632
|
+
hosting_kind: "cloud" | "hosting" | "vpn" | null;
|
|
2633
|
+
asn: number | null;
|
|
2634
|
+
as_name: string | null;
|
|
2635
|
+
/** ISO 3166-1 alpha-2. */
|
|
2636
|
+
country: string | null;
|
|
2637
|
+
/**
|
|
2638
|
+
* From coss.com's IP privacy data provider; `null` when it isn't available or was not asked
|
|
2639
|
+
* (private addresses).
|
|
2640
|
+
*/
|
|
2641
|
+
privacy: RiskIpPrivacy | null;
|
|
2642
|
+
}
|
|
2643
|
+
/** Whether an address is a VPN exit, a proxy or a privacy relay (iCloud Private Relay…). */
|
|
2644
|
+
interface RiskIpPrivacy {
|
|
2645
|
+
vpn: boolean;
|
|
2646
|
+
proxy: boolean;
|
|
2647
|
+
relay: boolean;
|
|
2648
|
+
/** The VPN or proxy service. */
|
|
2649
|
+
service: string | null;
|
|
2650
|
+
}
|
|
2651
|
+
/** How a card is funded, as your payment processor reports it. */
|
|
2652
|
+
type RiskCardFunding = "credit" | "debit" | "prepaid" | "unknown";
|
|
2653
|
+
/** What you sent in `checkout` (never the card). */
|
|
2654
|
+
interface RiskCheckoutSignals {
|
|
2655
|
+
amount: number;
|
|
2656
|
+
currency: string;
|
|
2657
|
+
card_country: string | null;
|
|
2658
|
+
card_funding: RiskCardFunding | null;
|
|
2659
|
+
billing_country: string | null;
|
|
2660
|
+
shipping_country: string | null;
|
|
2661
|
+
}
|
|
2662
|
+
/** What the browser reported through `coss/device` (its device id is only kept as a keyed hash). */
|
|
2663
|
+
interface RiskDeviceSignals {
|
|
2664
|
+
/** `false`: the token was malformed or too old. */
|
|
2665
|
+
valid: boolean;
|
|
2666
|
+
/** WebDriver control or a headless browser. */
|
|
2667
|
+
automation: boolean;
|
|
2668
|
+
/** IANA time zone (`Europe/London`). */
|
|
2669
|
+
timezone: string | null;
|
|
2670
|
+
/** The browser's first language. */
|
|
2671
|
+
language: string | null;
|
|
2672
|
+
platform: string | null;
|
|
2673
|
+
/** `<width>x<height>` in CSS pixels. */
|
|
2674
|
+
screen: string | null;
|
|
2675
|
+
touch: boolean | null;
|
|
2676
|
+
}
|
|
2677
|
+
/** An assessment of one event. */
|
|
2678
|
+
interface RiskAssessment {
|
|
2679
|
+
object: "risk_assessment";
|
|
2680
|
+
id: string;
|
|
2681
|
+
event: RiskEvent;
|
|
2682
|
+
event_name: string | null;
|
|
2683
|
+
decision: RiskDecision;
|
|
2684
|
+
/** 0-1: how risky the signals are together. Lists can decide regardless of the score. */
|
|
2685
|
+
score: number;
|
|
2686
|
+
/** Why, most significant first. */
|
|
2687
|
+
reasons: RiskReason[];
|
|
2688
|
+
signals: {
|
|
2689
|
+
email: RiskEmailSignals | null;
|
|
2690
|
+
ip: RiskIpSignals | null;
|
|
2691
|
+
/**
|
|
2692
|
+
* Events of the same kind in this environment, this one included, keyed
|
|
2693
|
+
* `<dimension>_<window>` (e.g. `ip_1h`, `mailbox_24h`); `null` when unavailable.
|
|
2694
|
+
*/
|
|
2695
|
+
velocity: Record<string, number> | null;
|
|
2696
|
+
captcha: RiskCaptchaSignals | null;
|
|
2697
|
+
login: RiskLoginSignals | null;
|
|
2698
|
+
/** `null` when no content was given or it couldn't be classified. */
|
|
2699
|
+
content: RiskContentScores | null;
|
|
2700
|
+
checkout: RiskCheckoutSignals | null;
|
|
2701
|
+
device: RiskDeviceSignals | null;
|
|
2702
|
+
};
|
|
2703
|
+
user: {
|
|
2704
|
+
id: string | null;
|
|
2705
|
+
email: string | null;
|
|
2706
|
+
};
|
|
2707
|
+
/** `null` once removed (90 days after the assessment). */
|
|
2708
|
+
ip: string | null;
|
|
2709
|
+
degraded: RiskDegradedSignal[];
|
|
2710
|
+
/** The latest outcome you reported with `coss.risk.feedback`. */
|
|
2711
|
+
outcome: RiskOutcome | null;
|
|
2712
|
+
/** `open` for `review` decisions until you send feedback, then `resolved`. */
|
|
2713
|
+
review_status: "open" | "resolved" | null;
|
|
2714
|
+
/** ISO 8601 timestamp. */
|
|
2715
|
+
created_at: string;
|
|
2716
|
+
}
|
|
2717
|
+
/** Body of `POST /v1/risk/assessments`. */
|
|
2718
|
+
interface AssessRiskParams {
|
|
2719
|
+
event: RiskEvent;
|
|
2720
|
+
/** Required for `custom` events (e.g. `invite_sent`), not allowed otherwise. */
|
|
2721
|
+
event_name?: string;
|
|
2722
|
+
user?: {
|
|
2723
|
+
/** Your id for the user, when it exists (logins always; sign-ups once the account exists). */
|
|
2724
|
+
id?: string;
|
|
2725
|
+
/** The email address the user gave. */
|
|
2726
|
+
email?: string;
|
|
2727
|
+
};
|
|
2728
|
+
/** The client's IP address (not your server's or proxy's). */
|
|
2729
|
+
ip?: string;
|
|
2730
|
+
/** The client's user agent. */
|
|
2731
|
+
user_agent?: string;
|
|
2732
|
+
/**
|
|
2733
|
+
* The token your captcha widget (Turnstile or hCaptcha, set in the risk settings) gave the
|
|
2734
|
+
* browser. Verified once: don't reuse it.
|
|
2735
|
+
*/
|
|
2736
|
+
captcha?: {
|
|
2737
|
+
token: string;
|
|
2738
|
+
};
|
|
2739
|
+
/**
|
|
2740
|
+
* Text the user wrote (a bio, a message, a listing), classified with the event and never
|
|
2741
|
+
* stored: its scores go in `signals.content`, and `content.*` reasons fire only at thresholds
|
|
2742
|
+
* you set.
|
|
2743
|
+
*/
|
|
2744
|
+
content?: {
|
|
2745
|
+
text: string;
|
|
2746
|
+
};
|
|
2747
|
+
/** Only with `checkout` events: what is being paid for, and with which card. */
|
|
2748
|
+
checkout?: {
|
|
2749
|
+
/** In the currency's minor unit (cents for USD: 1999 is $19.99). */
|
|
2750
|
+
amount: number;
|
|
2751
|
+
/** ISO 4217, upper-case (`USD`). */
|
|
2752
|
+
currency: string;
|
|
2753
|
+
/** What your payment processor tells you about the card. */
|
|
2754
|
+
card?: {
|
|
2755
|
+
/**
|
|
2756
|
+
* Your processor's fingerprint of the card number (Stripe: `card.fingerprint`), kept as a
|
|
2757
|
+
* keyed hash only. Never send the card number.
|
|
2758
|
+
*/
|
|
2759
|
+
fingerprint?: string;
|
|
2760
|
+
/** Where the card was issued (ISO 3166-1 alpha-2, upper-case). */
|
|
2761
|
+
country?: string;
|
|
2762
|
+
funding?: RiskCardFunding;
|
|
2763
|
+
};
|
|
2764
|
+
billing_country?: string;
|
|
2765
|
+
shipping_country?: string;
|
|
2766
|
+
};
|
|
2767
|
+
/** What `collectDevice()` from `coss/device` returned in the user's browser. */
|
|
2768
|
+
device?: {
|
|
2769
|
+
token: string;
|
|
2770
|
+
};
|
|
2771
|
+
}
|
|
2772
|
+
/** Query of `GET /v1/risk/assessments`. */
|
|
2773
|
+
interface ListRiskAssessmentsParams {
|
|
2774
|
+
event?: RiskEvent;
|
|
2775
|
+
decision?: RiskDecision;
|
|
2776
|
+
user_id?: string;
|
|
2777
|
+
/** `open`: the review queue. */
|
|
2778
|
+
review_status?: "open" | "resolved";
|
|
2779
|
+
/** 1-100, default 50. */
|
|
2780
|
+
limit?: number;
|
|
2781
|
+
/** The `id` of the last assessment of the previous page. */
|
|
2782
|
+
after?: string;
|
|
2783
|
+
}
|
|
2784
|
+
/** Body of `POST /v1/risk/assessments/{id}/feedback`. */
|
|
2785
|
+
interface RiskFeedbackParams {
|
|
2786
|
+
outcome: RiskOutcome;
|
|
2787
|
+
/** For your team; never shared. */
|
|
2788
|
+
note?: string;
|
|
2789
|
+
}
|
|
2790
|
+
/** An entry of the environment's allow or block list. */
|
|
2791
|
+
interface RiskListEntry {
|
|
2792
|
+
object: "risk_list_entry";
|
|
2793
|
+
id: string;
|
|
2794
|
+
list: RiskList;
|
|
2795
|
+
type: RiskListEntryType;
|
|
2796
|
+
/** Normalized: emails as their mailbox, CIDR ranges canonical, ASNs as numbers. */
|
|
2797
|
+
value: string;
|
|
2798
|
+
note: string | null;
|
|
2799
|
+
/** ISO 8601 timestamp: the entry stops matching then. */
|
|
2800
|
+
expires_at: string | null;
|
|
2801
|
+
/** ISO 8601 timestamp. */
|
|
2802
|
+
created_at: string;
|
|
2803
|
+
}
|
|
2804
|
+
/** Body of `POST /v1/risk/list_entries` (`coss.risk.lists.add` builds it). */
|
|
2805
|
+
interface CreateRiskListEntryParams {
|
|
2806
|
+
list: RiskList;
|
|
2807
|
+
type: RiskListEntryType;
|
|
2808
|
+
value: string;
|
|
2809
|
+
note?: string;
|
|
2810
|
+
/** ISO 8601 timestamp with an offset. */
|
|
2811
|
+
expires_at?: string;
|
|
2812
|
+
}
|
|
2813
|
+
/** What `coss.risk.lists.add` matches on: exactly one of these. */
|
|
2814
|
+
type RiskListEntryValue = {
|
|
2815
|
+
email: string;
|
|
2816
|
+
} | {
|
|
2817
|
+
domain: string;
|
|
2818
|
+
} | {
|
|
2819
|
+
ip: string;
|
|
2820
|
+
} | {
|
|
2821
|
+
asn: string | number;
|
|
2822
|
+
} | {
|
|
2823
|
+
country: string;
|
|
2824
|
+
} | {
|
|
2825
|
+
user: string;
|
|
2826
|
+
};
|
|
2827
|
+
/** Query of `GET /v1/risk/list_entries`. */
|
|
2828
|
+
interface ListRiskListEntriesParams {
|
|
2829
|
+
list?: RiskList;
|
|
2830
|
+
type?: RiskListEntryType;
|
|
2831
|
+
/** 1-100, default 50. */
|
|
2832
|
+
limit?: number;
|
|
2833
|
+
after?: string;
|
|
2834
|
+
}
|
|
2835
|
+
/** Response of `DELETE /v1/risk/list_entries/{id}`. */
|
|
2836
|
+
interface DeletedRiskListEntry {
|
|
2837
|
+
object: "risk_list_entry";
|
|
2838
|
+
id: string;
|
|
2839
|
+
deleted: true;
|
|
2840
|
+
}
|
|
2841
|
+
/** Response of `DELETE /v1/risk/users/{user_id}`. */
|
|
2842
|
+
interface ForgottenRiskUser {
|
|
2843
|
+
object: "risk_user";
|
|
2844
|
+
/** Your user id. */
|
|
2845
|
+
id: string;
|
|
2846
|
+
deleted: true;
|
|
2847
|
+
}
|
|
2848
|
+
type RiskCaptchaProvider = "turnstile" | "hcaptcha";
|
|
2849
|
+
/** The environment's risk settings. */
|
|
2850
|
+
interface RiskSettings {
|
|
2851
|
+
object: "risk_settings";
|
|
2852
|
+
/** Scores at or above it are `review`. */
|
|
2853
|
+
review_threshold: number;
|
|
2854
|
+
/** Scores at or above it are `block`. */
|
|
2855
|
+
block_threshold: number;
|
|
2856
|
+
/** Reasons that never fire in this environment. */
|
|
2857
|
+
disabled_reasons: RiskReasonCode[];
|
|
2858
|
+
/** The captcha provider assessments verify tokens with (never the secret). */
|
|
2859
|
+
captcha: {
|
|
2860
|
+
provider: RiskCaptchaProvider;
|
|
2861
|
+
required: boolean;
|
|
2862
|
+
} | null;
|
|
2863
|
+
/** Per content category, the score at which `content.<category>` fires; `null`: never. */
|
|
2864
|
+
content_thresholds: Record<RiskContentCategory, number | null>;
|
|
2865
|
+
/** Reasons whose weight this environment changed; the rest weigh what the catalog says. */
|
|
2866
|
+
reason_weights: Partial<Record<RiskReasonCode, number>>;
|
|
2867
|
+
/** ISO 8601 timestamp; `null` while on the defaults. */
|
|
2868
|
+
updated_at: string | null;
|
|
2869
|
+
}
|
|
2870
|
+
/** Body of `PATCH /v1/risk/settings`: only the fields given change. */
|
|
2871
|
+
interface UpdateRiskSettingsParams {
|
|
2872
|
+
review_threshold?: number;
|
|
2873
|
+
block_threshold?: number;
|
|
2874
|
+
disabled_reasons?: RiskReasonCode[];
|
|
2875
|
+
/** `null` turns captcha verification off and deletes the secret. */
|
|
2876
|
+
captcha?: {
|
|
2877
|
+
provider: RiskCaptchaProvider;
|
|
2878
|
+
/** Required when setting a provider for the first time or changing it. */
|
|
2879
|
+
secret?: string;
|
|
2880
|
+
/** Assessments without a token get `captcha.missing`. */
|
|
2881
|
+
required?: boolean;
|
|
2882
|
+
} | null;
|
|
2883
|
+
/** Changes the categories given: a score in (0, 1] sets the threshold, `null` removes it. */
|
|
2884
|
+
content_thresholds?: Partial<Record<RiskContentCategory, number | null>>;
|
|
2885
|
+
/**
|
|
2886
|
+
* Changes the reasons given: a weight in [0, 0.99] replaces the default (for example
|
|
2887
|
+
* calibration's `suggested_weight`), `null` restores it. Not `list.*` or `rule.matched`.
|
|
2888
|
+
*/
|
|
2889
|
+
reason_weights?: Partial<Record<RiskReasonCode, number | null>>;
|
|
2890
|
+
}
|
|
2891
|
+
/** Feedback counted against one reason or rule (`fraud` includes `abuse`). */
|
|
2892
|
+
interface RiskCalibrationCounts {
|
|
2893
|
+
fraud: number;
|
|
2894
|
+
legitimate: number;
|
|
2895
|
+
/** `fraud / (fraud + legitimate)`; `null` without feedback. */
|
|
2896
|
+
precision: number | null;
|
|
2897
|
+
}
|
|
2898
|
+
/** How often each reason and rule was right over the last 90 days, by your feedback. */
|
|
2899
|
+
interface RiskCalibration {
|
|
2900
|
+
object: "risk_calibration";
|
|
2901
|
+
window_days: number;
|
|
2902
|
+
/** Assessments in the window. */
|
|
2903
|
+
assessments: number;
|
|
2904
|
+
/** Of those, with feedback. */
|
|
2905
|
+
labeled: number;
|
|
2906
|
+
reasons: (RiskCalibrationCounts & {
|
|
2907
|
+
code: RiskReasonCode;
|
|
2908
|
+
/** Assessments it fired in. */
|
|
2909
|
+
fired: number;
|
|
2910
|
+
default_weight: number;
|
|
2911
|
+
/** Its weight in this environment now. */
|
|
2912
|
+
weight: number;
|
|
2913
|
+
/** What feedback supports; `null` with fewer than 20 assessments with feedback. */
|
|
2914
|
+
suggested_weight: number | null;
|
|
2915
|
+
})[];
|
|
2916
|
+
rules: (RiskCalibrationCounts & {
|
|
2917
|
+
rule: string;
|
|
2918
|
+
name: string;
|
|
2919
|
+
/** Assessments it decided. */
|
|
2920
|
+
matched: number;
|
|
2921
|
+
})[];
|
|
2922
|
+
}
|
|
2923
|
+
/** A field a rule condition can test (see the rules guide). */
|
|
2924
|
+
type RiskRuleField = "email.valid" | "email.disposable" | "email.undeliverable" | "email.role_account" | "email.free_provider" | "email.typo" | "email.domain_new" | "email.domain" | "email.domain_age_days" | "ip.tor" | "ip.hosting" | "ip.vpn" | "ip.proxy" | "ip.relay" | "ip.private" | "ip.country" | "ip.asn" | "ip.hosting_provider" | "captcha.passed" | "duplicate.canonical_mailbox" | "duplicate.device" | "history.fraud" | "login.new_country" | "login.new_network" | "content.spam" | "content.phishing" | "content.malware" | "content.fraud" | "checkout.amount" | "checkout.currency" | "checkout.card_country" | "checkout.card_funding" | "checkout.billing_country" | "checkout.shipping_country" | "device.automation" | "device.timezone" | "device.language" | "score" | "velocity.ip_1h" | "velocity.ip_24h" | "velocity.subnet_1h" | "velocity.subnet_24h" | "velocity.email_domain_1h" | "velocity.email_domain_24h" | "velocity.mailbox_1h" | "velocity.mailbox_24h" | "velocity.user_1h" | "velocity.user_24h" | "velocity.card_1h" | "velocity.card_24h" | "velocity.device_1h" | "velocity.device_24h";
|
|
2925
|
+
/** A test of one field. A field without a value (no IP, no email…) never matches. */
|
|
2926
|
+
interface RiskRuleCondition {
|
|
2927
|
+
field: RiskRuleField;
|
|
2928
|
+
/** `is` (booleans); `eq`, `neq`, `gt`, `gte`, `lt`, `lte` (numbers); `eq`, `neq`, `in`, `not_in` (strings). */
|
|
2929
|
+
operator: "is" | "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" | "not_in";
|
|
2930
|
+
value: boolean | number | string | string[];
|
|
2931
|
+
}
|
|
2932
|
+
/** A rule: the first enabled one whose conditions match decides (after the lists). */
|
|
2933
|
+
interface RiskRule {
|
|
2934
|
+
object: "risk_rule";
|
|
2935
|
+
id: string;
|
|
2936
|
+
name: string;
|
|
2937
|
+
enabled: boolean;
|
|
2938
|
+
/** Rules are tried in ascending order. */
|
|
2939
|
+
position: number;
|
|
2940
|
+
/** Events it applies to; empty: every event. */
|
|
2941
|
+
events: RiskEvent[];
|
|
2942
|
+
/** `all`: every condition must hold. `any`: one is enough. */
|
|
2943
|
+
match: "all" | "any";
|
|
2944
|
+
conditions: RiskRuleCondition[];
|
|
2945
|
+
action: RiskDecision;
|
|
2946
|
+
/** ISO 8601 timestamp. */
|
|
2947
|
+
created_at: string;
|
|
2948
|
+
/** ISO 8601 timestamp. */
|
|
2949
|
+
updated_at: string;
|
|
2950
|
+
}
|
|
2951
|
+
/** Body of `POST /v1/risk/rules`. */
|
|
2952
|
+
interface CreateRiskRuleParams {
|
|
2953
|
+
name: string;
|
|
2954
|
+
enabled?: boolean;
|
|
2955
|
+
/** Default 0. */
|
|
2956
|
+
position?: number;
|
|
2957
|
+
events?: RiskEvent[];
|
|
2958
|
+
/** Default `all`. */
|
|
2959
|
+
match?: "all" | "any";
|
|
2960
|
+
conditions: RiskRuleCondition[];
|
|
2961
|
+
action: RiskDecision;
|
|
2962
|
+
}
|
|
2963
|
+
/** Body of `PATCH /v1/risk/rules/{id}`: only the fields given change. */
|
|
2964
|
+
type UpdateRiskRuleParams = Partial<CreateRiskRuleParams>;
|
|
2965
|
+
/** Response of `DELETE /v1/risk/rules/{id}`. */
|
|
2966
|
+
interface DeletedRiskRule {
|
|
2967
|
+
object: "risk_rule";
|
|
2968
|
+
id: string;
|
|
2969
|
+
deleted: true;
|
|
2970
|
+
}
|
|
2971
|
+
/** Result of `coss.risk.checkEmail()`: what coss.com knows about an address. Nothing is stored. */
|
|
2972
|
+
interface RiskEmailCheck {
|
|
2973
|
+
object: "risk_email_check";
|
|
2974
|
+
email: string;
|
|
2975
|
+
valid: boolean;
|
|
2976
|
+
domain: string | null;
|
|
2977
|
+
/** The mailbox with the provider's aliasing folded (dots and `+tags` at Gmail…). */
|
|
2978
|
+
canonical: string | null;
|
|
2979
|
+
disposable: boolean;
|
|
2980
|
+
/** From DNS (MX, A, AAAA). `unknown` when the lookup failed or timed out. */
|
|
2981
|
+
deliverability: "deliverable" | "undeliverable" | "unknown";
|
|
2982
|
+
role_account: boolean;
|
|
2983
|
+
free_provider: boolean;
|
|
2984
|
+
/** The likely intended domain when this one looks like a typo of a popular one. */
|
|
2985
|
+
suggestion: string | null;
|
|
2986
|
+
/** Days since the domain was registered (RDAP); `null` when unknown or not looked up. */
|
|
2987
|
+
domain_age_days: number | null;
|
|
2988
|
+
/** Lookups that failed or timed out. */
|
|
2989
|
+
degraded: ("email_dns" | "domain_age")[];
|
|
2990
|
+
}
|
|
2991
|
+
/** Result of `coss.risk.checkIp()`. Nothing is stored. */
|
|
2992
|
+
interface RiskIpCheck extends RiskIpSignals {
|
|
2993
|
+
object: "risk_ip_check";
|
|
2994
|
+
ip: string;
|
|
2995
|
+
/**
|
|
2996
|
+
* `ip_data` when some IP data is unavailable at the moment; `ip_privacy` when the privacy data
|
|
2997
|
+
* provider failed or timed out.
|
|
2998
|
+
*/
|
|
2999
|
+
degraded: ("ip_data" | "ip_privacy")[];
|
|
3000
|
+
}
|
|
3001
|
+
/** Result of `coss.risk.classify()`: scores only, neither stored nor logged. */
|
|
3002
|
+
interface RiskContentClassification {
|
|
3003
|
+
object: "risk_content_classification";
|
|
3004
|
+
scores: RiskContentScores;
|
|
3005
|
+
/** The text was longer than the model reads (8,000 characters): only its beginning counted. */
|
|
3006
|
+
truncated: boolean;
|
|
3007
|
+
}
|
|
3008
|
+
/** What `on_failure` answers while coss.com can't count. */
|
|
3009
|
+
type RiskLimitFailureMode = "allow" | "deny";
|
|
3010
|
+
/** One of your rate limit buckets: each key gets `burst` tokens, refilling `limit` per period. */
|
|
3011
|
+
interface RiskLimitBucket {
|
|
3012
|
+
object: "risk_limit_bucket";
|
|
3013
|
+
id: string;
|
|
3014
|
+
/** What `coss.risk.limit({ bucket })` names it by. */
|
|
3015
|
+
name: string;
|
|
3016
|
+
/** Tokens added per `period_seconds`. */
|
|
3017
|
+
limit: number;
|
|
3018
|
+
period_seconds: number;
|
|
3019
|
+
/** How many requests a key can make at once. */
|
|
3020
|
+
burst: number;
|
|
3021
|
+
on_failure: RiskLimitFailureMode;
|
|
3022
|
+
/** ISO 8601 timestamp. */
|
|
3023
|
+
created_at: string;
|
|
3024
|
+
/** ISO 8601 timestamp. */
|
|
3025
|
+
updated_at: string;
|
|
3026
|
+
}
|
|
3027
|
+
/** Body of `POST /v1/risk/limit_buckets`. */
|
|
3028
|
+
interface CreateRiskLimitBucketParams {
|
|
3029
|
+
/** 1-64 lower-case letters, digits, `.`, `_` or `-`; unique in the environment. */
|
|
3030
|
+
name: string;
|
|
3031
|
+
limit: number;
|
|
3032
|
+
/** 1 second to 1 day. */
|
|
3033
|
+
period_seconds: number;
|
|
3034
|
+
/** Defaults to `limit`. */
|
|
3035
|
+
burst?: number;
|
|
3036
|
+
/** Defaults to `allow`. */
|
|
3037
|
+
on_failure?: RiskLimitFailureMode;
|
|
3038
|
+
}
|
|
3039
|
+
/** Body of `PATCH /v1/risk/limit_buckets/{id}` (the name can't change). */
|
|
3040
|
+
type UpdateRiskLimitBucketParams = Partial<Omit<CreateRiskLimitBucketParams, "name">>;
|
|
3041
|
+
interface DeletedRiskLimitBucket {
|
|
3042
|
+
object: "risk_limit_bucket";
|
|
3043
|
+
id: string;
|
|
3044
|
+
deleted: true;
|
|
3045
|
+
}
|
|
3046
|
+
/** Body of `POST /v1/risk/limits`. */
|
|
3047
|
+
interface CheckRiskLimitParams {
|
|
3048
|
+
/** The bucket's name. */
|
|
3049
|
+
bucket: string;
|
|
3050
|
+
/** Who or what is limited (a user id, an email or IP address…); coss.com keeps only a hash. */
|
|
3051
|
+
key: string;
|
|
3052
|
+
/** Tokens this request takes. Default 1. */
|
|
3053
|
+
cost?: number;
|
|
3054
|
+
}
|
|
3055
|
+
/** Result of `coss.risk.limit()`. */
|
|
3056
|
+
interface RiskLimit {
|
|
3057
|
+
object: "risk_limit";
|
|
3058
|
+
bucket: string;
|
|
3059
|
+
/** Whether to let the request through. Denied requests take no tokens. */
|
|
3060
|
+
allowed: boolean;
|
|
3061
|
+
/** The bucket's size (`burst`). */
|
|
3062
|
+
limit: number;
|
|
3063
|
+
/** Tokens left for this key. */
|
|
3064
|
+
remaining: number;
|
|
3065
|
+
/** Milliseconds until the key's bucket is full again. */
|
|
3066
|
+
reset_ms: number;
|
|
3067
|
+
/** When denied: milliseconds until the same request would fit; `null` if it never would. */
|
|
3068
|
+
retry_after_ms: number | null;
|
|
3069
|
+
/** coss.com couldn't count: `allowed` is the bucket's `on_failure`. */
|
|
3070
|
+
degraded: boolean;
|
|
3071
|
+
}
|
|
3072
|
+
//#endregion
|
|
3073
|
+
//#region src/resources/risk.d.ts
|
|
3074
|
+
type ReadOptions$3 = Pick<RequestOptions, "signal">;
|
|
3075
|
+
/** `coss.risk.assessments`: reading past assessments (`assess` lives on `coss.risk`). */
|
|
3076
|
+
declare class RiskAssessmentsResource {
|
|
3077
|
+
#private;
|
|
3078
|
+
/** @internal Use `new Coss().risk.assessments`. */
|
|
3079
|
+
constructor(http: HttpClient);
|
|
3080
|
+
/** Retrieves one assessment. */
|
|
3081
|
+
get(id: string, options?: ReadOptions$3): Promise<CossResult<RiskAssessment>>;
|
|
3082
|
+
/**
|
|
3083
|
+
* Lists assessments, newest first (`review_status: "open"` is the review queue). Pass the last
|
|
3084
|
+
* `id` as `after` while `has_more` is true.
|
|
3085
|
+
*/
|
|
3086
|
+
list(params?: ListRiskAssessmentsParams, options?: ReadOptions$3): Promise<CossResult<List<RiskAssessment>>>;
|
|
3087
|
+
}
|
|
3088
|
+
/** `coss.risk.lists`: the environment's allow and block lists. */
|
|
3089
|
+
declare class RiskListsResource {
|
|
3090
|
+
#private;
|
|
3091
|
+
/** @internal Use `new Coss().risk.lists`. */
|
|
3092
|
+
constructor(http: HttpClient);
|
|
3093
|
+
/**
|
|
3094
|
+
* Adds an entry: `coss.risk.lists.add("block", { domain: "evil.example" })`. An allow-list match
|
|
3095
|
+
* makes decisions `allow`, a block-list match `block`. Returns the existing entry if there is one.
|
|
3096
|
+
*/
|
|
3097
|
+
add(list: RiskList, entry: RiskListEntryValue & {
|
|
3098
|
+
note?: string;
|
|
3099
|
+
expires_at?: string | Date;
|
|
3100
|
+
}, options?: RequestOptions): Promise<CossResult<RiskListEntry>>;
|
|
3101
|
+
/** Lists entries, newest first. Pass the last `id` as `after` while `has_more` is true. */
|
|
3102
|
+
list(params?: ListRiskListEntriesParams, options?: ReadOptions$3): Promise<CossResult<List<RiskListEntry>>>;
|
|
3103
|
+
/** Retrieves one entry. */
|
|
3104
|
+
get(id: string, options?: ReadOptions$3): Promise<CossResult<RiskListEntry>>;
|
|
3105
|
+
/** Removes an entry. */
|
|
3106
|
+
remove(id: string, options?: ReadOptions$3): Promise<CossResult<DeletedRiskListEntry>>;
|
|
3107
|
+
}
|
|
3108
|
+
/** `coss.risk.settings`: the environment's thresholds, disabled reasons and captcha provider. */
|
|
3109
|
+
declare class RiskSettingsResource {
|
|
3110
|
+
#private;
|
|
3111
|
+
/** @internal Use `new Coss().risk.settings`. */
|
|
3112
|
+
constructor(http: HttpClient);
|
|
3113
|
+
get(options?: ReadOptions$3): Promise<CossResult<RiskSettings>>;
|
|
3114
|
+
/** Changes the fields given. The captcha secret is write-only. */
|
|
3115
|
+
update(params: UpdateRiskSettingsParams, options?: ReadOptions$3): Promise<CossResult<RiskSettings>>;
|
|
3116
|
+
}
|
|
3117
|
+
/**
|
|
3118
|
+
* `coss.risk.rules`: the environment's rules. After the lists, the first enabled rule whose
|
|
3119
|
+
* conditions match an event decides it.
|
|
3120
|
+
*/
|
|
3121
|
+
declare class RiskRulesResource {
|
|
3122
|
+
#private;
|
|
3123
|
+
/** @internal Use `new Coss().risk.rules`. */
|
|
3124
|
+
constructor(http: HttpClient);
|
|
3125
|
+
/** Creates a rule. Not retried automatically: a retry could create it twice. */
|
|
3126
|
+
create(params: CreateRiskRuleParams, options?: ReadOptions$3): Promise<CossResult<RiskRule>>;
|
|
3127
|
+
/** Every rule, in evaluation order. */
|
|
3128
|
+
list(options?: ReadOptions$3): Promise<CossResult<List<RiskRule>>>;
|
|
3129
|
+
get(id: string, options?: ReadOptions$3): Promise<CossResult<RiskRule>>;
|
|
3130
|
+
/** Changes the fields given; `conditions` replaces the whole list. */
|
|
3131
|
+
update(id: string, params: UpdateRiskRuleParams, options?: ReadOptions$3): Promise<CossResult<RiskRule>>;
|
|
3132
|
+
delete(id: string, options?: ReadOptions$3): Promise<CossResult<DeletedRiskRule>>;
|
|
3133
|
+
}
|
|
3134
|
+
/**
|
|
3135
|
+
* `coss.risk.limitBuckets`: your rate limit buckets, which `coss.risk.limit()` charges per key.
|
|
3136
|
+
*/
|
|
3137
|
+
declare class RiskLimitBucketsResource {
|
|
3138
|
+
#private;
|
|
3139
|
+
/** @internal Use `new Coss().risk.limitBuckets`. */
|
|
3140
|
+
constructor(http: HttpClient);
|
|
3141
|
+
/** Creates a bucket. Not retried automatically: a retry would find its name taken. */
|
|
3142
|
+
create(params: CreateRiskLimitBucketParams, options?: ReadOptions$3): Promise<CossResult<RiskLimitBucket>>;
|
|
3143
|
+
/** Every bucket, by name. */
|
|
3144
|
+
list(options?: ReadOptions$3): Promise<CossResult<List<RiskLimitBucket>>>;
|
|
3145
|
+
get(id: string, options?: ReadOptions$3): Promise<CossResult<RiskLimitBucket>>;
|
|
3146
|
+
/** Changes the fields given; the next check uses them. */
|
|
3147
|
+
update(id: string, params: UpdateRiskLimitBucketParams, options?: ReadOptions$3): Promise<CossResult<RiskLimitBucket>>;
|
|
3148
|
+
delete(id: string, options?: ReadOptions$3): Promise<CossResult<DeletedRiskLimitBucket>>;
|
|
3149
|
+
}
|
|
3150
|
+
/** `coss.risk.users`: what coss.com remembers about your users. */
|
|
3151
|
+
declare class RiskUsersResource {
|
|
3152
|
+
#private;
|
|
3153
|
+
/** @internal Use `new Coss().risk.users`. */
|
|
3154
|
+
constructor(http: HttpClient);
|
|
3155
|
+
/**
|
|
3156
|
+
* Call when you delete a user: coss.com deletes what identifies them (their mailbox, fraud reports,
|
|
3157
|
+
* and the user id, email, IP and user agent on their assessments). Safe to repeat.
|
|
3158
|
+
*/
|
|
3159
|
+
forget(userId: string, options?: ReadOptions$3): Promise<CossResult<ForgottenRiskUser>>;
|
|
3160
|
+
}
|
|
3161
|
+
/**
|
|
3162
|
+
* `coss.risk`: assess sign-ups, logins and other events. Call it from your server and treat an
|
|
3163
|
+
* error as `allow` (fail open), so an outage never locks your users out.
|
|
3164
|
+
*
|
|
3165
|
+
* ```ts
|
|
3166
|
+
* const { data } = await coss.risk.assess({ event: "signup", user: { email }, ip, user_agent });
|
|
3167
|
+
* if (data?.decision === "block") return refuse();
|
|
3168
|
+
* ```
|
|
3169
|
+
*/
|
|
3170
|
+
declare class RiskResource {
|
|
3171
|
+
#private;
|
|
3172
|
+
/** Past assessments (`get`, `list`). */
|
|
3173
|
+
readonly assessments: RiskAssessmentsResource;
|
|
3174
|
+
/** Allow and block lists (`add`, `list`, `get`, `remove`). */
|
|
3175
|
+
readonly lists: RiskListsResource;
|
|
3176
|
+
/** Forgetting deleted users. */
|
|
3177
|
+
readonly users: RiskUsersResource;
|
|
3178
|
+
/** Thresholds, disabled reasons and the captcha provider (`get`, `update`). */
|
|
3179
|
+
readonly settings: RiskSettingsResource;
|
|
3180
|
+
/** Rules (`create`, `list`, `get`, `update`, `delete`). */
|
|
3181
|
+
readonly rules: RiskRulesResource;
|
|
3182
|
+
/** Your rate limit buckets (`create`, `list`, `get`, `update`, `delete`). */
|
|
3183
|
+
readonly limitBuckets: RiskLimitBucketsResource;
|
|
3184
|
+
/** @internal Use `new Coss().risk`. */
|
|
3185
|
+
constructor(http: HttpClient);
|
|
3186
|
+
/**
|
|
3187
|
+
* Assesses an event and returns the decision with its score and reasons. Retries reuse one
|
|
3188
|
+
* `Idempotency-Key`, so an event is never counted twice.
|
|
3189
|
+
*/
|
|
3190
|
+
assess(params: AssessRiskParams, options?: RequestOptions): Promise<CossResult<RiskAssessment>>;
|
|
3191
|
+
/**
|
|
3192
|
+
* Reports what an assessed user turned out to be: `fraud` and `abuse` teach later assessments to
|
|
3193
|
+
* flag the same mailbox, user, card, device, IP and subnet; `legitimate` takes that back.
|
|
3194
|
+
* Resolves a review, and counts in `calibration()`.
|
|
3195
|
+
*/
|
|
3196
|
+
feedback(id: string, params: RiskFeedbackParams, options?: RequestOptions): Promise<CossResult<RiskAssessment>>;
|
|
3197
|
+
/**
|
|
3198
|
+
* How often each reason and rule was right over the last 90 days, by your feedback, and the
|
|
3199
|
+
* reason weights that supports. Apply them with `settings.update({ reason_weights })`.
|
|
3200
|
+
*/
|
|
3201
|
+
calibration(options?: ReadOptions$3): Promise<CossResult<RiskCalibration>>;
|
|
3202
|
+
/**
|
|
3203
|
+
* Checks an email address on its own: syntax, disposable domains, deliverability, role
|
|
3204
|
+
* accounts, free providers, the canonical mailbox, typos and domain age. Nothing is stored.
|
|
3205
|
+
*/
|
|
3206
|
+
checkEmail(email: string, options?: ReadOptions$3): Promise<CossResult<RiskEmailCheck>>;
|
|
3207
|
+
/**
|
|
3208
|
+
* Checks an IP address on its own: Tor, cloud, hosting and VPN networks, ASN and country, and
|
|
3209
|
+
* VPN, proxy and relay exits when coss.com's privacy data is available.
|
|
3210
|
+
*/
|
|
3211
|
+
checkIp(ip: string, options?: ReadOptions$3): Promise<CossResult<RiskIpCheck>>;
|
|
3212
|
+
/**
|
|
3213
|
+
* Scores text for spam, phishing, malware and fraud. Scores only, never a verdict: you choose
|
|
3214
|
+
* the thresholds. The text is neither stored nor logged.
|
|
3215
|
+
*/
|
|
3216
|
+
classify(params: {
|
|
3217
|
+
text: string;
|
|
3218
|
+
}, options?: ReadOptions$3): Promise<CossResult<RiskContentClassification>>;
|
|
3219
|
+
/**
|
|
3220
|
+
* Takes `cost` tokens (default 1) from `key`'s share of one of your buckets
|
|
3221
|
+
* (`coss.risk.limitBuckets`). Retries reuse one `Idempotency-Key`, so they are charged once.
|
|
3222
|
+
*
|
|
3223
|
+
* ```ts
|
|
3224
|
+
* const { data } = await coss.risk.limit({ bucket: "password_reset", key: email });
|
|
3225
|
+
* if (data && !data.allowed) return tooManyRequests(data.retry_after_ms);
|
|
3226
|
+
* ```
|
|
3227
|
+
*/
|
|
3228
|
+
limit(params: CheckRiskLimitParams, options?: RequestOptions): Promise<CossResult<RiskLimit>>;
|
|
3229
|
+
}
|
|
3230
|
+
//#endregion
|
|
3231
|
+
//#region src/types/webhook.d.ts
|
|
3232
|
+
/** What a webhook says about the email; never its content, cc or bcc. */
|
|
3233
|
+
interface EmailWebhookEventData extends EmailEventData {
|
|
3234
|
+
email_id: string;
|
|
3235
|
+
from: string;
|
|
3236
|
+
to: string[];
|
|
3237
|
+
subject: string;
|
|
3238
|
+
tags: EmailTag[];
|
|
3239
|
+
category: string | null;
|
|
3240
|
+
/** `true` for emails sent with a sandbox (`coss_test_…`) key. */
|
|
3241
|
+
sandbox: boolean;
|
|
3242
|
+
/** The recipient this event is about; `null` for the whole email. */
|
|
3243
|
+
recipient: string | null;
|
|
3244
|
+
/** ISO 8601 timestamp of the event itself (deliveries can arrive later, and out of order). */
|
|
3245
|
+
occurred_at: string;
|
|
3246
|
+
}
|
|
3247
|
+
/** An email event. `id` equals the `webhook-id` header and `EmailEvent.id`. */
|
|
3248
|
+
interface EmailWebhookEvent {
|
|
3249
|
+
id: string;
|
|
3250
|
+
object: "event";
|
|
3251
|
+
type: EmailEventType;
|
|
3252
|
+
/** The API version this event is rendered in: the receiving endpoint's `api_version`. */
|
|
3253
|
+
api_version: string;
|
|
3254
|
+
/** ISO 8601 timestamp. */
|
|
3255
|
+
created_at: string;
|
|
3256
|
+
data: EmailWebhookEventData;
|
|
3257
|
+
}
|
|
3258
|
+
/** Events about received (inbound) emails. */
|
|
3259
|
+
type ReceivedEmailEventType = "email.received";
|
|
3260
|
+
/** What a webhook says about a received email; never its content, headers or cc. */
|
|
3261
|
+
interface ReceivedEmailWebhookEventData {
|
|
3262
|
+
/** Retrieve the email (bodies, headers, attachments) with `coss.email.received.get`. */
|
|
3263
|
+
received_email_id: string;
|
|
3264
|
+
/** The `From` header. */
|
|
3265
|
+
from: string | null;
|
|
3266
|
+
/** The `To` header's addresses. */
|
|
3267
|
+
to: string[];
|
|
3268
|
+
/** The envelope recipients this environment received it for. */
|
|
3269
|
+
recipients: string[];
|
|
3270
|
+
subject: string | null;
|
|
3271
|
+
message_id: string | null;
|
|
3272
|
+
attachment_count: number;
|
|
3273
|
+
size: number;
|
|
3274
|
+
/** Whether the spam verdict is `fail`. */
|
|
3275
|
+
spam: boolean;
|
|
3276
|
+
verdicts: ReceivedEmailVerdicts;
|
|
3277
|
+
sandbox: boolean;
|
|
3278
|
+
/** ISO 8601 timestamp. */
|
|
3279
|
+
received_at: string;
|
|
3280
|
+
}
|
|
3281
|
+
/** An email arrived. `id` equals the `webhook-id` header. */
|
|
3282
|
+
interface ReceivedEmailWebhookEvent {
|
|
3283
|
+
id: string;
|
|
3284
|
+
object: "event";
|
|
3285
|
+
type: ReceivedEmailEventType;
|
|
3286
|
+
/** The API version this event is rendered in: the receiving endpoint's `api_version`. */
|
|
3287
|
+
api_version: string;
|
|
3288
|
+
/** ISO 8601 timestamp. */
|
|
3289
|
+
created_at: string;
|
|
3290
|
+
data: ReceivedEmailWebhookEventData;
|
|
3291
|
+
}
|
|
3292
|
+
/** Events about the organization's domains (sent to live environments only). */
|
|
3293
|
+
type DomainEventType = "domain.dmarc_report_received";
|
|
3294
|
+
/** What a webhook says about a DMARC report; never its rows or source addresses. */
|
|
3295
|
+
interface DomainWebhookEventData {
|
|
3296
|
+
organization_id: string;
|
|
3297
|
+
domain_id: string;
|
|
3298
|
+
domain: string;
|
|
3299
|
+
/** Retrieve the report (its rows) with `coss.domains.dmarc.reports.get`. */
|
|
3300
|
+
dmarc_report_id: string;
|
|
3301
|
+
/** The reporting organization (`org_name`). */
|
|
3302
|
+
reporter: string;
|
|
3303
|
+
/** ISO 8601 timestamps of the period the report covers. */
|
|
3304
|
+
period_start: string;
|
|
3305
|
+
period_end: string;
|
|
3306
|
+
messages: number;
|
|
3307
|
+
passing: number;
|
|
3308
|
+
/** ISO 8601 timestamp. */
|
|
3309
|
+
occurred_at: string;
|
|
3310
|
+
}
|
|
3311
|
+
/** A DMARC aggregate report about a domain arrived. `id` equals the `webhook-id` header. */
|
|
3312
|
+
interface DomainWebhookEvent {
|
|
3313
|
+
id: string;
|
|
3314
|
+
object: "event";
|
|
3315
|
+
type: DomainEventType;
|
|
3316
|
+
/** The API version this event is rendered in: the receiving endpoint's `api_version`. */
|
|
3317
|
+
api_version: string;
|
|
3318
|
+
/** ISO 8601 timestamp. */
|
|
3319
|
+
created_at: string;
|
|
3320
|
+
data: DomainWebhookEventData;
|
|
3321
|
+
}
|
|
3322
|
+
/** Changes of the organization's reputation standing (sent to live environments only). */
|
|
3323
|
+
type AccountEventType = "account.reputation_warning" | "account.reputation_recovered" | "account.suspended" | "account.reinstated";
|
|
3324
|
+
interface AccountWebhookEventData {
|
|
3325
|
+
organization_id: string;
|
|
3326
|
+
status: ReputationStatus;
|
|
3327
|
+
previous_status: ReputationStatus;
|
|
3328
|
+
/** The trigger behind a `warning` or `suspended` status, e.g. `complaint_rate`. */
|
|
3329
|
+
reason: string | null;
|
|
3330
|
+
/** ISO 8601 timestamp. */
|
|
3331
|
+
occurred_at: string;
|
|
3332
|
+
/** The measurements behind the change (see `coss.reputation.get()`). */
|
|
3333
|
+
checks: ReputationCheck[];
|
|
3334
|
+
}
|
|
3335
|
+
/** A reputation change. `id` equals the `webhook-id` header. */
|
|
3336
|
+
interface AccountWebhookEvent {
|
|
3337
|
+
id: string;
|
|
3338
|
+
object: "event";
|
|
3339
|
+
type: AccountEventType;
|
|
3340
|
+
/** The API version this event is rendered in: the receiving endpoint's `api_version`. */
|
|
3341
|
+
api_version: string;
|
|
3342
|
+
/** ISO 8601 timestamp. */
|
|
3343
|
+
created_at: string;
|
|
3344
|
+
data: AccountWebhookEventData;
|
|
3345
|
+
}
|
|
3346
|
+
/** Billing events (organization-wide; sent to live environments only). */
|
|
3347
|
+
type BillingEventType = "billing.invoice_finalized" | "billing.invoice_paid" | "billing.invoice_payment_failed" | "billing.invoice_voided" | "billing.plan_changed" | "billing.usage_threshold_reached" | "billing.hold_placed" | "billing.hold_lifted" | "billing.credit_granted";
|
|
3348
|
+
interface BillingEventFields {
|
|
3349
|
+
/** Equals the `webhook-id` header. */
|
|
3350
|
+
id: string;
|
|
3351
|
+
object: "event";
|
|
3352
|
+
/** The API version this event is rendered in: the receiving endpoint's `api_version`. */
|
|
3353
|
+
api_version: string;
|
|
3354
|
+
/** ISO 8601 timestamp. */
|
|
3355
|
+
created_at: string;
|
|
3356
|
+
}
|
|
3357
|
+
/** Every billing event's `data` has these. */
|
|
3358
|
+
interface BillingEventData {
|
|
3359
|
+
organization_id: string;
|
|
3360
|
+
/** When it happened (ISO 8601): sort events by it. */
|
|
3361
|
+
occurred_at: string;
|
|
3362
|
+
}
|
|
3363
|
+
/** A billing event; narrow on `type` for its `data`. */
|
|
3364
|
+
type BillingWebhookEvent = (BillingEventFields & {
|
|
3365
|
+
type: "billing.invoice_finalized" | "billing.invoice_paid" | "billing.invoice_voided";
|
|
3366
|
+
data: BillingEventData & {
|
|
3367
|
+
invoice: InvoiceSummary;
|
|
3368
|
+
};
|
|
3369
|
+
}) | (BillingEventFields & {
|
|
3370
|
+
type: "billing.invoice_payment_failed";
|
|
3371
|
+
data: BillingEventData & {
|
|
3372
|
+
invoice: InvoiceSummary;
|
|
3373
|
+
failure: {
|
|
3374
|
+
message: string;
|
|
3375
|
+
};
|
|
3376
|
+
};
|
|
3377
|
+
}) | (BillingEventFields & {
|
|
3378
|
+
type: "billing.plan_changed";
|
|
3379
|
+
data: BillingEventData & {
|
|
3380
|
+
/**
|
|
3381
|
+
* `upgrade` (in effect now), `downgrade`/`cancellation` (scheduled), `reverted` (a
|
|
3382
|
+
* scheduled change was undone), `contract` (a contract changed).
|
|
3383
|
+
*/
|
|
3384
|
+
change: "upgrade" | "downgrade" | "cancellation" | "reverted" | "contract";
|
|
3385
|
+
/** The plan from `effective_at`. */
|
|
3386
|
+
plan: PlanKey;
|
|
3387
|
+
previous_plan: PlanKey;
|
|
3388
|
+
effective_at: string;
|
|
3389
|
+
};
|
|
3390
|
+
}) | (BillingEventFields & {
|
|
3391
|
+
type: "billing.usage_threshold_reached";
|
|
3392
|
+
data: BillingEventData & {
|
|
3393
|
+
/** The threshold crossed, e.g. 80. */
|
|
3394
|
+
percent: number;
|
|
3395
|
+
/** `credit`: the month's usage credit; `allowance`: a capped plan's included units. */
|
|
3396
|
+
of: "credit" | "allowance";
|
|
3397
|
+
meter: Meter | null;
|
|
3398
|
+
period: {
|
|
3399
|
+
start: string;
|
|
3400
|
+
end: string;
|
|
3401
|
+
};
|
|
3402
|
+
};
|
|
3403
|
+
}) | (BillingEventFields & {
|
|
3404
|
+
type: "billing.hold_placed" | "billing.hold_lifted";
|
|
3405
|
+
data: BillingEventData & {
|
|
3406
|
+
reason: BillingHoldReason;
|
|
3407
|
+
};
|
|
3408
|
+
}) | (BillingEventFields & {
|
|
3409
|
+
type: "billing.credit_granted";
|
|
3410
|
+
data: BillingEventData & {
|
|
3411
|
+
credit: Credit;
|
|
3412
|
+
};
|
|
3413
|
+
});
|
|
3414
|
+
/** Risk events: `review` decisions, and their resolution, for a queue you work through. */
|
|
3415
|
+
type RiskEventType = "risk.assessment.review" | "risk.assessment.reviewed";
|
|
3416
|
+
interface RiskWebhookEventData {
|
|
3417
|
+
assessment_id: string;
|
|
3418
|
+
event: RiskEvent;
|
|
3419
|
+
event_name: string | null;
|
|
3420
|
+
decision: RiskDecision;
|
|
3421
|
+
score: number;
|
|
3422
|
+
reasons: RiskReason[];
|
|
3423
|
+
/** Your user id, if the assessment had one. Never the email or IP address. */
|
|
3424
|
+
user_id: string | null;
|
|
3425
|
+
/** `risk.assessment.reviewed`: the outcome that resolved the review. */
|
|
3426
|
+
outcome: RiskOutcome | null;
|
|
3427
|
+
/** ISO 8601 timestamp. */
|
|
3428
|
+
occurred_at: string;
|
|
3429
|
+
}
|
|
3430
|
+
/** A risk review opened or resolved. `id` equals the `webhook-id` header. */
|
|
3431
|
+
interface RiskWebhookEvent {
|
|
3432
|
+
id: string;
|
|
3433
|
+
object: "event";
|
|
3434
|
+
type: RiskEventType;
|
|
3435
|
+
/** The API version this event is rendered in: the receiving endpoint's `api_version`. */
|
|
3436
|
+
api_version: string;
|
|
3437
|
+
/** ISO 8601 timestamp. */
|
|
3438
|
+
created_at: string;
|
|
3439
|
+
data: RiskWebhookEventData;
|
|
3440
|
+
}
|
|
3441
|
+
/** Events about Hooks: an endpoint of one of your applications was disabled for failing. */
|
|
3442
|
+
type HookOperationalEventType = "hook_endpoint.disabled";
|
|
3443
|
+
interface HookEndpointWebhookEventData {
|
|
3444
|
+
application_id: string;
|
|
3445
|
+
/** Your uid for the application, when it has one. */
|
|
3446
|
+
application_uid: string | null;
|
|
3447
|
+
endpoint_id: string;
|
|
3448
|
+
url: string;
|
|
3449
|
+
/** ISO 8601 timestamp: when its deliveries started failing every attempt. */
|
|
3450
|
+
failing_since: string;
|
|
3451
|
+
/** ISO 8601 timestamp. */
|
|
3452
|
+
occurred_at: string;
|
|
3453
|
+
}
|
|
3454
|
+
/** A Hooks endpoint of one of your applications was disabled. `id` equals the `webhook-id` header. */
|
|
3455
|
+
interface HookEndpointWebhookEvent {
|
|
3456
|
+
id: string;
|
|
3457
|
+
object: "event";
|
|
3458
|
+
type: HookOperationalEventType;
|
|
3459
|
+
/** The API version this event is rendered in: the receiving endpoint's `api_version`. */
|
|
3460
|
+
api_version: string;
|
|
3461
|
+
/** ISO 8601 timestamp. */
|
|
3462
|
+
created_at: string;
|
|
3463
|
+
data: HookEndpointWebhookEventData;
|
|
3464
|
+
}
|
|
3465
|
+
/** The JSON body of a webhook request; narrow on `type`. */
|
|
3466
|
+
type WebhookEvent = EmailWebhookEvent | ReceivedEmailWebhookEvent | DomainWebhookEvent | AccountWebhookEvent | BillingWebhookEvent | RiskWebhookEvent | HookEndpointWebhookEvent;
|
|
3467
|
+
//#endregion
|
|
3468
|
+
//#region src/types/webhook-endpoint.d.ts
|
|
3469
|
+
/** Every event type an endpoint can subscribe to. */
|
|
3470
|
+
type WebhookEventType = EmailEventType | ReceivedEmailEventType | DomainEventType | AccountEventType | BillingEventType | RiskEventType | HookOperationalEventType;
|
|
3471
|
+
/** Why an endpoint is disabled. */
|
|
3472
|
+
type WebhookEndpointDisabledReason = "manual" | "failing";
|
|
3473
|
+
/** A URL of the API key's environment that receives signed event notifications. */
|
|
3474
|
+
interface WebhookEndpoint {
|
|
3475
|
+
object: "webhook_endpoint";
|
|
3476
|
+
id: string;
|
|
3477
|
+
url: string;
|
|
3478
|
+
description: string | null;
|
|
3479
|
+
/**
|
|
3480
|
+
* Event types delivered to this endpoint. An empty array means every event type, including
|
|
3481
|
+
* ones added later.
|
|
3482
|
+
*/
|
|
3483
|
+
event_types: string[];
|
|
3484
|
+
/** The API version events are rendered in for this endpoint (each event's `api_version`). */
|
|
3485
|
+
api_version: string;
|
|
3486
|
+
/** A disabled endpoint receives nothing until it is enabled again. */
|
|
3487
|
+
enabled: boolean;
|
|
3488
|
+
/**
|
|
3489
|
+
* `manual`: someone disabled it. `failing`: its deliveries failed every attempt for five days,
|
|
3490
|
+
* so coss.com disabled it. `null` while enabled.
|
|
3491
|
+
*/
|
|
3492
|
+
disabled_reason: WebhookEndpointDisabledReason | null;
|
|
3493
|
+
/** When it was disabled (ISO 8601); `null` while enabled. */
|
|
3494
|
+
disabled_at: string | null;
|
|
3495
|
+
/**
|
|
3496
|
+
* When the endpoint's current run of failed deliveries began (ISO 8601); cleared by the next
|
|
3497
|
+
* successful delivery. An endpoint failing for five days is disabled. `null` while healthy.
|
|
3498
|
+
*/
|
|
3499
|
+
failing_since: string | null;
|
|
3500
|
+
/**
|
|
3501
|
+
* After a secret roll, deliveries are also signed with the previous secret until this time
|
|
3502
|
+
* (ISO 8601). `null` when only the current secret signs.
|
|
3503
|
+
*/
|
|
3504
|
+
previous_secret_expires_at: string | null;
|
|
3505
|
+
/** ISO 8601 timestamp. */
|
|
3506
|
+
created_at: string;
|
|
3507
|
+
updated_at: string;
|
|
3508
|
+
}
|
|
3509
|
+
/** A freshly created endpoint, or one whose secret was just rolled: the only responses with the signing secret. */
|
|
3510
|
+
interface WebhookEndpointWithSecret extends WebhookEndpoint {
|
|
3511
|
+
/**
|
|
3512
|
+
* The endpoint's `whsec_…` signing secret, for `verifyWebhook`. Returned only on creation and
|
|
3513
|
+
* on a roll — store it now; it cannot be read back through the API.
|
|
3514
|
+
*/
|
|
3515
|
+
secret: string;
|
|
3516
|
+
}
|
|
3517
|
+
/** Body of `POST /v1/webhook_endpoints`. */
|
|
3518
|
+
interface CreateWebhookEndpointParams {
|
|
3519
|
+
/** An `https://` URL coss.com posts events to. */
|
|
3520
|
+
url: string;
|
|
3521
|
+
/** A note for your own reference. */
|
|
3522
|
+
description?: string | null;
|
|
3523
|
+
/** Defaults to every event type, including ones added later. */
|
|
3524
|
+
event_types?: WebhookEventType[];
|
|
3525
|
+
/**
|
|
3526
|
+
* The API version events are rendered in. Defaults to the client's `apiVersion`, so events match
|
|
3527
|
+
* this SDK's `WebhookEvent` types.
|
|
3528
|
+
*/
|
|
3529
|
+
api_version?: ApiVersion;
|
|
3530
|
+
}
|
|
3531
|
+
/** Body of `PATCH /v1/webhook_endpoints/{id}`. Omitted fields keep their current value. */
|
|
3532
|
+
interface UpdateWebhookEndpointParams {
|
|
3533
|
+
url?: string;
|
|
3534
|
+
/** `null` clears the description. */
|
|
3535
|
+
description?: string | null;
|
|
3536
|
+
event_types?: WebhookEventType[];
|
|
3537
|
+
api_version?: ApiVersion;
|
|
3538
|
+
enabled?: boolean;
|
|
3539
|
+
}
|
|
3540
|
+
/** Body of `POST /v1/webhook_endpoints/{id}/roll_secret`. */
|
|
3541
|
+
interface RollWebhookEndpointSecretParams {
|
|
3542
|
+
/**
|
|
3543
|
+
* Seconds the current secret keeps signing deliveries next to the new one, so receivers can
|
|
3544
|
+
* switch without rejecting anything. Default 86400 (a day), at most 604800 (a week). `0` stops
|
|
3545
|
+
* it immediately, e.g. after a leak.
|
|
3546
|
+
*/
|
|
3547
|
+
previous_secret_expires_in?: number;
|
|
3548
|
+
}
|
|
3549
|
+
/** Body of `POST /v1/webhook_endpoints/{id}/recover`. */
|
|
3550
|
+
interface RecoverWebhookEndpointParams {
|
|
3551
|
+
/**
|
|
3552
|
+
* Requeue the deliveries that failed and were created at or after this time (ISO 8601 string or
|
|
3553
|
+
* `Date`). Deliveries are kept for 30 days.
|
|
3554
|
+
*/
|
|
3555
|
+
since: string | Date;
|
|
3556
|
+
}
|
|
3557
|
+
/** Returned by `webhookEndpoints.recover`. */
|
|
3558
|
+
interface WebhookEndpointRecovery {
|
|
3559
|
+
object: "webhook_endpoint_recovery";
|
|
3560
|
+
endpoint_id: string;
|
|
3561
|
+
/** How many failed deliveries were queued for one more attempt (spread over the next minute). */
|
|
3562
|
+
requeued: number;
|
|
3563
|
+
/** At most 1,000 are requeued per call; `true` means call again with the same `since`. */
|
|
3564
|
+
has_more: boolean;
|
|
3565
|
+
}
|
|
3566
|
+
/** Returned by `webhookEndpoints.delete`. */
|
|
3567
|
+
interface DeletedWebhookEndpoint {
|
|
3568
|
+
object: "webhook_endpoint";
|
|
3569
|
+
id: string;
|
|
3570
|
+
deleted: true;
|
|
3571
|
+
}
|
|
3572
|
+
/**
|
|
3573
|
+
* `pending`: waiting for its next attempt. `succeeded`: the endpoint answered with a 2xx status.
|
|
3574
|
+
* `failed`: every attempt failed, or the endpoint was disabled.
|
|
3575
|
+
*/
|
|
3576
|
+
type WebhookDeliveryStatus = "pending" | "succeeded" | "failed";
|
|
3577
|
+
/** One HTTP request of a delivery. */
|
|
3578
|
+
interface WebhookAttempt {
|
|
3579
|
+
object: "webhook_attempt";
|
|
3580
|
+
id: string;
|
|
3581
|
+
/** ISO 8601 timestamp. */
|
|
3582
|
+
attempted_at: string;
|
|
3583
|
+
/** The endpoint's HTTP status; `null` when no response arrived. */
|
|
3584
|
+
status_code: number | null;
|
|
3585
|
+
duration_ms: number;
|
|
3586
|
+
/** Why the attempt failed (e.g. `HTTP 500`, a timeout); `null` on success. */
|
|
3587
|
+
error: string | null;
|
|
3588
|
+
/** At most 1 KB of the response body, as text. */
|
|
3589
|
+
response_excerpt: string | null;
|
|
3590
|
+
}
|
|
3591
|
+
/** One event sent to one endpoint, retried with backoff until it succeeds or gives up. */
|
|
3592
|
+
interface WebhookDelivery {
|
|
3593
|
+
object: "webhook_delivery";
|
|
3594
|
+
id: string;
|
|
3595
|
+
endpoint_id: string;
|
|
3596
|
+
/** The event's id: the `id` of the payload and the `webhook-id` header. */
|
|
3597
|
+
event_id: string;
|
|
3598
|
+
event_type: string;
|
|
3599
|
+
status: WebhookDeliveryStatus;
|
|
3600
|
+
attempt_count: number;
|
|
3601
|
+
/** When the next attempt is due; `null` once the delivery is finished. */
|
|
3602
|
+
next_attempt_at: string | null;
|
|
3603
|
+
last_status_code: number | null;
|
|
3604
|
+
last_error: string | null;
|
|
3605
|
+
/** The event body, exactly as posted to the endpoint (a `WebhookEvent`). */
|
|
3606
|
+
payload: Record<string, unknown>;
|
|
3607
|
+
/** Every HTTP attempt of this delivery, oldest first. */
|
|
3608
|
+
attempts: WebhookAttempt[];
|
|
3609
|
+
created_at: string;
|
|
3610
|
+
updated_at: string;
|
|
3611
|
+
}
|
|
3612
|
+
/** Query of `GET /v1/webhook_endpoints/{id}/deliveries`. */
|
|
3613
|
+
interface ListWebhookDeliveriesParams {
|
|
3614
|
+
/** Only deliveries with this status. */
|
|
3615
|
+
status?: WebhookDeliveryStatus;
|
|
3616
|
+
/** Only the delivery of this event. */
|
|
3617
|
+
event_id?: string;
|
|
3618
|
+
/** 1-100, default 50. */
|
|
3619
|
+
limit?: number;
|
|
3620
|
+
/** Cursor: the `id` of the last delivery of the previous page. */
|
|
3621
|
+
after?: string;
|
|
3622
|
+
}
|
|
3623
|
+
//#endregion
|
|
3624
|
+
//#region src/resources/webhook-deliveries.d.ts
|
|
3625
|
+
type ReadOptions$2 = Pick<RequestOptions, "signal">;
|
|
3626
|
+
/**
|
|
3627
|
+
* `coss.webhookEndpoints.deliveries`: an endpoint's delivery log. Each delivery carries every
|
|
3628
|
+
* HTTP attempt and the payload as sent.
|
|
3629
|
+
*/
|
|
3630
|
+
declare class WebhookDeliveriesResource {
|
|
3631
|
+
#private;
|
|
3632
|
+
/** @internal Use `new Coss().webhookEndpoints.deliveries`. */
|
|
3633
|
+
constructor(http: HttpClient);
|
|
3634
|
+
/** Lists the endpoint's deliveries, newest first. Pass the last `id` as `after` while `has_more` is true. */
|
|
3635
|
+
list(endpointId: string, params?: ListWebhookDeliveriesParams, options?: ReadOptions$2): Promise<CossResult<List<WebhookDelivery>>>;
|
|
3636
|
+
/** Retrieves one delivery of the endpoint. */
|
|
3637
|
+
get(endpointId: string, id: string, options?: ReadOptions$2): Promise<CossResult<WebhookDelivery>>;
|
|
3638
|
+
/**
|
|
3639
|
+
* Queues a finished delivery for one more attempt, made within seconds. A delivery that is
|
|
3640
|
+
* still `pending` is returned unchanged (it is already scheduled for `next_attempt_at`).
|
|
3641
|
+
* Never automatically retried: the API does not deduplicate replay requests, even with an
|
|
3642
|
+
* idempotency key.
|
|
3643
|
+
*/
|
|
3644
|
+
retry(endpointId: string, id: string, options?: RequestOptions): Promise<CossResult<WebhookDelivery>>;
|
|
3645
|
+
}
|
|
3646
|
+
//#endregion
|
|
3647
|
+
//#region src/resources/webhook-endpoints.d.ts
|
|
3648
|
+
type ReadOptions$1 = Pick<RequestOptions, "signal">;
|
|
3649
|
+
/**
|
|
3650
|
+
* `coss.webhookEndpoints`: the URLs that receive signed event notifications. Endpoints belong to
|
|
3651
|
+
* the API key's own environment, so a `coss_test_…` key only ever manages sandbox endpoints.
|
|
3652
|
+
*/
|
|
3653
|
+
declare class WebhookEndpointsResource {
|
|
3654
|
+
#private;
|
|
3655
|
+
/** Each endpoint's delivery log: list, retrieve and retry deliveries. */
|
|
3656
|
+
readonly deliveries: WebhookDeliveriesResource;
|
|
3657
|
+
/** @internal Use `new Coss().webhookEndpoints`. */
|
|
3658
|
+
constructor(http: HttpClient);
|
|
3659
|
+
/**
|
|
3660
|
+
* Creates an endpoint. The result carries its `secret` (returned again only by `rollSecret`) —
|
|
3661
|
+
* store it and pass it to `verifyWebhook` for every delivery. Creation is never automatically retried:
|
|
3662
|
+
* the API does not deduplicate it, even with an idempotency key. After a lost response,
|
|
3663
|
+
* list endpoints and remove the endpoint with the unknown secret before creating a replacement.
|
|
3664
|
+
*/
|
|
3665
|
+
create(params: CreateWebhookEndpointParams, options?: RequestOptions): Promise<CossResult<WebhookEndpointWithSecret>>;
|
|
3666
|
+
/** Lists the environment's endpoints, oldest first. Secrets are never included. */
|
|
3667
|
+
list(options?: ReadOptions$1): Promise<CossResult<List<WebhookEndpoint>>>;
|
|
3668
|
+
/** Retrieves an endpoint of the API key's environment. */
|
|
3669
|
+
get(id: string, options?: ReadOptions$1): Promise<CossResult<WebhookEndpoint>>;
|
|
3670
|
+
/**
|
|
3671
|
+
* Changes the URL, description, subscribed event types or `enabled` flag. The signing secret
|
|
3672
|
+
* stays the same (see `rollSecret`), so receivers keep verifying deliveries.
|
|
3673
|
+
*/
|
|
3674
|
+
update(id: string, params: UpdateWebhookEndpointParams, options?: ReadOptions$1): Promise<CossResult<WebhookEndpoint>>;
|
|
3675
|
+
/**
|
|
3676
|
+
* Replaces the endpoint's signing secret; the result carries the new `secret`. Until
|
|
3677
|
+
* `previous_secret_expires_at` (a day by default), deliveries are signed with both secrets, so
|
|
3678
|
+
* `verifyWebhook` accepts them with either: deploy the new one, then let the old one expire.
|
|
3679
|
+
* Never automatically retried (a second roll would stop the original secret at once): after a
|
|
3680
|
+
* lost response, roll again and deploy that secret.
|
|
3681
|
+
*/
|
|
3682
|
+
rollSecret(id: string, params?: RollWebhookEndpointSecretParams, options?: RequestOptions): Promise<CossResult<WebhookEndpointWithSecret>>;
|
|
3683
|
+
/**
|
|
3684
|
+
* Queues the endpoint's deliveries that failed since `since` for one more attempt each (at most
|
|
3685
|
+
* 1,000 per call; while `has_more` is true, call again with the same `since`), e.g. after fixing a
|
|
3686
|
+
* receiver that was down. The endpoint must be enabled.
|
|
3687
|
+
*/
|
|
3688
|
+
recover(id: string, params: RecoverWebhookEndpointParams, options?: RequestOptions): Promise<CossResult<WebhookEndpointRecovery>>;
|
|
3689
|
+
/** Deletes the endpoint and its delivery log. To pause it instead, update `enabled` to false. */
|
|
3690
|
+
delete(id: string, options?: ReadOptions$1): Promise<CossResult<DeletedWebhookEndpoint>>;
|
|
3691
|
+
}
|
|
3692
|
+
//#endregion
|
|
3693
|
+
//#region src/types/webhook-listener.d.ts
|
|
3694
|
+
/** A temporary subscriber of the API key's environment, open while it is polled. */
|
|
3695
|
+
interface WebhookListener {
|
|
3696
|
+
object: "webhook_listener";
|
|
3697
|
+
id: string;
|
|
3698
|
+
/** The API version events are rendered in. */
|
|
3699
|
+
api_version: string;
|
|
3700
|
+
/** Empty: every event type. */
|
|
3701
|
+
event_types: string[];
|
|
3702
|
+
description: string | null;
|
|
3703
|
+
/** When it closes unless polled again (every poll moves it 10 minutes ahead). */
|
|
3704
|
+
expires_at: string;
|
|
3705
|
+
created_at: string;
|
|
3706
|
+
}
|
|
3707
|
+
/** One event handed out by a poll, to forward and acknowledge. */
|
|
3708
|
+
interface WebhookListenerDelivery {
|
|
3709
|
+
object: "webhook_listener_delivery";
|
|
3710
|
+
id: string;
|
|
3711
|
+
/** Send it back in the acknowledgement. */
|
|
3712
|
+
ack_token: string;
|
|
3713
|
+
/** The event's id: the body's `id`, and the `webhook-id` header endpoints receive. */
|
|
3714
|
+
event_id: string;
|
|
3715
|
+
event_type: string;
|
|
3716
|
+
/** How many polls have handed it out (more than 1 after an unacknowledged answer). */
|
|
3717
|
+
attempt: number;
|
|
3718
|
+
/** The event body, exactly as an endpoint would receive it: forward these bytes. */
|
|
3719
|
+
body: string;
|
|
3720
|
+
created_at: string;
|
|
3721
|
+
}
|
|
3722
|
+
/** Answer of `POST /v1/webhook_listeners/{id}/poll`. */
|
|
3723
|
+
interface WebhookListenerPoll {
|
|
3724
|
+
object: "webhook_listener_poll";
|
|
3725
|
+
listener: WebhookListener;
|
|
3726
|
+
/** Oldest first; empty when nothing arrived while the poll waited. */
|
|
3727
|
+
deliveries: WebhookListenerDelivery[];
|
|
3728
|
+
/** How many of the request's acknowledgements were recorded. */
|
|
3729
|
+
acknowledged: number;
|
|
3730
|
+
}
|
|
3731
|
+
interface DeletedWebhookListener {
|
|
3732
|
+
object: "webhook_listener";
|
|
3733
|
+
id: string;
|
|
3734
|
+
deleted: true;
|
|
3735
|
+
}
|
|
3736
|
+
/** Body of `POST /v1/webhook_listeners`. */
|
|
3737
|
+
interface CreateWebhookListenerParams {
|
|
3738
|
+
/** Defaults to every event type. */
|
|
3739
|
+
event_types?: WebhookEventType[];
|
|
3740
|
+
/** Defaults to the client's `apiVersion`. */
|
|
3741
|
+
api_version?: ApiVersion;
|
|
3742
|
+
/** Where the events go, for your own reference (shown in the log). */
|
|
3743
|
+
description?: string | null;
|
|
3744
|
+
}
|
|
3745
|
+
/** What happened to one delivery handed out earlier. */
|
|
3746
|
+
interface WebhookListenerAck {
|
|
3747
|
+
delivery_id: string;
|
|
3748
|
+
ack_token: string;
|
|
3749
|
+
/** The local server's status; `null` when nothing answered, or the event was only printed. */
|
|
3750
|
+
status_code: number | null;
|
|
3751
|
+
duration_ms: number;
|
|
3752
|
+
/** Why forwarding failed; `null` if it didn't. */
|
|
3753
|
+
error: string | null;
|
|
3754
|
+
}
|
|
3755
|
+
/** Body of `POST /v1/webhook_listeners/{id}/poll`. */
|
|
3756
|
+
interface PollWebhookListenerParams {
|
|
3757
|
+
acks?: WebhookListenerAck[];
|
|
3758
|
+
/** How long to wait for events, in milliseconds (default 20000, at most 25000). */
|
|
3759
|
+
wait_ms?: number;
|
|
3760
|
+
/** The most deliveries to hand out (default 10, at most 50). */
|
|
3761
|
+
limit?: number;
|
|
3762
|
+
}
|
|
3763
|
+
//#endregion
|
|
3764
|
+
//#region src/resources/webhook-listeners.d.ts
|
|
3765
|
+
type ReadOptions = Pick<RequestOptions, "signal">;
|
|
3766
|
+
/**
|
|
3767
|
+
* `coss.webhookListeners`: what `coss listen` uses to forward an environment's events to a local
|
|
3768
|
+
* server. A listener receives events created after it opens, while it is polled; it is closed by
|
|
3769
|
+
* `delete` or after 10 minutes without a poll.
|
|
3770
|
+
*/
|
|
3771
|
+
declare class WebhookListenersResource {
|
|
3772
|
+
#private;
|
|
3773
|
+
/** @internal Use `new Coss().webhookListeners`. */
|
|
3774
|
+
constructor(http: HttpClient);
|
|
3775
|
+
/** Opens a listener. Never retried automatically: a lost answer leaves one to expire. */
|
|
3776
|
+
create(params?: CreateWebhookListenerParams, options?: ReadOptions): Promise<CossResult<WebhookListener>>;
|
|
3777
|
+
/**
|
|
3778
|
+
* Acknowledges earlier deliveries and waits (up to `wait_ms`) for more. Never retried
|
|
3779
|
+
* automatically: call it in a loop, and keep unacknowledged acks for the next call after an error.
|
|
3780
|
+
*/
|
|
3781
|
+
poll(id: string, params?: PollWebhookListenerParams, options?: ReadOptions): Promise<CossResult<WebhookListenerPoll>>;
|
|
3782
|
+
/** Closes a listener: it receives nothing more. */
|
|
3783
|
+
delete(id: string, options?: ReadOptions): Promise<CossResult<DeletedWebhookListener>>;
|
|
3784
|
+
}
|
|
3785
|
+
//#endregion
|
|
3786
|
+
//#region src/client.d.ts
|
|
3787
|
+
interface CossOptions {
|
|
3788
|
+
/** Secret API key (`coss_live_…` or `coss_test_…`). Defaults to the `COSS_API_KEY` env variable. */
|
|
3789
|
+
apiKey?: string;
|
|
3790
|
+
/** Defaults to the `COSS_BASE_URL` env variable, then `https://api.coss.com`. */
|
|
3791
|
+
baseUrl?: string;
|
|
3792
|
+
/** Custom `fetch` implementation. Defaults to the global `fetch`. */
|
|
3793
|
+
fetch?: FetchLike;
|
|
3794
|
+
/** Per-attempt timeout in milliseconds. Default `30000`. */
|
|
3795
|
+
timeout?: number;
|
|
3796
|
+
/** Retries for connection errors, timeouts, 409, 429 and 5xx. Default `2`; excludes webhook creation. */
|
|
3797
|
+
maxRetries?: number;
|
|
3798
|
+
/**
|
|
3799
|
+
* The API version (`Coss-Version`) to request. Defaults to `API_VERSION`, the version this SDK's
|
|
3800
|
+
* types describe; requests never fall back to your organization's pinned version.
|
|
3801
|
+
*/
|
|
3802
|
+
apiVersion?: ApiVersion;
|
|
3803
|
+
/**
|
|
3804
|
+
* Allow use where a `document` global exists. Off by default because shipping a secret API key
|
|
3805
|
+
* to a browser exposes it to anyone who opens the page.
|
|
3806
|
+
*/
|
|
3807
|
+
dangerouslyAllowBrowser?: boolean;
|
|
3808
|
+
}
|
|
3809
|
+
/**
|
|
3810
|
+
* The coss.com client. One API key covers every product.
|
|
3811
|
+
*
|
|
3812
|
+
* ```ts
|
|
3813
|
+
* const coss = new Coss({ apiKey: "coss_test_…" });
|
|
3814
|
+
* const { data, error } = await coss.email.send({ from, to, subject, html });
|
|
3815
|
+
* ```
|
|
3816
|
+
*/
|
|
3817
|
+
declare class Coss {
|
|
3818
|
+
readonly email: EmailResource;
|
|
3819
|
+
/** The API key's environment, project and organization (`coss.environment.get()`). */
|
|
3820
|
+
readonly environment: EnvironmentResource;
|
|
3821
|
+
/** The client's own API key (`coss.apiKey.revoke()`). */
|
|
3822
|
+
readonly apiKey: ApiKeyResource;
|
|
3823
|
+
/** Sending domains of the organization (`coss.domains.create`, `.verify`, …). */
|
|
3824
|
+
readonly domains: DomainsResource;
|
|
3825
|
+
/** Webhook endpoints of the API key's environment. */
|
|
3826
|
+
readonly webhookEndpoints: WebhookEndpointsResource;
|
|
3827
|
+
/** Temporary listeners `coss listen` pulls the environment's events from. */
|
|
3828
|
+
readonly webhookListeners: WebhookListenersResource;
|
|
3829
|
+
/** The organization's sending reputation (`coss.reputation.get()`). */
|
|
3830
|
+
readonly reputation: ReputationResource;
|
|
3831
|
+
/** The environment's log: API requests, email events, webhook attempts (`coss.logs.list()`). */
|
|
3832
|
+
readonly logs: LogsResource;
|
|
3833
|
+
/** HTTPS endpoints the environment's log is streamed to (`coss.logDrains.create()`). */
|
|
3834
|
+
readonly logDrains: LogDrainsResource;
|
|
3835
|
+
/** The organization's audit log: changes by members, API keys and coss.com support (`coss.auditEvents.list()`). */
|
|
3836
|
+
readonly auditEvents: AuditEventsResource;
|
|
3837
|
+
/** Hooks, webhooks as a service: `coss.hooks.messages.send()` delivers to your users' endpoints. */
|
|
3838
|
+
readonly hooks: HooksResource;
|
|
3839
|
+
/** Risk assessments of sign-ups, logins and other events (`coss.risk.assess()`). */
|
|
3840
|
+
readonly risk: RiskResource;
|
|
3841
|
+
/** The organization's plan, usage, invoices and credits (`coss.billing.get()`). */
|
|
3842
|
+
readonly billing: BillingResource;
|
|
3843
|
+
/**
|
|
3844
|
+
* Throws only for programmer errors: no API key, or running in a browser without
|
|
3845
|
+
* `dangerouslyAllowBrowser`. Request failures are returned as `{ data: null, error }`.
|
|
3846
|
+
*/
|
|
3847
|
+
constructor(options?: CossOptions);
|
|
3848
|
+
}
|
|
3849
|
+
//#endregion
|
|
3850
|
+
export { RiskUsersResource as $, ListSuppressionsParams as $i, EnvironmentResource as $n, MailFromStatus as $r, LogsResource as $t, BillingEventType as A, CossError as Aa, EmailFailure as Ai, HookApplication as An, DmarcNextStepKind as Ar, RiskLimit as At, ReceivedEmailEventType as B, ReactEmailElement as Bi, HookMessage as Bn, ListDmarcReportsParams as Br, RiskReasonCode as Bt, WebhookEndpointDisabledReason as C, ListAuditEventsParams as Ca, Email as Ci, HooksResource as Cn, TrackingDomainsResource as Cr, RiskEmailCheck as Ct, AccountEventType as D, NamedResource as Da, EmailEvent as Di, CreateHookPortalSessionParams as Dn, DmarcCheck as Dr, RiskIpCheck as Dt, WebhookEventType as E, Environment as Ea, EmailBatch as Ei, CreateHookEventTypeParams as En, DmarcResource as Er, RiskFeedbackParams as Et, EmailWebhookEvent as F, API_VERSIONS as Fa, EmailSummary as Fi, HookEndpointDisabledReason as Fn, DmarcReportRecord as Fr, RiskListEntryType as Ft, RiskWebhookEventData as G, SendEmailTemplateParams as Gi, ListHookMessagesParams as Gn, CreateTrackingDomainParams as Gr, UpdateRiskLimitBucketParams as Gt, ReceivedEmailWebhookEventData as H, SendEmailBaseParams as Hi, ListHookApplicationsParams as Hn, BimiStatus as Hr, RiskRuleCondition as Ht, EmailWebhookEventData as I, ApiVersion as Ia, EmailTag as Ii, HookEndpointRecovery as In, DmarcReportSummary as Ir, RiskListEntryValue as It, RiskLimitBucketsResource as J, CreateSuppressionParams as Ji, SendHookMessageParams as Jn, DomainBimi as Jr, ReputationResource as Jt, WebhookEvent as K, TrackingOptions as Ki, RecoverHookEndpointParams as Kn, DeletedDomain as Kr, UpdateRiskRuleParams as Kt, HookEndpointWebhookEvent as L, EmailTracking as Li, HookEndpointSecret as Ln, DmarcSource as Lr, RiskLoginSignals as Lt, DomainEventType as M, CossErrorType as Ma, EmailRecipient as Mi, HookDelivery as Mn, DmarcPolicyPublished as Mr, RiskLimitFailureMode as Mt, DomainWebhookEvent as N, CossResult as Na, EmailRecipientStatus as Ni, HookDeliveryStatus as Nn, DmarcPublishedRecord as Nr, RiskList as Nt, AccountWebhookEvent as O, FetchLike as Oa, EmailEventData as Oi, DeletedHookApplication as On, DmarcCheckId as Or, RiskIpPrivacy as Ot, DomainWebhookEventData as P, API_VERSION as Pa, EmailStatus as Pi, HookEndpoint as Pn, DmarcReport as Pr, RiskListEntry as Pt, RiskSettingsResource as Q, ImportSuppressionsParams as Qi, UpdateHookEventTypeParams as Qn, DomainStatus as Qr, ReputationStatus as Qt, HookEndpointWebhookEventData as R, List as Ri, HookEndpointWithSecret as Rn, DmarcStage as Rr, RiskOutcome as Rt, WebhookEndpoint as S, AuditEvent as Sa, AuditEventsResource as Si, HookPortalResource as Sn, DomainsResource as Sr, RiskDeviceSignals as St, WebhookEndpointWithSecret as T, DeletedApiKey as Ta, EmailAttachmentParams as Ti, CreateHookEndpointParams as Tn, DmarcReportsResource as Tr, RiskEvent as Tt, RiskEventType as U, SendEmailContentParams as Ui, ListHookDeliveriesParams as Un, CreateDomainParams as Ur, RiskRuleField as Ut, ReceivedEmailWebhookEvent as V, RescheduleEmailParams as Vi, HookPortalSession as Vn, BimiIssueCode as Vr, RiskRule as Vt, RiskWebhookEvent as W, SendEmailParams as Wi, ListHookEventTypesParams as Wn, CreateReceivingDomainParams as Wr, RiskSettings as Wt, RiskResource as X, ExportSuppressionsParams as Xi, UpdateHookApplicationParams as Xn, DomainRecordPurpose as Xr, ReputationCheck as Xt, RiskListsResource as Y, DeletedSuppression as Yi, SendHookTestParams as Yn, DomainRecord as Yr, Reputation as Yt, RiskRulesResource as Z, ImportSuppressionEntry as Zi, UpdateHookEndpointParams as Zn, DomainRecordStatus as Zr, ReputationCheckSeverity as Zt, RollWebhookEndpointSecretParams as _, TemplateVariableParams as _a, ListInvoicesParams as _i, HookApplicationsResource as _n, EmailTemplateVersionsResource as _r, RiskContentCategory as _t, DeletedWebhookListener as a, DeletedEmailTemplate as aa, BillingCreditsResource as ai, LogDrain as an, UpdateTrackingRuleParams as ar, DeletedRiskLimitBucket as at, WebhookDelivery as b, UpdateEmailTemplateParams as ba, PlanKey as bi, HookEventTypesResource as bn, DedicatedIpPool as br, RiskDecision as bt, WebhookListenerAck as c, EmailTemplateVersion as ca, Billing as ci, LogDrainBatchStatus as cn, DeletedReceivedEmail as cr, ForgottenRiskUser as ct, WebhookEndpointsResource as d, PublishEmailTemplateParams as da, Invoice as di, LogDrainWithSecret as dn, ReceivedEmail as dr, RiskAssessment as dt, Suppression as ea, ReceivingDomain as ei, LogDrainBatchesResource as en, EmailResource as er, AssessRiskParams as et, WebhookDeliveriesResource as f, TemplateContent as fa, InvoiceLine as fi, UpdateLogDrainParams as fn, ReceivedEmailAttachment as fr, RiskCalibration as ft, RecoverWebhookEndpointParams as g, TemplateVariable as ga, ListCreditsParams as gi, LogSource as gn, VerdictStatus as gr, RiskCheckoutSignals as gt, ListWebhookDeliveriesParams as h, TemplateScalarType as ha, InvoiceSummary as hi, LogLevel as hn, ReceivedEmailVerdicts as hr, RiskCardFunding as ht, CreateWebhookListenerParams as i, CreateEmailTemplateParams as ia, TrackingDomainStatus as ii, ListLogDrainBatchesParams as in, TrackingSettings as ir, CreateRiskRuleParams as it, BillingWebhookEvent as j, CossErrorIssue as ja, EmailLink as ji, HookAttempt as jn, DmarcPolicy as jr, RiskLimitBucket as jt, AccountWebhookEventData as k, RequestOptions as ka, EmailEventType as ki, DeletedHookEndpoint as kn, DmarcNextStep as kr, RiskIpSignals as kt, WebhookListenerDelivery as l, ListEmailTemplateVersionsParams as la, BillingHoldReason as li, LogDrainLine as ln, InboundAddress as lr, ListRiskAssessmentsParams as lt, DeletedWebhookEndpoint as m, TemplateProblem as ma, InvoiceStatus as mi, Log as mn, ReceivedEmailSummary as mr, RiskCaptchaSignals as mt, CossOptions as n, SuppressionImport as na, TrackingDomain as ni, CreateLogDrainParams as nn, DeletedTrackingRule as nr, CreateRiskLimitBucketParams as nt, PollWebhookListenerParams as o, EmailTemplate as oa, BillingInvoicesResource as oi, LogDrainAttempt as on, SuppressionResource as or, DeletedRiskListEntry as ot, CreateWebhookEndpointParams as p, TemplateContentParams as pa, InvoiceLineKind as pi, ListLogsParams as pn, ReceivedEmailStatus as pr, RiskCaptchaProvider as pt, RiskAssessmentsResource as q, CheckSuppressionParams as qi, RollHookEndpointSecretParams as qn, Domain as qr, UpdateRiskSettingsParams as qt, WebhookListenersResource as r, SuppressionReason as ra, TrackingDomainRecord as ri, DeletedLogDrain as rn, TrackingRule as rr, CreateRiskListEntryParams as rt, WebhookListener as s, EmailTemplateReference as sa, BillingResource as si, LogDrainBatch as sn, ReceivedEmailsResource as sr, DeletedRiskRule as st, Coss as t, SuppressionCheck as ta, ReceivingDomainRecord as ti, LogDrainsResource as tn, TrackingResource as tr, CheckRiskLimitParams as tt, WebhookListenerPoll as u, ListEmailTemplatesParams as ua, Credit as ui, LogDrainSource as un, ListReceivedEmailsParams as ur, ListRiskListEntriesParams as ut, UpdateWebhookEndpointParams as v, TemplateVariableType as va, ListUsageParams as vi, HookDeliveriesResource as vn, EmailTemplatesResource as vr, RiskContentClassification as vt, WebhookEndpointRecovery as w, ApiKeyResource as wa, EmailAttachment as wi, CreateHookApplicationParams as wn, ReceivingDomainsResource as wr, RiskEmailSignals as wt, WebhookDeliveryStatus as x, AuditActorType as xa, Usage as xi, HookMessagesResource as xn, DedicatedIpPoolStatus as xr, RiskDegradedSignal as xt, WebhookAttempt as y, UpdateEmailTemplateDraftParams as ya, Meter as yi, HookEndpointsResource as yn, DedicatedIpsResource as yr, RiskContentScores as yt, HookOperationalEventType as z, ListEmailsParams as zi, HookEventType as zn, DomainDmarc as zr, RiskReason as zt };
|